参考:https://www.cs.toronto.edu/~frossard/post/vgg16/
论文地址:https://arxiv.org/pdf/1409.1556.pdf
1. VGG16

其中VGG16即为D,包含16个卷积层,3个全连接层;而VGG19即为19个卷积层。
其基本特点为通过使用较小的卷积核()来代替AlexNet中较大的卷积核。具体来说就是用2个的卷积核代替的卷积核,用3个的卷积核代替的卷积核。从而加深了网络的深度,增强了网络的拟合能力。
但是其参数数量庞大,主要集中在最后的三个全连接层中,目前预训练模型达到了500多Mb。

2. Code
import tensorflow as tf
import numpy as np
import caffe_classes
from PIL import Image
class VGG16():
def __init__(self,x):
self.x = x
self.parameters = []
self.getFeature()
self.getClassifier()
self.probs = tf.nn.softmax(self.fc8)
#have not been used
def conv2d(x,kh,kw,in_channel,out_channel,name):
w = tf.Variable(tf.truncated_normal([kh,kw,in_channel,out_channel]),name='w')
b = tf.Variable(tf.constant(0.0,shape=[out_channel],dtype=tf.float32),name='b')
conv = tf.nn.conv2d(x,w,[1,1,1,1],padding='SAME')
out = tf.nn.bias_add(conv,b)
conv_out = tf.nn.relu(out,name=name)
parameter = [w,b]
return [conv_out,parameter]
def getFeature(self):
with tf.variable_scope("preprocess") as scope:
mean = tf.constant([123.68, 116.779, 103.939], dtype=tf.float32, shape=[1, 1, 1, 3], name='img_mean')
images = self.x-mean
with tf.variable_scope("conv1_1") as scope:
w = tf.Variable(tf.truncated_normal([3,3,3,64]),name='w')
b = tf.Variable(tf.constant(0.0,shape=[64],dtype=tf.float32),name='b')
conv = tf.nn.conv2d(self.x,w,[1,1,1,1],padding='SAME')
out = tf.nn.bias_add(conv,b)
self.conv1_1 = tf.nn.relu(out,name=scope.name)
self.parameters += [w,b]
with tf.variable_scope("conv1_2") as scope:
w = tf.Variable(tf.truncated_normal([3,3,64,64]),name='w')
b = tf.Variable(tf.constant(0.0,shape=[64],dtype=tf.float32),name='b')
conv = tf.nn.conv2d(self.conv1_1,w,[1,1,1,1],padding='SAME')
out = tf.nn.bias_add(conv,b)
self.conv1_2 = tf.nn.relu(out,name=scope.name)
self.parameters += [w,b]
self.pool1 = tf.nn.max_pool(self.conv1_2,[1,2,2,1],[1,2,2,1],padding='SAME',name='pool1')
with tf.variable_scope("conv2_1") as scope:
w = tf.Variable(tf.truncated_normal([3,3,64,128]),name='w')
b = tf.Variable(tf.constant(0.0,shape=[128],dtype=tf.float32),name='b')
conv = tf.nn.conv2d(self.pool1,w,[1,1,1,1],padding='SAME')
out = tf.nn.bias_add(conv,b)
self.conv2_1 = tf.nn.relu(out,name=scope.name)
self.parameters += [w,b]
with tf.variable_scope("conv2_2") as scope:
w = tf.Variable(tf.truncated_normal([3,3,128,128]),name='w')
b = tf.Variable(tf.constant(0.0,shape=[128],dtype=tf.float32),name='b')
conv = tf.nn.conv2d(self.conv2_1,w,[1,1,1,1],padding='SAME')
out = tf.nn.bias_add(conv,b)
self.conv2_2 = tf.nn.relu(out,name=scope.name)
self.parameters += [w,b]
self.pool2 = tf.nn.max_pool(self.conv2_2,[1,2,2,1],[1,2,2,1],padding='SAME',name='pool2')
with tf.variable_scope("conv3_1") as scope:
w = tf.Variable(tf.truncated_normal([3,3,128,256]),name='w')
b = tf.Variable(tf.constant(0.0,shape=[256],dtype=tf.float32),name='b')
conv = tf.nn.conv2d(self.pool2,w,[1,1,1,1],padding='SAME')
out = tf.nn.bias_add(conv,b)
self.conv3_1 = tf.nn.relu(out,name=scope.name)
self.parameters += [w,b]
with tf.variable_scope("conv3_2") as scope:
w = tf.Variable(tf.truncated_normal([3,3,256,256]),name='w')
b = tf.Variable(tf.constant(0.0,shape=[256],dtype=tf.float32),name='b')
conv = tf.nn.conv2d(self.conv3_1,w,[1,1,1,1],padding='SAME')
out = tf.nn.bias_add(conv,b)
self.conv3_2 = tf.nn.relu(out,name=scope.name)
self.parameters += [w,b]
with tf.variable_scope("conv3_3") as scope:
w = tf.Variable(tf.truncated_normal([3,3,256,256]),name='w')
b = tf.Variable(tf.constant(0.0,shape=[256],dtype=tf.float32),name='b')
conv = tf.nn.conv2d(self.conv3_2,w,[1,1,1,1],padding='SAME')
out = tf.nn.bias_add(conv,b)
self.conv3_3 = tf.nn.relu(out,name=scope.name)
self.parameters += [w,b]
self.pool3 = tf.nn.max_pool(self.conv3_3,[1,2,2,1],[1,2,2,1],padding='SAME',name='pool3')
with tf.variable_scope("conv4_1") as scope:
w = tf.Variable(tf.truncated_normal([3,3,256,512]),name='w')
b = tf.Variable(tf.constant(0.0,shape=[512],dtype=tf.float32),name='b')
conv = tf.nn.conv2d(self.pool3,w,[1,1,1,1],padding='SAME')
out = tf.nn.bias_add(conv,b)
self.conv4_1 = tf.nn.relu(out,name=scope.name)
self.parameters += [w,b]
with tf.variable_scope("conv4_2") as scope:
w = tf.Variable(tf.truncated_normal([3,3,512,512]),name='w')
b = tf.Variable(tf.constant(0.0,shape=[512],dtype=tf.float32),name='b')
conv = tf.nn.conv2d(self.conv4_1,w,[1,1,1,1],padding='SAME')
out = tf.nn.bias_add(conv,b)
self.conv4_2 = tf.nn.relu(out,name=scope.name)
self.parameters += [w,b]
with tf.variable_scope("conv4_3") as scope:
w = tf.Variable(tf.truncated_normal([3,3,512,512]),name='w')
b = tf.Variable(tf.constant(0.0,shape=[512],dtype=tf.float32),name='b')
conv = tf.nn.conv2d(self.conv4_2,w,[1,1,1,1],padding='SAME')
out = tf.nn.bias_add(conv,b)
self.conv4_3 = tf.nn.relu(out,name=scope.name)
self.parameters += [w,b]
self.pool4 = tf.nn.max_pool(self.conv4_3,[1,2,2,1],[1,2,2,1],padding='SAME',name='pool4')
with tf.variable_scope("conv5_1") as scope:
w = tf.Variable(tf.truncated_normal([3,3,512,512]),name='w')
b = tf.Variable(tf.constant(0.0,shape=[512],dtype=tf.float32),name='b')
conv = tf.nn.conv2d(self.pool4,w,[1,1,1,1],padding='SAME')
out = tf.nn.bias_add(conv,b)
self.conv5_1 = tf.nn.relu(out,name=scope.name)
self.parameters += [w,b]
with tf.variable_scope("conv5_2") as scope:
w = tf.Variable(tf.truncated_normal([3,3,512,512]),name='w')
b = tf.Variable(tf.constant(0.0,shape=[512],dtype=tf.float32),name='b')
conv = tf.nn.conv2d(self.conv5_1,w,[1,1,1,1],padding='SAME')
out = tf.nn.bias_add(conv,b)
self.conv5_2 = tf.nn.relu(out,name=scope.name)
self.parameters += [w,b]
with tf.variable_scope("conv5_3") as scope:
w = tf.Variable(tf.truncated_normal([3,3,512,512]),name='w')
b = tf.Variable(tf.constant(0.0,shape=[512],dtype=tf.float32),name='b')
conv = tf.nn.conv2d(self.conv5_2,w,[1,1,1,1],padding='SAME')
out = tf.nn.bias_add(conv,b)
self.conv5_3 = tf.nn.relu(out,name=scope.name)
self.parameters += [w,b]
self.pool5 = tf.nn.max_pool(self.conv5_3,[1,2,2,1],[1,2,2,1],padding='SAME',name='pool5')
def getClassifier(self):
with tf.variable_scope("fc6") as scope:
shape = int(np.prod(self.pool5.get_shape()[1:]))
w = tf.Variable(tf.truncated_normal([shape,4096],dtype=tf.float32),name='w')
b = tf.Variable(tf.constant(1.0,shape=[4096],dtype=tf.float32,name='b'))
flat = tf.reshape(self.pool5,[-1,shape])
fc = tf.nn.bias_add(tf.matmul(flat,w),b)
self.fc6 = tf.nn.relu(fc)
self.parameters +=[w,b]
with tf.variable_scope("fc7") as scope:
w = tf.Variable(tf.truncated_normal([4096,4096],dtype=tf.float32),name='w')
b = tf.Variable(tf.constant(1.0,shape=[4096],dtype=tf.float32,name='b'))
fc = tf.nn.bias_add(tf.matmul(self.fc6,w),b)
self.fc7 = tf.nn.relu(fc)
self.parameters +=[w,b]
with tf.variable_scope("fc8") as scope:
w = tf.Variable(tf.truncated_normal([4096,1000],dtype=tf.float32),name='w')
b = tf.Variable(tf.constant(1.0,shape=[1000],dtype=tf.float32,name='b'))
fc = tf.nn.bias_add(tf.matmul(self.fc7,w),b)
self.fc8 = tf.nn.relu(fc)
self.parameters +=[w,b]
def loadmodel(self,sess,modepath="vgg16_weights.npz"):
weights = np.load(modepath)
keys = np.sort(weights.files)
for i,k in enumerate(keys):
print(i,k,np.shape(weights[k]))
sess.run(self.parameters[i].assign(weights[k]))
sess = tf.InteractiveSession()
X = tf.placeholder(dtype=tf.float32,shape=[1,224,224,3])
model = VGG16(X)
with tf.device('/cpu:0'):
model.loadmodel(sess)
im = np.asarray(Image.open("dog.jpg").resize((224,224)))
im_true = im
im = np.expand_dims(im,axis=0)
prob = []
with tf.device("/cpu:0"):
prob = sess.run(model.probs,feed_dict={X:im})
final_class = caffe_classes.class_names[np.argmax(prob)]
print("the finale class is {}".format(final_class))
plt.imshow(im_true)
测试,输出结果:

网友评论