tensorflow搭建vgg16提取图像特征

github代码

https://github.com/ry/tensorflow-vgg16

https://github.com/machrisaa/tensorflow-vgg

预训练模型地址:

测试代码:

test_vgg16.py

import numpy as np
import tensorflow as tf

import vgg16
import utils

img1 = utils.load_image("./test_data/tiger.jpeg")
img2 = utils.load_image("./test_data/puzzle.jpeg")

batch1 = img1.reshape((1, 224, 224, 3))
batch2 = img2.reshape((1, 224, 224, 3))
fo=open('aa','w')
batch = np.concatenate((batch1, batch2), 0)
with tf.device('/gpu:1'):
    with tf.Session() as sess:
        images = tf.placeholder("float", [2, 224, 224, 3])
        feed_dict = {images: batch}

#        vgg = vgg16.Vgg16()
#        with tf.name_scope("content_vgg"):
#            vgg.build(images)

#        prob = sess.run(vgg.prob, feed_dict=feed_dict)
#        print(prob)
#        utils.print_prob(prob[0], './synset.txt')
#        utils.print_prob(prob[1], './synset.txt')
        vgg = vgg16.Vgg16()
        with tf.name_scope("content_vgg"):
            vgg.build(images)
        feature = sess.run(vgg.fc8, feed_dict=feed_dict)#提取fc8层的特征
        print(type(feature[0]))
fo.close()

feature=sess.run提取的是fc8的特征,是一个tensor,如果要在会话之外调用,要设置一个会话之外的变量,将feature赋值出来,从tensor变为一个maxtrix。

fc8_feature = feature

如果要用于分类,就把fc改为原来的prob就可以了。这个是经过softmax得到的结果,也就是把注释掉的还原。

因为输入是两张图像,所有fc8最后是两个长度为1000的向量。可以写循环把图片批量处理,一个batch一个batch的丢进去。我写成了一个函数,代码如下:

调用的时候直接 features = get_feature(im_path, im_list)就可以,batch是20。设置太大了gpu受不了。

参数:im_path,图片文件夹路径,im_list 要处理的图片名字。

在per batch特征拼接的时候,使用了concatenate([a,b]),不断的把特征堆叠到一起。

def get_feature(im_path, im_list):
  flag=0
  num_im=len(im_list)
  flag2=0
  flag3=0
  for name in im_list:
    im_dict[name]={}
    im_dict[name]['path']=im_path+name
    im_dict[name]['img'] = utils.load_image(im_path+name)
    img = cv2.imread(im_dict[name]['path'])
    print(im_dict[name]['path'])
    im_dict[name]['reshape'] = im_dict[name]['img'].reshape((1, 224, 224, 3))
    if flag==0:
      batch = im_dict[name]['reshape']
      flag=1
    else:
      batch1 = im_dict[name]['reshape']
      batch = concatenate((batch, batch1), 0)
  print(batch.shape)
  count=int(math.floor(num_im/20)+1)
  print('count is {}'.format(count))
  tt=array([])
  for j in range(count):
    aa=array([])
    if j != int(math.floor(num_im/20)):
      batch_input = batch[j*20:(j+1)*20,:,:,:]
      print("data is batch[{}:{},:,:,:]".format(j*20,(j+1)*20))
      print("batch_input shape is {}".format(batch_input.shape[0]))
    else:
      batch_input= batch[j*20:num_im,:,:,:]
      print("data is batch[{}:{},:,:,:]".format(j*20,num_im))
      print("batch_input shape is {}".format(batch_input.shape[0]))
    num_batch=batch_input.shape[0]
    with tf.device('/gpu:1'):
            sess = tf.Session()
            images = tf.placeholder("float", [num_batch, 224, 224, 3])
            print("num_batch is {}".format(num_batch))
            feed_dict = {images: batch_input}
            vgg = vgg16.Vgg16()
            with tf.name_scope("content_vgg"):
               vgg.build(images)
            if j==0:
              feature= sess.run(vgg.pool5, feed_dict=feed_dict)
              tt=feature.reshape(num_batch, 25088)
              print(tt.shape[0])
              print(tt.shape[1])
            else:
              feature= sess.run(vgg.pool5, feed_dict=feed_dict)
              aa=feature.reshape(num_batch, 25088)
              print(aa.shape[0])
              print(aa.shape[1])
            sess.close()
    print("tt len is {}".format(len(tt)))
    tf.reset_default_graph()
    if j!=0:
       tt = concatenate([tt, aa])
    print("tt len is {}".format(len(tt)))
  print(len(tt))
  return tt

print一下特征向量。

如果要可视化,可以参考我的另一篇文章,只需要对特征进行以下绘制操作。建议Plot卷积层,全连接层的视觉表征还是少一点,偏向语义,看起来没有什么意义。

https://blog.csdn.net/gusui7202/article/details/86491698

with tf.Session() as sess:#打开会话
    sess.run(init)#初始化
    img1 = mnist.train.images[1]#输入图片
    img1.shape = [1, 784]#转换接口格式
    result = sess.run(h_conv1, feed_dict={xs : img1})#提取tensor特征
    for i in range(32):#画出每一张特征图
        show_img = result[:, :, :, i]
        # print type(show_img)
        show_img.shape = [28, 28]
        plt.subplot(4, 8, i + 1)#打开一个4x8的画布。
        plt.imshow(show_img, cmap='gray')
        plt.axis('off')
    plt.show()

猜你喜欢

转载自blog.csdn.net/gusui7202/article/details/86554905