机器学习: 利用 Tensorflow 和预训练模型提取特征-- Mobilenet V2

之前介绍了利用 Mobinet V1 做特征提取,从 Tensorflow 的官网上看, Mobilenet V2 的性能比 V1 要更好,今天介绍用 V2 的预训练模型提取特征的方式,基本和 V1 是一样的,只是有一个地方需要注意一下,就是加载网络结构的时候:

with tf.contrib.slim.arg_scope(mobilenet_v2.training_scope(is_training=False)):
    logits, endpoints = mobilenet_v2.mobilenet(x_batch, num_classes=1001, depth_multiplier=1.4)

需要修改 depth_multiplier,如果你是加载的 mobilenet_v2_1.4_224.ckpt,需要将 depth_multiplier 修改为 1.4, 否则会报错,之前
也是踩过不少坑,除了这个地方,其他的都和 V1 类似,附上下面完整的代码:

import tensorflow as tf
import numpy as np
import glob

from nets.mobilenet import mobilenet_v2

slim = tf.contrib.slim

def mobi_parse_fun(x_in, y_label=1):
    
    img_path = tf.read_file(x_in)
    img_decode = tf.io.decode_jpeg(img_path, channels=3)
    img = tf.image.resize_images(img_decode, [224, 224])
    img = tf.cast(img, tf.float32) / 127.5 - 1.0
    	
    return img, y_label
	

# tf.graph.default_graph()

X_in = tf.placeholder(tf.string, None)
# Y_in = tf.placeholder(tf.int32, None)

train_data = tf.data.Dataset.from_tensor_slices((X_in))
train_data = train_data.map(mobi_parse_fun)
train_data = train_data.batch(1)

iter_ = tf.data.Iterator.from_structure(train_data.output_types,
                                        train_data.output_shapes)

x_batch, y_batch = iter_.get_next()

train_init_op = iter_.make_initializer(train_data)

x_ = tf.placeholder(tf.float32, (None, 224, 224, 3))

print(tf.__version__)

with tf.contrib.slim.arg_scope(mobilenet_v2.training_scope(is_training=False)):
    logits, endpoints = mobilenet_v2.mobilenet(x_batch, num_classes=1001, depth_multiplier=1.4)

img_path = 'F:\cute\*.jpg'
img_list = glob.glob(img_path)

ckpt_path = 'D:\Python_Code\Models\mobilenet_v2_1.4_224\mobilenet_v2_1.4_224.ckpt'
saver = tf.train.Saver()
with tf.Session() as sess:

    saver.restore(sess, ckpt_path)
    
    print('print the trainable parameters: ')
    for eval_ in tf.trainable_variables():
        # print(eval_.name)
        w_val = sess.run(eval_.name)
        print(eval_.name, w_val.shape)
    
    sess.run(train_init_op, feed_dict={X_in: img_list})
    
    #---------------------------------------------
    #---------------------------------------------
    key_name = endpoints.keys()
    print('print the feature maps: ')
    for name_ in key_name:
        feat_map = sess.run(endpoints[name_])
        print(name_, feat_map.shape)
        
    fc_map = endpoints['global_pool']
    fc_feat = tf.squeeze(fc_map, [1, 2])
    
    for img_name in img_list:
        print(img_name)
        
        x_bat, y_bat = sess.run([x_batch, y_batch])
        print(x_bat.shape, y_bat.shape)
        
        fc_feature = sess.run([fc_feat])
        print(fc_feature[0].shape)
        
        break

网络结构太长了,这里就给出 V2 的 feature map:

