4种经典的卷积神经网络,AlexNet(8),VGGNet(19),Google Inception net(22),ResNet(152)。
AlexNet:
Trick:ReLu, Dropout,LPN,gpu加速
显示每一个卷积层或者池化层输出tensor的尺寸
print(t.op.name, ' ', t.get_shape().as_list())
第一个卷积层conv1,通过下列句子,可以将scope内生成的Variable自动命名为conv1/xxx,便于区分不同卷积层之间的组件。
with tf.name_scope('conv1') as构造正态分布的随机tensor
# 作为网络的inputimages = tf.Variable(tf.random_nomal([batch_size, image_size,image_size,3],dtype = tf.float32, stddev = 1e-1))
VGGNet:
VGG网络简洁,整个网络都用了同样大小的卷积核尺寸(3 * 3)和最大池化尺寸(2 * 2 )。
两个3 * 3的卷积层串联相当于1个5 * 5的卷积层,即一个像素会跟周围5 * 5的像素产生关联,可以说感受野大小为5 * 5。
三个串联的3 * 3的卷积层,相当于1个7 * 7。但3个3 * 3的卷积层拥有比1个7 * 7的卷积层更多的非线性变换,使得CNN对特征的学习能力更强。
kernel = tf.get_variable(scope + "w",
shape = [n_in, n_out],dtype = tf.float32,
initializer = tf.contrib.layers.xavier_initializer())
在进入全连接层之前,需要将卷积结果扁平化。
shp = pool5.get_shape()flattened_shape = shp[1].value * shp[2].value * shp[3].value
# 将每个样本化为一维向量
resh1 = tf.reshape(pool5, [-1, flattened_shape], name = "resh1")
在FC层之后,用soft max进行处理,得到分类概率。用tf.argmax求输出概率最大的类别。
softmax = tf.nn.softmax(fc8)predictions = tf.argmax(softmax,1)
VGGnet的模型参数虽然比AlexNet多,但反而只需要较少的迭代次数就可以收敛,主要原因是更深的网络和更小的卷积核带来的隐式的正则化效果。
Google Inception net:
Inception V3
这里使用tf.contrib.slim辅助设计这个网络,contrib.slim中的一些功能和组件可以大大减少设计Inception Net的代码量。如,可以用一行代码定义一个卷积层。
with slim.arg_scope([slim.conv2d, slim.max_pool2d, slim.avg_pool2d], stride=1, padding='VALID'):'
net = slim.conv2d(inputs, 32, [3,3], stride=2, scope='Conv2d_1a_3x3')# tf.concat将4个分支的输出合并在一起(在输出通道上合并)
net = tf.concat([branch_0, branch_1, branch_2, branch_3], 3)
在分支里内开了2个分支
branch_1 = tf.concat([slim.conv2d(branch_1, 384, [1,3], scope='Conv2d_0b_1x3'),
slim.conv2d(branch_1, 384, [3,1], scope='Conv2d_0b_3x1')],3)
去除输出tensor中维数为1的维度:
logits = tf.squeeze(logits,[1,2],name = 'SpatialSqueeze')ResNet:
ResNet的结构可以极快地加速超深神经网络的训练,模型的准确率也有非常大的提升。
ResNet允许原始输入信息直接传输到后面的层中。
ResNet相当于将学习目标改变了,不再是学习一个完整的输出H(x),只是输出和输入的差别,即残差。
普通直连的卷积神经网络和ResNet的最大区别在于,ResNet有很多旁路的支线将输入直接连到后面的层,使得后面的层可以直接学习残差,这种结构被称为shortcut或skip connections。