科普知识
国际计算机视觉与模式识别会议(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.输入数据部分的代码较之前有了改进,使用请注意,例如对每个类别的标签是自定义的。
各位,周末愉快,科研人,晚安!
编辑:玥怡居士|审核:小圈圈居士