print the feature maps:
layer_1 (1, 112, 112, 48)
layer_2 (1, 112, 112, 24)
layer_3 (1, 56, 56, 32)
layer_4 (1, 56, 56, 32)
layer_5 (1, 28, 28, 48)
layer_6 (1, 28, 28, 48)
layer_7 (1, 28, 28, 48)
layer_8 (1, 14, 14, 88)
layer_9 (1, 14, 14, 88)
layer_10 (1, 14, 14, 88)
layer_11 (1, 14, 14, 88)
layer_12 (1, 14, 14, 136)
layer_13 (1, 14, 14, 136)
layer_14 (1, 14, 14, 136)
layer_15 (1, 7, 7, 224)
layer_16 (1, 7, 7, 224)
layer_17 (1, 7, 7, 224)
layer_18 (1, 7, 7, 448)
layer_19 (1, 7, 7, 1792)
layer_2/depthwise_output (1, 112, 112, 48)
layer_2/output (1, 112, 112, 24)
layer_3/expansion_output (1, 112, 112, 144)
layer_3/depthwise_output (1, 56, 56, 144)
layer_3/output (1, 56, 56, 32)
layer_4/expansion_output (1, 56, 56, 192)
layer_4/depthwise_output (1, 56, 56, 192)
layer_4/output (1, 56, 56, 32)
layer_5/expansion_output (1, 56, 56, 192)
layer_5/depthwise_output (1, 28, 28, 192)
layer_5/output (1, 28, 28, 48)
layer_6/expansion_output (1, 28, 28, 288)
layer_6/depthwise_output (1, 28, 28, 288)
layer_6/output (1, 28, 28, 48)
layer_7/expansion_output (1, 28, 28, 288)
layer_7/depthwise_output (1, 28, 28, 288)
layer_7/output (1, 28, 28, 48)
layer_8/expansion_output (1, 28, 28, 288)
layer_8/depthwise_output (1, 14, 14, 288)
layer_8/output (1, 14, 14, 88)
layer_9/expansion_output (1, 14, 14, 528)
layer_9/depthwise_output (1, 14, 14, 528)
layer_9/output (1, 14, 14, 88)
layer_10/expansion_output (1, 14, 14, 528)
layer_10/depthwise_output (1, 14, 14, 528)
layer_10/output (1, 14, 14, 88)
layer_11/expansion_output (1, 14, 14, 528)
layer_11/depthwise_output (1, 14, 14, 528)
layer_11/output (1, 14, 14, 88)
layer_12/expansion_output (1, 14, 14, 528)
layer_12/depthwise_output (1, 14, 14, 528)
layer_12/output (1, 14, 14, 136)
layer_13/expansion_output (1, 14, 14, 816)
layer_13/depthwise_output (1, 14, 14, 816)
layer_13/output (1, 14, 14, 136)
layer_14/expansion_output (1, 14, 14, 816)
layer_14/depthwise_output (1, 14, 14, 816)
layer_14/output (1, 14, 14, 136)
layer_15/expansion_output (1, 14, 14, 816)
layer_15/depthwise_output (1, 7, 7, 816)
layer_15/output (1, 7, 7, 224)
layer_16/expansion_output (1, 7, 7, 1344)
layer_16/depthwise_output (1, 7, 7, 1344)
layer_16/output (1, 7, 7, 224)
layer_17/expansion_output (1, 7, 7, 1344)
layer_17/depthwise_output (1, 7, 7, 1344)
layer_17/output (1, 7, 7, 224)
layer_18/expansion_output (1, 7, 7, 1344)
layer_18/depthwise_output (1, 7, 7, 1344)
layer_18/output (1, 7, 7, 448)
global_pool (1, 1, 1, 1792)
Logits (1, 1001)
Predictions (1, 1001)
F:\cute\0a431c2b13928b84df8110a1c6ef8568.jpg
(1, 224, 224, 3) (1,)
(1, 1792)

可以看到,最靠近输出层的是 global_pool 层的 feature map,所以可以直接抽取这层的 feature map 作为我们的 feature。

发布了219 篇原创文章 · 获赞 211 · 访问量 113万+

猜你喜欢

转载自blog.csdn.net/shinian1987/article/details/88776860