深度学习实战篇之 ( 十四) -- TensorFlow之VGG16

2022-06-01 20:15:10 浏览数 (1)

科普知识

国际计算机视觉与模式识别会议(CVPR)是IEEE一年一度的学术性会议,会议的主要内容是计算机视觉与模式识别技术。CVPR是世界顶级的计算机视觉会议(三大顶会之一,另外两个是ICCV和ECCV),近年来每年有约1500名参加者,收录的论文数量一般300篇左右。本会议每年都会有固定的研讨主题,而每一年都会有公司赞助该会议并获得在会场展示的机会。

# 前言

SEP.

同学们,我们终于又见面了,你们的小编,世外居士已经回来了,距离最近的一篇文章9.26号已经快一个月了,小编也很想念大家,最近忙着写论文,困了几个月了,放弃可惜,不放弃又不出好的结果,结果一直僵持,最终还是搞定了,还取得了比较SOTA的结果,这不刚一结束完论文就来拥抱大家了。言归正传,我们紧跟着上一篇理论篇的文章深度学习理论篇之 ( 十五) -- VGG之初探深度之谜,趁热打铁进行实战训练。

TensorFlow之VGG16实战

本次VGG16网络结构,我们依旧采用之前的鲜花数据集,代码部分也依旧采用之前的结构,但是输入数据的处理代码稍微升级了下,其余的大同小异,之后我会将代码放到代码托管平台,方便同学们下载测试。

1.数据准备

五分类鲜花数据集:主要分为训练和验证集:train和val,每个集下包含五个类别的鲜花,通常来说训练集的数量远多于验证集同类别的数量。

2.网络结构

'''

VGG网络结构 input: 224x224x3

1. 64通道卷积层块: 输入: 224x224x3, 2层3x3x64的卷积结构, padding, 输出:64x224x224

2. maxpooling1: 输入: 64x224x224, 输出: 64x112x112

3. 128通道卷积块:输入: 64x112x1122, 2层3x3x128的卷积结构, padding,输出:128x112x112

4. maxpooling2: 输入: 128x112x112, 输出: 128x56x56

5. 256通道卷积块:输入: 128x56x563层, 3x3x256的卷积结构, padding, 输出:256x56x56。

6. maxpooling3: 输入: 256x56x56, 输出: 256x28x28

7. 512通道卷积块: 输入: 256x28x28, 3层3x3x512的卷积结构, padding, 输出:512x28x28。

8 maxpooling4: 输入:512x28x28, 输出:512x14x14。

9. 512通道卷积块: 输入: 512x14x14, 3层3x3x512的卷积结构, padding, 输出:512x14x14。

10. maxpooling4: 输入:512x14x14, 输出:512x7x7。

11. 全连接层1: 输入:512*7*7,输出:4096

12. 全连接层1: 输入:4096,输出:4096

13. 全连接层1: 输入:4096,输出:5(类别数目)

'''

