GoogleNet系列网络原理及结构详解:从Inception-v1到v4
GoogleNet系列网络原理及结构详解:从Inception-v1到v4
-
1. Google Net综述
-
2. Inception v1
-
- 2.1 论文地址
- 2.2 网络结构
- 2.3 实验结果
- 2.4 代码实现
-
3. Inception v2
-
- 3.1 论文地址
- 3.2 网络结构
- 3.3 计算公式
- 3.4 实验结果
- 3.5 代码实现
-
4. Inception v3
-
- 4.1 论文地址
- 4.2 网络结构
- 4.3 补充
- 4.4 实验结果
- 4.5 代码实现
-
5. Inception v4
- 5.1 论文地址
- 5.2 网络结构
- 5.2.1 Inception-ResNet-v1
- 5.2.1.1 Stem模块的前馈网络
- 5.2.1.2 Inception-ResNet-A模块
- 5.2.1.3 Inception-ResNet-B模块
- 5.2.1.4 Inception-ResNet-C模块
- 5.2.1.5 Reduction-A或B模块
- 5.1 论文地址
-
5.2.2 Inception-ResNet-v2
- 5.2.2.1 输入前馈网络
- 5.2.2.2 Inception-ResNet-A模块
- 5.2.2.3 Inception-ResNet-B模块
- 5.2.2.4 Inception-ResNet-C模块
- 5.2.2.5 Reduction A/B模块
5.2.3 Inception-V4网络
5.2.3.1 stem的前馈路径
5.2.3.2 Inception A模块
5.2.3.3 Inception B模块
5.2.3.4 Inception C模块
5.2.3.5 Reduction A模块
5.2.3.6 Reduction B模块
* 5.3 核心思想
* 5.4 性能比较
* 5.5 试验结果
以下是本篇文章的总结部分,我们主要探讨了...
1. Google Net综述
Google Net是由2014年Google团队在ImageNet竞赛中开发的网络,实现了图像识别的第一名和目标检测的第二名的优异成绩。

其主要特点就是提出了一种叫做Inception的结构进行堆叠;
该结构的核心特点在于增强了网络的深度和宽度(主要集中在宽度方向),通过堆叠不同感受野大小的特征层,同时在不增加运算量的前提下,计算资源的利用效率得到了显著提升。
相较于两年前的ImageNet比赛最初冠军(同时也是卷积神经网络的开山之作),该模型在参数规模上较前作减少了约12倍,然而在top-5误差率方面却实现了显著的提升,从16.42%降至6.67%。
2. Inception v1
2.1 论文地址
https://arxiv.org/pdf/1409.4842.pdf
2.2 网络结构

Inception v1的网络结构如图所示:
图(a)展示了作者提出的一种基础Inception v1网络架构,其核心理念在于:对输入特征层,分别采用了不同尺寸的卷积核进行操作,具体包括1×1、3×3、5×5的卷积层,以及一个3×3的最大池化层,从而生成了具有不同感受野尺寸的特征层;通过将这些特征层进行拼接,最终获得了Inception v1网络的输出特征层。
图(b)展示了作者提出的一种改进结构方案。改进的原因可能源于Inception v1的输入层可能源于上一个Inception v1经过concat操作后的输出层,其深度可能会变得非常大。因此,即使采用少量的5x5卷积操作,也会显著增加计算量。
在3x3和5x5卷积操作前,我们引入了一层1x1卷积层用于降维。通过1x1卷积层的使用,在保持特征层感受野不变的前提下,降低了特征深度,从而减少了计算量。此外,经过1x1卷积层处理后,接上ReLU激活函数,能够有效提升网络的非线性特性。
2.3 实验结果

