Vgg16图像分类

#请仔细研读,领会梯度下降法,这是深度学习模型训练的基本方法。可以使用Anaconda(spyder)编辑和执行

#预训练的权值文件下载地址:https://pan.baidu.com/s/1Cjp0uFvi49Myq3ylIMzR2g

# -*- coding: utf-8 -*-

"""

Created on Thu Nov  7 20:47:28 2019



@author: admin

"""



import tensorflow.compat.v1 as tf

tf.disable_v2_behavior()



import numpy as np

from scipy.misc import imread, imresize

from imagenet_classes import class_names





class vgg16:

    def __init__(self, imgs, weights=None, sess=None):

        self.imgs = imgs

        self.convlayers()

        self.fc_layers()

        self.probs = tf.nn.softmax(self.fc3l)

        if weights is not None and sess is not None:

            self.load_weights(weights, sess)





    def convlayers(self):

        self.parameters = []



        # zero-mean input

        with tf.name_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.imgs-mean



        # conv1_1

        with tf.name_scope('conv1_1') as scope:

            kernel = tf.Variable(tf.truncated_normal([3, 3, 3, 64], dtype=tf.float32,

                                                     stddev=1e-1), name='weights')%三个通道,3*3的卷积核大小,64个核

            conv = tf.nn.conv2d(images, kernel, [1, 1, 1, 1], padding='SAME')#步长、填充

            biases = tf.Variable(tf.constant(0.0, shape=[64], dtype=tf.float32),

                                 trainable=True, name='biases')#偏置初始化

            out = tf.nn.bias_add(conv, biases)

            self.conv1_1 = tf.nn.relu(out, name=scope)#激活函数

            self.parameters += [kernel, biases]



        # conv1_2

        with tf.name_scope('conv1_2') as scope:

            kernel = tf.Variable(tf.truncated_normal([3, 3, 64, 64], dtype=tf.float32,

                                                     stddev=1e-1), name='weights')

            conv = tf.nn.conv2d(self.conv1_1, kernel, [1, 1, 1, 1], padding='SAME')

            biases = tf.Variable(tf.constant(0.0, shape=[64], dtype=tf.float32),

                                 trainable=True, name='biases')

            out = tf.nn.bias_add(conv, biases)

            self.conv1_2 = tf.nn.relu(out, name=scope)

            self.parameters += [kernel, biases]



        # pool1

        self.pool1 = tf.nn.max_pool(self.conv1_2,

                               ksize=[1, 2, 2, 1],#核大小

                               strides=[1, 2, 2, 1],#步长,上下、左右方向

                               padding='SAME',

                               name='pool1')



        # conv2_1  其它组的变化主要是参数大小,主要差别:通道数      组内间差异小

        with tf.name_scope('conv2_1') as scope:

            kernel = tf.Variable(tf.truncated_normal([3, 3, 64, 128], dtype=tf.float32,

                                                     stddev=1e-1), name='weights')

            conv = tf.nn.conv2d(self.pool1, kernel, [1, 1, 1, 1], padding='SAME')

            biases = tf.Variable(tf.constant(0.0, shape=[128], dtype=tf.float32),

                                 trainable=True, name='biases')

            out = tf.nn.bias_add(conv, biases)

            self.conv2_1 = tf.nn.relu(out, name=scope)

            self.parameters += [kernel, biases]



        # conv2_2

        with tf.name_scope('conv2_2') as scope:

            kernel = tf.Variable(tf.truncated_normal([3, 3, 128, 128], dtype=tf.float32,

                                                     stddev=1e-1), name='weights')

            conv = tf.nn.conv2d(self.conv2_1, kernel, [1, 1, 1, 1], padding='SAME')

            biases = tf.Variable(tf.constant(0.0, shape=[128], dtype=tf.float32),

                                 trainable=True, name='biases')

            out = tf.nn.bias_add(conv, biases)

            self.conv2_2 = tf.nn.relu(out, name=scope)

            self.parameters += [kernel, biases]



        # pool2

        self.pool2 = tf.nn.max_pool(self.conv2_2,

                               ksize=[1, 2, 2, 1],

                               strides=[1, 2, 2, 1],

                               padding='SAME',

                               name='pool2')



        # conv3_1

        with tf.name_scope('conv3_1') as scope:

            kernel = tf.Variable(tf.truncated_normal([3, 3, 128, 256], dtype=tf.float32,

                                                     stddev=1e-1), name='weights')

            conv = tf.nn.conv2d(self.pool2, kernel, [1, 1, 1, 1], padding='SAME')

            biases = tf.Variable(tf.constant(0.0, shape=[256], dtype=tf.float32),

                                 trainable=True, name='biases')

            out = tf.nn.bias_add(conv, biases)

            self.conv3_1 = tf.nn.relu(out, name=scope)

            self.parameters += [kernel, biases]



        # conv3_2

        with tf.name_scope('conv3_2') as scope:

            kernel = tf.Variable(tf.truncated_normal([3, 3, 256, 256], dtype=tf.float32,

                                                     stddev=1e-1), name='weights')

            conv = tf.nn.conv2d(self.conv3_1, kernel, [1, 1, 1, 1], padding='SAME')

            biases = tf.Variable(tf.constant(0.0, shape=[256], dtype=tf.float32),

                                 trainable=True, name='biases')

            out = tf.nn.bias_add(conv, biases)

            self.conv3_2 = tf.nn.relu(out, name=scope)

            self.parameters += [kernel, biases]



        # conv3_3

        with tf.name_scope('conv3_3') as scope:

            kernel = tf.Variable(tf.truncated_normal([3, 3, 256, 256], dtype=tf.float32,

                                                     stddev=1e-1), name='weights')

            conv = tf.nn.conv2d(self.conv3_2, kernel, [1, 1, 1, 1], padding='SAME')

            biases = tf.Variable(tf.constant(0.0, shape=[256], dtype=tf.float32),

                                 trainable=True, name='biases')

            out = tf.nn.bias_add(conv, biases)

            self.conv3_3 = tf.nn.relu(out, name=scope)

            self.parameters += [kernel, biases]



        # pool3

        self.pool3 = tf.nn.max_pool(self.conv3_3,

                               ksize=[1, 2, 2, 1],

                               strides=[1, 2, 2, 1],

                               padding='SAME',

                               name='pool3')



        # conv4_1

        with tf.name_scope('conv4_1') as scope:

            kernel = tf.Variable(tf.truncated_normal([3, 3, 256, 512], dtype=tf.float32,

                                                     stddev=1e-1), name='weights')

            conv = tf.nn.conv2d(self.pool3, kernel, [1, 1, 1, 1], padding='SAME')

            biases = tf.Variable(tf.constant(0.0, shape=[512], dtype=tf.float32),

                                 trainable=True, name='biases')

            out = tf.nn.bias_add(conv, biases)

            self.conv4_1 = tf.nn.relu(out, name=scope)

            self.parameters += [kernel, biases]



        # conv4_2

        with tf.name_scope('conv4_2') as scope:

            kernel = tf.Variable(tf.truncated_normal([3, 3, 512, 512], dtype=tf.float32,

                                                     stddev=1e-1), name='weights')

            conv = tf.nn.conv2d(self.conv4_1, kernel, [1, 1, 1, 1], padding='SAME')

            biases = tf.Variable(tf.constant(0.0, shape=[512], dtype=tf.float32),

                                 trainable=True, name='biases')

            out = tf.nn.bias_add(conv, biases)

            self.conv4_2 = tf.nn.relu(out, name=scope)

            self.parameters += [kernel, biases]



        # conv4_3

        with tf.name_scope('conv4_3') as scope:

            kernel = tf.Variable(tf.truncated_normal([3, 3, 512, 512], dtype=tf.float32,

                                                     stddev=1e-1), name='weights')

            conv = tf.nn.conv2d(self.conv4_2, kernel, [1, 1, 1, 1], padding='SAME')

            biases = tf.Variable(tf.constant(0.0, shape=[512], dtype=tf.float32),

                                 trainable=True, name='biases')

            out = tf.nn.bias_add(conv, biases)

            self.conv4_3 = tf.nn.relu(out, name=scope)

            self.parameters += [kernel, biases]



        # pool4

        self.pool4 = tf.nn.max_pool(self.conv4_3,

                               ksize=[1, 2, 2, 1],

                               strides=[1, 2, 2, 1],

                               padding='SAME',

                               name='pool4')



        # conv5_1

        with tf.name_scope('conv5_1') as scope:

            kernel = tf.Variable(tf.truncated_normal([3, 3, 512, 512], dtype=tf.float32,

                                                     stddev=1e-1), name='weights')

            conv = tf.nn.conv2d(self.pool4, kernel, [1, 1, 1, 1], padding='SAME')

            biases = tf.Variable(tf.constant(0.0, shape=[512], dtype=tf.float32),

                                 trainable=True, name='biases')

            out = tf.nn.bias_add(conv, biases)

            self.conv5_1 = tf.nn.relu(out, name=scope)

            self.parameters += [kernel, biases]



        # conv5_2

        with tf.name_scope('conv5_2') as scope:

            kernel = tf.Variable(tf.truncated_normal([3, 3, 512, 512], dtype=tf.float32,

                                                     stddev=1e-1), name='weights')

            conv = tf.nn.conv2d(self.conv5_1, kernel, [1, 1, 1, 1], padding='SAME')

            biases = tf.Variable(tf.constant(0.0, shape=[512], dtype=tf.float32),

                                 trainable=True, name='biases')

            out = tf.nn.bias_add(conv, biases)

            self.conv5_2 = tf.nn.relu(out, name=scope)

            self.parameters += [kernel, biases]



        # conv5_3

        with tf.name_scope('conv5_3') as scope:

            kernel = tf.Variable(tf.truncated_normal([3, 3, 512, 512], dtype=tf.float32,

                                                     stddev=1e-1), name='weights')

            conv = tf.nn.conv2d(self.conv5_2, kernel, [1, 1, 1, 1], padding='SAME')

            biases = tf.Variable(tf.constant(0.0, shape=[512], dtype=tf.float32),

                                 trainable=True, name='biases')

            out = tf.nn.bias_add(conv, biases)

            self.conv5_3 = tf.nn.relu(out, name=scope)

            self.parameters += [kernel, biases]



        # pool5

        self.pool5 = tf.nn.max_pool(self.conv5_3,

                               ksize=[1, 2, 2, 1],

                               strides=[1, 2, 2, 1],

                               padding='SAME',

                               name='pool4')



    def fc_layers(self):#两个全连接层

        # fc1

        with tf.name_scope('fc1') as scope:

            shape = int(np.prod(self.pool5.get_shape()[1:]))#展开成向量

            fc1w = tf.Variable(tf.truncated_normal([shape, 4096],

                                                         dtype=tf.float32,

                                                         stddev=1e-1), name='weights')

            fc1b = tf.Variable(tf.constant(1.0, shape=[4096], dtype=tf.float32),

                                 trainable=True, name='biases')

            pool5_flat = tf.reshape(self.pool5, [-1, shape])#y=a*x+b

            fc1l = tf.nn.bias_add(tf.matmul(pool5_flat, fc1w), fc1b)

            self.fc1 = tf.nn.relu(fc1l)

            self.parameters += [fc1w, fc1b]



        # fc2

        with tf.name_scope('fc2') as scope:

            fc2w = tf.Variable(tf.truncated_normal([4096, 4096],

                                                         dtype=tf.float32,

                                                         stddev=1e-1), name='weights')

            fc2b = tf.Variable(tf.constant(1.0, shape=[4096], dtype=tf.float32),

                                 trainable=True, name='biases')

            fc2l = tf.nn.bias_add(tf.matmul(self.fc1, fc2w), fc2b)

            self.fc2 = tf.nn.relu(fc2l)

            self.parameters += [fc2w, fc2b]



        # fc3 输出层

        with tf.name_scope('fc3') as scope:

            fc3w = tf.Variable(tf.truncated_normal([4096, 1000],#可分类1000类

                                                         dtype=tf.float32,

                                                         stddev=1e-1), name='weights')

            fc3b = tf.Variable(tf.constant(1.0, shape=[1000], dtype=tf.float32),

                                 trainable=True, name='biases')

            self.fc3l = tf.nn.bias_add(tf.matmul(self.fc2, fc3w), fc3b)

            self.parameters += [fc3w, fc3b]



    def load_weights(self, weight_file, sess):

        weights = np.load(weight_file)

        keys = sorted(weights.keys())

        for i, k in enumerate(keys):

            print(i, k, np.shape(weights[k]))

            sess.run(self.parameters[i].assign(weights[k]))



if __name__ == '__main__':

    sess = tf.Session()

    imgs = tf.placeholder(tf.float32, [None, 224, 224, 3])

    vgg = vgg16(imgs, 'vgg16_weights.npz', sess)#调用定义好的vgg16网络结构、训练好的权重、偏置,训练好的网络可以识别1000种的物体



    img1 = imread('laska.jpg', mode='RGB')

    img1 = imresize(img1, (224, 224))



    prob = sess.run(vgg.probs, feed_dict={vgg.imgs: [img1]})[0]

    preds = (np.argsort(prob)[::-1])[0:5]#输出概率大的前5个

    for p in preds:

        print(class_names[p], prob[p])


你可能感兴趣的:(深度学习)