代码语言:javascript复制
def inference(images, batch_size, n_classes,drop_rate):
    # 一个简单的卷积神经网络,卷积 池化层x2,全连接层x2,最后一个softmax层做分类。
    # 卷积层1
    # 1. 64通道卷积层块: 输入: 224x224x3, 2层3x3x64的卷积结构, padding, 输出:64x224x224
    # 2. maxpooling1:输入: 64x224x224, 输出: 112x112x64
    conv1 = Conv_layer(names = 'conv_block1', input = images , w_shape = [3, 3, 3, 64], b_shape = [64], strid = [1, 1])
    conv2 = Conv_layer(names = 'conv_block2', input = conv1 , w_shape = [3, 3, 64, 64], b_shape = [64], strid = [1, 1])
    pool_1 = Max_pool_lrn(names = 'pooling1', input = conv2 , ksize = [1, 2, 2, 1], is_lrn = True)

    # 3. 128通道卷积块:输入: 64x112x1122, 2层3x3x128的卷积结构, padding,输出:128x112x112
    # 4. maxpooling2: 输入: 128x112x112, 输出: 128x56x56
    conv3 = Conv_layer(names = 'conv_block3', input = pool_1 , w_shape = [3, 3, 64, 128], b_shape = [128], strid = [1, 1])
    conv4 = Conv_layer(names = 'conv_block4', input = conv3 , w_shape = [3, 3, 128, 128], b_shape = [128], strid = [1, 1])
    pool_2 = Max_pool_lrn(names = 'pooling2', input = conv4 , ksize = [1, 2, 2, 1], is_lrn = False)

    # 5. 256通道卷积块:输入: 128x56x56, 3层3x3x256的卷积结构, padding, 输出:256x56x56。
    # 6. maxpooling3: 输入: 256x56x56, 输出: 256x28x28
    
    conv5 = Conv_layer(names = 'conv_block5', input = pool_2 , w_shape = [3, 3, 128, 256], b_shape = [256], strid = [1, 1])
    conv6 = Conv_layer(names = 'conv_block6', input = conv5 , w_shape = [3, 3, 256, 256], b_shape = [256], strid = [1, 1])
    conv7 = Conv_layer(names = 'conv_block7', input = conv6 , w_shape = [3, 3, 256, 256], b_shape = [256], strid = [1, 1])
    pool_3 = Max_pool_lrn(names = 'pooling3', input = conv7 , ksize = [1, 2, 2, 1], is_lrn = False)

    # 7. 512通道卷积块: 输入: 256x28x28, 3层3x3x512的卷积结构, padding, 输出:512x28x28。
    # 8  maxpooling4: 输入:512x28x28, 输出:512x14x14。
    conv8 = Conv_layer(names = 'conv_block8', input = pool_3 , w_shape = [3, 3, 256, 512], b_shape = [512], strid = [1, 1])
    conv9 = Conv_layer(names = 'conv_block9', input = conv8 , w_shape = [3, 3, 512, 512], b_shape = [512], strid = [1, 1])
    conv10 = Conv_layer(names = 'conv_block10', input = conv9 , w_shape = [3, 3, 512, 512], b_shape = [512], strid = [1, 1])
    pool_4 = Max_pool_lrn(names = 'pooling4', input = conv10 , ksize = [1, 2, 2, 1], is_lrn = False)
    # print(pool_4.shape)

    # 9. 512通道卷积块: 输入: 512x14x14, 3层3x3x512的卷积结构, padding, 输出:512x14x14。
    # 10. maxpooling4: 输入:512x14x14, 输出:512x7x7。
    conv11 = Conv_layer(names = 'conv_block11', input = pool_4 , w_shape = [3, 3, 512, 512], b_shape = [512], strid = [1, 1])
    conv12 = Conv_layer(names = 'conv_block12', input = conv11 , w_shape = [3, 3, 512, 512], b_shape = [512], strid = [1, 1])
    conv13 = Conv_layer(names = 'conv_block13', input = conv12 , w_shape = [3, 3, 512, 512], b_shape = [512], strid = [1, 1])
    pool_5 = Max_pool_lrn(names = 'pooling5', input = conv13 , ksize = [1, 2, 2, 1], is_lrn = False)

    # 11. 全连接层1:输入:512*7*7,输出:4096
    # 12. 全连接层1:输入:4096,输出:4096
    # 13. 全连接层1:输入:4096,输出:5(类别数目)
    reshape = tf.reshape(pool_5, shape=[batch_size, -1])
    dim = reshape.get_shape()[1].value

    local_1 = local_layer(names = 'local1_scope', input = reshape , w_shape = [dim, 4096], b_shape = [4096])
    local_2 = local_layer(names = 'local2_scope', input = local_1 , w_shape = [4096, 4096], b_shape = [4096])

    with tf.variable_scope('softmax_linear') as scope:
        weights = tf.Variable(tf.truncated_normal(shape=[4096, n_classes], stddev=0.005, dtype=tf.float32),
                              name='softmax_linear', dtype=tf.float32)

        biases = tf.Variable(tf.constant(value=0.1, dtype=tf.float32, shape=[n_classes]),
                             name='biases', dtype=tf.float32)

        softmax_linear = tf.add(tf.matmul(local_2, weights), biases, name='softmax_linear')
        # print("---------softmax_linear:{}".format(softmax_linear))

    return softmax_linear

3.训练过程

源码获取:https://gitee.com/fengyuxiexie/tensor-flow-vgg16

END

结语

本次分享到这里就结束啦,TensorFlow的代码实践虽然完成了,但是请注意以下几个问题。

1.由于我们仅仅注重于网络构建,并没有进行调参,因此网络的性能可能表现不佳。

2.在训练过程中按道理应该训练一轮数据就在训练集和测试集测试,但是我们的代码中是训练完一个batch就对测试集测试,这里需要改进。

3.输入数据部分的代码较之前有了改进,使用请注意,例如对每个类别的标签是自定义的。

各位,周末愉快,科研人,晚安!

编辑:玥怡居士|审核:小圈圈居士

0 人点赞