(1)融合模型的数量为Number-of-models;
(2)每张检测图片的裁剪区域数量为Number-of-Crops;
(3)计算成本Cost仅针对单张图片进行计算,其值等于模型数目与裁剪区域数目之积。
可以看到模型越多、取样越多,准确率就越高,但相应地计算开销就会越大。
2.4 代码实现
import tensorflow as tf
slim = tf.contrib.slim
def Incvption_v1_net(inputs, scope):
with tf.variable_scope(scope):
with slim.arg_scope([slim.conv2d],
activation_fn=tf.nn.relu, padding='SAME',
weights_regularizer=slim.l2_regularizer(5e-3)):
net = slim.max_pool2d(
inputs, [3, 3], strides=2, padding='SAME', scope='max_pool')
net_a = slim.conv2d(net, 64, [1, 1], scope='conv2d_a_1x1')
net_b = slim.conv2d(net, 96, [1, 1], scope='conv2d_b_1x1')
net_b = slim.conv2d(net_b, 128, [3, 3], scope='conv2d_b_3x3')
net_c = slim.conv2d(net, 16, [1, 1], scope='conv2d_c_1x1')
net_c = slim.conv2d(net_c, 32, [5, 5], scope='conv2d_c_5x5')
net_d = slim.max_pool2d(
net, [3, 3], strides=1, scope='pool3x3', padding='SAME')
net_d = slim.conv2d(
net_d, 32, [1, 1], scope='conv2d_d_1x1')
net = tf.concat([net_a, net_b, net_c, net_d], axis=-1)
return net
代码解读
3. Inception v2
3.1 论文地址
https://arxiv.org/pdf/1502.03167.pdf
3.2 网络结构

Inception v2在结构上没有发生显著变化,但首次提出了Batch Normalization的概念,通过将一个batch的数据变换到均值为0、方差为1的正态分布,使得数据分布趋于一致,从而有效避免了梯度消失问题。
3.3 计算公式

输入的是一个batch的图片(或者特征层),格式为NHWC;
计算过程:
(1)首先,计算数据集的均值μ;
(2)其次,计算数据集的无偏方差σ²;
(3)随后,对数据进行标准化处理,具体公式为x’=(x-μ)/√(σ²+ε);
(4)最后,通过缩放和平移变换,将标准化后的数据转换为目标尺度。
注:
(1)ε 被定义为一个极小的正数,其作用是为了防止除以零的情况发生;
(2)其中γ和β是可调节的参数,它们在模型训练过程中会被优化调整;
(3)当采用批归一化(batch normalization)时,全连接层无需添加bias项,因为β参数实际上起到了调整偏置的作用;
(4)在测试阶段,u和σ被设定为训练数据集train_data的均值和标准差。
3.4 实验结果

可以看到使用batch-normalization之后,Top-5 Error 从6.67%下降到了4.9%。
3.5 代码实现
import tensorflow as tf
slim = tf.contrib.slim
def Incvption_v1_net(inputs, scope):
with tf.variable_scope(scope):
with slim.arg_scope([slim.conv2d],
activation_fn=tf.nn.relu, padding='SAME',
weights_regularizer=slim.l2_regularizer(5e-3)):
net = slim.max_pool2d(
inputs, [3, 3], strides=2, padding='SAME', scope='max_pool')
net_a = slim.conv2d(net, 64, [1, 1], scope='conv2d_a_1x1')
net_b = slim.conv2d(net, 96, [1, 1], scope='conv2d_b_1x1')
net_b = slim.conv2d(net_b, 128, [3, 3], scope='conv2d_b_3x3')
net_c = slim.conv2d(net, 16, [1, 1], scope='conv2d_c_1x1')
net_c = slim.conv2d(net_c, 32, [5, 5], scope='conv2d_c_5x5')
net_d = slim.max_pool2d(
net, [3, 3], strides=1, scope='pool3x3', padding='SAME')
net_d = slim.conv2d(
net_d, 32, [1, 1], scope='conv2d_d_1x1')
net = tf.concat([net_a, net_b, net_c, net_d], axis=-1)
net = tf.layers.batch_normalization(net, name='BN')
return net
代码解读
4. Inception v3
4.1 论文地址
https://arxiv.org/pdf/1512.00567.pdf
4.2 网络结构


图(Figure 5)基于作者的思路,其中,一个5×5大小的卷积层与两个3×3大小的卷积层所得到的特征层的感受野大小均为5(如图所示);

如果采用两个3x3卷积核替代5x5的卷积核,可以显著降低参数量;例如,假设深度为C,一个5x5卷积核的参数量为5²×C,而两个3x3卷积核的参数量为2×3²×C;
该图在此基础上,作者进一步提出分别使用一个nx1卷积层和一个1xn卷积层,以取代nxn的卷积层,从而得出了我们最终的Inception v3的结构。

4.3 补充
在整体架构方面,作者还提出了减小特征层大小、增加深度(通道数)的策略:

4.4 实验结果

