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()