美文网首页
使用Tensorflow实现VGG16

使用Tensorflow实现VGG16

作者: csuhan | 来源:发表于2019-04-16 00:03 被阅读0次

参考:https://www.cs.toronto.edu/~frossard/post/vgg16/

论文地址:https://arxiv.org/pdf/1409.1556.pdf

1. VGG16

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

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)

测试,输出结果:


Dog

相关文章

网友评论

      本文标题:使用Tensorflow实现VGG16

      本文链接:https://www.haomeiwen.com/subject/epimwqtx.html