可以看到相比于Inception v2的4.9%,Inception v3的 Top-5 Error 已经下降到了3.58%。
4.5 代码实现
import tensorflow as tf
slim = tf.contrib.slim
def Incvption_v1_net(inputs, scope):
with tf.variable_scope(scope):
with slim.arg_scope([slim.conv2d],
activation_fn=tf.nn.relu, padding='SAME',
weights_regularizer=slim.l2_regularizer(5e-3)):
net = slim.max_pool2d(
inputs, [3, 3], strides=2, padding='SAME', scope='max_pool')
net_a = slim.conv2d(net, 64, [1, 1], scope='conv2d_a_1x1')
net_b = slim.conv2d(net, 96, [1, 1], scope='conv2d_b_1x1')
net_b_1 = slim.conv2d(net_b, 128, [1, 3], scope='conv2d_b_1x3')
net_b_2 = slim.conv2d(net_b, 128, [3, 1], scope='conv2d_b_3x1')
net_c = slim.conv2d(net, 16, [1, 1], scope='conv2d_c_1x1')
net_c = slim.conv2d(net_c, 32, [3, 3], scope='conv2d_c_3x3')
net_c_1 = slim.conv2d(net_c, 32, [1, 3], scope='conv2d_c_1x3')
net_c_2 = slim.conv2d(net_c, 32, [3, 1], scope='conv2d_c_3x1')
net_d = slim.max_pool2d(
net, [3, 3], strides=1, scope='pool3x3', padding='SAME')
net_d = slim.conv2d(
net_d, 32, [1, 1], scope='conv2d_d_1x1')
net = tf.concat(
[net_a, net_b_1, net_b_2, net_c_1, net_c_2, net_d], axis=-1)
net = tf.layers.batch_normalization(net, name='BN')
return net
代码解读
5. Inception v4
5.1 论文地址
https://arxiv.org/pdf/1602.07261.pdf
5.2 网络结构
作者在ResNet残差机制的基础上,利用Inception v3框架开发了Inception-resnet-v1和Inception-resnet-v2两种改进型网络结构。同时对Inception v3进行了优化,并在此基础上提出了Inception v4的结构。
5.2.1 Inception-resnet-v1

从下到上依次为:
(1)input:输入图像数据;
(2)stem:前馈型网络结构;
(3)采用5个Inception-resnet-A模块;
(4)经过Reduction-A模块处理;
(5)采用10个Inception-resnet-B模块;
(6)经过Reduction-B模块处理;
(7)采用5个Inception-resnet-C模块;
(8)执行平均池化层操作;
(9)应用Dropout层技术;
(10)使用Softmax激活函数;
其中,reduction用于缩小特征层;
5.2.1.1 stem前馈网络

5.2.1.2 Inception-resnet-A结构

5.2.1.3 Inception-resnet-B结构

5.2.1.4 Inception-resnet-C结构

5.2.1.5 Reduction-A/B结构

5.2.2 Inception-resnet-v2

5.2.2.1 stem前馈网络

5.2.2.2 Inception-resnet-A结构

5.2.2.3 Inception-resnet-B结构

5.2.2.4 Inception-resnet-C结构

5.2.2.5 Reduction-A/B结构

5.2.3 Inception v4

5.2.3.1 stem前馈网络
(与Inception-resnet-v2相同)

5.2.3.2 Inception-A结构

5.2.3.3 Inception-B结构

5.2.3.4 Inception-C结构

5.2.3.5 Reduction-A结构

5.2.3.6 Reduction-B结构

5.3 核心思想

该研究者在此基础上借鉴了ResNet的核心思想。为了便于优化,该研究者将原函数H(x)重新表述为F(x)+x的形式。虽然两者的函数表达式等价,但在反向传播过程中,x项的导数始终保持为1,从而有效规避了梯度消失的问题。
5.4 性能比较
- 相较于Inception v3,Inception-resnet-v1采用了残差结构,表现出更快的训练速度,其测试准确率显著高于Inception v3;
- Inception-resnet-v2的训练速度和准确率均显著高于Inception v4。
5.5 试验结果

可以看到这时Top-5 Error已经下降到了3.1%。
6. 总结
AlexNet、VGG等模型通过增加网络深度(即层数)来提升训练效果,但这种策略也带来了负面问题,如过拟合、梯度消失和梯度爆炸等。Inception方法则从计算资源利用效率和特征提取能力两个维度进行优化,在相同计算量下能够提取更多的特征,从而显著提升模型性能。
7. 本期即将结束,感谢各位大牛的支持与鼓励,期待您的点赞关注!
Ps:下一期更新一下ResNet系列,我们下期再见
