Going deeper with convolutions
在这篇论文中提出了一种新的深度卷积神经网络结构,命名为Inception。从名字来说,Google Inc想要引领物体分类和检测新的开端。确实,在本文中,Google Inc为神经网络提出了很多新的思路,例如引入 bottleneck network,在串行网络总引入并行操作,使得每个并行的操作都成为了一个模块,每个模块就叫做一个Inception。
Inception一种经过精心设计的结构,允许纵横增加深度和宽度的网络结构,这种体系结构的主要特点是减小了网络参数量,降低了计算资源。虽然深度达到22层,但大小却比AlexNet和VGG小很多(得益于采用1x1卷积,和使用全局均值池化代替池化层),Inception参数为500万个,AlexNet参数个数是GoogleNet的12倍,VGGNet参数又是AlexNet的3倍,因此在内存或计算资源有限时,Inception是比较好的选择;从模型结果来看,Inception的性能却更加优越。
关于名字 GoogLeNet
在ILSVRC14 competition中,Google Inc使用了GoogLeNet命令这种使用了多个Inception模块的网络,以表达对LeNet网络的敬意。
相关创新点:
-
受Serre等人使用多尺度Gabor滤波提取灵长类动物的视觉皮质不同特征区域启发,定义使用Inception model结构;分别使用1x1,3x3, 5x5卷积获得输入图像的不同信息,并行处理这些运算并结合所有结果将获得更好的图像表征。
-
参考Network-in-Network1x1的卷积使用方法,使用1x1卷积叠加在大尺度卷积核之前,以此来降低特征图维度,较少参数量;使得Inception模块在增加网络深度和宽度的同事,不会增加太大的计算负担
例如上图中第2列网网络:
1:如果不使用1x1卷积,参数量为:192x3x3x128=221184
2:如果使用1x1卷积,参数量为:(192x1x1x96) + (96x3x3x128)=129024,参数量为未使用1x1卷积的0.58倍
网络结构
inception的网络排布如下,每一组inception之前,都上接一个池化层机降低特征图尺寸。按照传统的CNN结构:输入-卷积-relu-pool,可以,每组inception是达成一组系统的卷积进行处理的。这种协同卷积结构在后续的网路中被大量采用。
inception层
每一个inception的结构如下,每层卷积的输出,与上表中的对应关系如下。如上表所示,inception的1x1的卷积主要有两个作用:提取原始特征图信息和降维,减少参数量
max pool
除了第一个卷积层会降低feature map尺寸外,其他卷积并不降低图像尺寸,只是增加图像的维度
每一个卷积层,都会将原图尺寸减小为原来的1/2,共4层max pool,加上第一层卷积层处理,整个GoogLeNet会将原图处理成 input_size/32 尺寸大小的feture map
avg pool
最后一程inception的输出为7x7x1024,后接一个全局平均池化层,对每一个7x7的feature map求池化平均值。主要还是参考NIN中的处理策略,用来代替全连接层,降低参数量
dropout
以40%的概率,舍弃神经元的激活,防止参数量过大导致的过拟合
linear
全连接层,输出分类特征值
softmax
求每个分类的概率值
输出层
GoogLeNet 有 9 个线性堆叠的 Inception 模块。它有 22 层(包括池化层的话是 27 层)。这是一个深层分类器。和所有深层网络一样,它也会遇到梯度消失问题。
为了阻止该网络中间部分梯度的「消失」过程,作者引入了两个辅助分类器(上图红色框)。它们对其中两个 Inception 模块的输出执行 softmax 操作,然后在同样的标签上计算辅助损失。总损失即辅助损失和真实损失的加权和。该论文中对每个辅助损失使用的权重值是 0.3。
# The total loss used by the inception net during training.
total_loss = real_loss + 0.3 * aux_loss_1 + 0.3 * aux_loss_2
辅助损失只是用于训练,在推断过程中并不使用。
训练
因为有两层辅助输出层,所以inceptionv1的_forward输出有三个输出值
return x, aux2, aux1
训练时,计算损失函数时,对应的也要计算三个损失值
if model_name =='inception_v1' and phase == 'train':
# From https://discuss.pytorch.org/t/how-to-optimize-inception-model-with-auxiliary-classifiers/7958
outputs, aux2, aux1 = model(inputs)
private_loss = criterion(outputs, labels)
aux_loss2 = criterion(aux2, labels)
aux_loss1 = criterion(aux1, labels)
loss = private_loss + 0.3*aux_loss2 + 0.3*aux_loss1
因为我们不是在ImageNet的1000分类数据上训练,因此需要修改网络的三个输出层结构
elif model_name == "inception_v1":
""" Inception v1
Be careful, expects (224,224) sized images and has auxiliary output
"""
model_ft = googlenet(pretrained=use_pretrained,aux_logits=True)
set_parameter_requires_grad(model_ft, feature_extract)
# Handle the first auxilary net
num_ftrs = model_ft.aux1.fc2.in_features
model_ft.aux1.fc2 = nn.Linear(num_ftrs, num_classes)
# Handle the send auxilary net
num_ftrs = model_ft.aux2.fc2.in_features
model_ft.aux2.fc2 = nn.Linear(num_ftrs, num_classes)
# Handle the primary net
num_ftrs = model_ft.fc.in_features
model_ft.fc = nn.Linear(num_ftrs,num_classes)
input_size = 224
详细代码请参考Pytorch/inceptionV1Train.py
训练结果
使用的数据为hymenoptera_data,测试结果如下
Epoch 59/59
----------
train Loss: 0.7238 Acc: 0.9262, lr: 0.0000000100
val Loss: 0.3467 Acc: 0.9412, lr: 0.0000000010
##参考文档:
https://zhuanlan.zhihu.com/p/37505777
https://juejin.cn/post/6844903767536582664