经典卷积神经网络(4)--InceptionNet-V3卷积网络模型
InceptionV1
GoogLeNet是一个22层的CNN,它以6.7%的错误率赢得了2014年度ILSVRC的冠军。这是第一个跟传统方法,也就是卷积层与池化层简单叠加以形成序列结构的方法不同的一种CNN的新架构。
按传统方法来增加模型深度,存在一些缺陷:
1.网络模型产生巨大参数,容易导致过拟合。
2.网络规模扩大会极大增加计算量,消耗更多计算机的资源。
InceptionV2
1.Inception V2学习了VGGNet,用两个3´3的卷积代替5´5的大卷积(用以降低参数量,减少计算量)
2.提出了著名的Batch Normalization(以下简称BN)方法。
BN是一个非常有效的正则化方法,可以让大型卷积网络的训练速度加快很多倍,同时收敛后的分类准确率也可以得到大幅提高。BN在用于神经网络某层时,会对每一个mini-batch数据的内部进行标准化(normalization)处理,使输出规范化到N(0,1)的正态分布,减少了Internal Covariate Shift(内部神经元分布的改变)。
BN的论文指出,传统的深度神经网络在训练时,每一层的输入的分布都在变化,导致训练变得困难,我们只能使用一个很小的学习速率解决这个问题。而对每一层使用BN之后,我们就可以有效地解决这个问题,学习速率可以增大很多倍,达到之前的准确率所需要的迭代次数只有1/14,训练时间大大缩短。而达到之前的准确率后,可以继续训练,并最终取得远超于Inception V1模型的性能——top-5错误率4.8%,已经优于人眼水平。
InceptionV3
InceptionV3对InceptionV2主要进行了两方面的改进
1.一方面,引入了Factorization into small convolutions的思想(分解大尺寸卷积为多个小卷积乃至一维卷积),将一个较大的二维卷积拆成两个较小的一维卷积,比如将7´7卷积拆成1´7卷积和7´1卷积,或者将3´3卷积拆成1´3卷积和3´1卷积,如下图所示。一方面节约了大量参数,加速运算并减轻了过拟合(比将7´7卷积拆成1´7卷积和7´1卷积,比拆成3个3´3卷积更节约参数),同时增加了一层非线性扩展模型表达能力。论文中指出,这种非对称的卷积结构拆分,其结果比对称地拆为几个相同的小卷积核效果更明显,可以处理更多、更丰富的空间特征,增加特征多样性。
于是,任意nxn的卷积都可以通过1xn卷积后接nx1卷积来替代。实际上,作者发现在网络的前期使用这种分解效果并不好,在中度大小的feature map上使用效果才会更好。(对于mxm大小的feature map,建议m在12到20之间)。
2.另一方面,Inception V3优化了Inception Module的结构,现在Inception Module有35´35(书上图8-14a)、17´17(书上图8-14b)和8´8(书上图8-14c)三种不同结构。这些Inception Module只在网络的后部出现,前部还是普通的卷积层。并且Inception V3除了在Inception Module中使用分支,还在分支中使用了分支(8´8的结构中),可以说是Network In Network In Network。
InceptionV3的一个module
tensor中的slim库
在阅读用tensorflow实现的深度学习网络结构的源码时,经常会看到使用TF中封装的slim高级库,看起来(实际上也是)比直接调用TF的API简洁好多。 TF-Slim是tensorflow中定义、训练和评估复杂模型的轻量级库。tf-slim中的组件可以轻易地和原生tensorflow框架。
TF-slim主要由下面几个组成:
[code]arg_scope data evluation layers learning losses metrics nets queues regularizers variables
tf.nn.conv2d和tf.contrib.slim.conv2d的区别
tf.nn.conv2d()搭建一个卷积时,
- 创建权重、偏置变量
- 将来自上一层的数据和权值进行卷积
- 在卷积结果上加上偏置
- 应用激活函数
[code]with tf.variable_scope("conv1_1"): conv1_weights = tf.get_variable("weight", [5, 5, 1, 32], initializer=tf.truncated_normal_initializer(stddev=0.1)) conv1_biases = tf.get_variable("bias", [32], initializer=tf.constant_initializer(0.0)) conv1 = tf.nn.conv2d(input_tensor, conv1_weights, strides=[1, 1, 1, 1], padding="SAME") relu1 = tf.nn.relu(tf.nn.bias_add(conv1, conv1_biases))
为了缓解重复这些代码,Slim库在更抽象的神经网络层的层面上提供了大量方便使用的操作符。tf.contrib.slim.conv2d()是上面代码封装后的结果,
tf.contrib.slim.conv2d (inputs, num_outputs,[卷积核个数] kernel_size,[卷积核的高度,卷积核的宽度] stride=1, padding="SAME" scope[变量空间名])
使用arg_scope后可以避免在每个slim.conv2d中添加重复的参数(如straide=1,padding="SAME",weight_initializer=xxx等)
[code]import tensorflow as tf import tensorflow.contrib.slim as slim #用slim的srg_scope()函数设置一些会用到卷积或池化函数的默认参数, #这包括stride=1和padding="SAME" with slim.arg_scope([slim.conv2d,slim.max_pool2d,slim.avg_pool2d],stride=1, padding="SAME"): #在这里为InceptionModule创建一个统一的变量命名空间,模块里面有多个路径, #每一条路径都会接收模块之前网络节点的输出,这里用last_net统一代表这个输出 with tf.variable_scope("Module"): #使用变量空间的名字标识模块的路径,这类似于"BRANCH_n"的形式, #例如BRANCH_1表示这个模块里的第二条路径 with tf.variable_scope("BRANCH_0"): branch_0 = slim.conv2d(last_net,320,[1,1],scope="Conv2d_0a_1x1") with tf.variable_scope("BRANCH_1"): branch_1 = slim.conv2d(last_net,384,[1,1],scope="Conv2d_1a_1x1") #concat()函数实现了拼接的功能,函数原型为concat(values,axis,name) #第一个参数用于指定拼接的维度信息,对于InceptionModule,值一般为3, #表示在第三个维度上进行拼接(串联),第二个参数是用于拼接的两个结果 branch_1 = tf.concat(3,[ slim.conv2d(branch_1, 384, [1,3], scope="Conv2d_1b_1x3"), slim.conv2d(branch_1, 384, [3,1], scope="Conv2d_1c_3x1")]) with tf.variable_scope("BRANCH_2"): branch_2 = slim.conv2d(last_net,448,[1,1],scope="Conv2d_2a_1x1") branch_2 = slim.conv2d(branch_2, 384, [3,3], scope="Conv2d_2b_3x3") branch_2 = tf.concat(3,[ slim.conv2d(branch_2, 384, [1,3], scope="Conv2d_2c_1x3"), slim.conv2d(branch_2, 384, [3,1], scope="Conv2d_2d_3x1")]) with tf.variable_scope("BRANCH_3"): branch_3 = slim.avg_pool2d(last_net, [3,3], scope="AvgPool_3a_3x3") branch_2 = slim.conv2d(branch_3, 192, [1, 1], scope="Conv2d_3a_1x1") #最后用concat()函数将InceptionModule每一条路径的结果进行拼接得到最终结果 Module_output = tf.concat(3,[branch_0,branch_1,branch_2,branch_3])
tf.concat(values,concat_dim,name)
concat_dim表示你在哪个维度上进行连接,他是整数,从0开始计数,0表示第一个维度,1表示第二个维度...... values是一个列表。列表里面是要连接的矩阵或者数组。
- TensorFlow 深度学习框架(9)-- 经典卷积网络模型 : LeNet-5 模型 & Inception-v3 模型
- TensorFlow 深度学习框架(9)-- 经典卷积网络模型 : LeNet-5 模型 & Inception-v3 模型
- TensorFlow 深度学习框架(9)-- 经典卷积网络模型 : LeNet-5 模型 & Inception-v3 模型
- TensorFlow 深度学习框架(9)-- 经典卷积网络模型 : LeNet-5 模型 & Inception-v3 模型
- TensorFlow 深度学习框架(9)-- 经典卷积网络模型 : LeNet-5 模型 & Inception-v3 模型
- TensorFlow 深度学习框架(9)-- 经典卷积网络模型 : LeNet-5 模型 & Inception-v3 模型
- TensorFlow 深度学习框架(9)-- 经典卷积网络模型 : LeNet-5 模型 & Inception-v3 模型
- TensorFlow 深度学习框架(9)-- 经典卷积网络模型 : LeNet-5 模型 & Inception-v3 模型
- TensorFlow 深度学习框架(9)-- 经典卷积网络模型 : LeNet-5 模型 & Inception-v3 模型
- TensorFlow 深度学习框架(9)-- 经典卷积网络模型 : LeNet-5 模型 & Inception-v3 模型
- TensorFlow 深度学习框架(9)-- 经典卷积网络模型 : LeNet-5 模型 & Inception-v3 模型
- TensorFlow 深度学习框架(9)-- 经典卷积网络模型 : LeNet-5 模型 & Inception-v3 模型
- TensorFlow 深度学习框架(9)-- 经典卷积网络模型 : LeNet-5 模型 & Inception-v3 模型
- TensorFlow 深度学习框架(9)-- 经典卷积网络模型 : LeNet-5 模型 & Inception-v3 模型
- 深度学习卷积神经网络——经典网络GoogLeNet(Inception V3)网络的搭建与实现
- TensorFlow 深度学习框架(9)-- 经典卷积网络模型 : LeNet-5 模型 & Inception-v3 模型
- TensorFlow 深度学习框架(9)-- 经典卷积网络模型 : LeNet-5 模型 & Inception-v3 模型
- TensorFlow 深度学习框架(9)-- 经典卷积网络模型 : LeNet-5 模型 & Inception-v3 模型
- TensorFlow 深度学习框架(9)-- 经典卷积网络模型 : LeNet-5 模型 & Inception-v3 模型
- TensorFlow 深度学习框架(9)-- 经典卷积网络模型 : LeNet-5 模型 & Inception-v3 模型