图像识别综述-从Inception到ResNet
存货, 介绍了从Inception系列到Resnet系列的发展历史以及基本理念和pytorch实现
Inception系列
1x1 卷积核的出处
出自颜水成组的Network in Network(ICLR 2014)中. 传统CNN使用线性滤波器, 为了捕捉高度非线性关系, 需要堆积卷积核, 计算量太大. 本文的贡献主要是
- 提出MLP conv层, 即用多层感知机建模卷积层之间的非线性关系, 可以
- 实现跨通道的交互和信息整合.
- 进行卷积核通道数的降维和升维,减少网络参数
- 具体到实现上, 可以用1x1 卷积核来近似实现. 普通卷积层+多个1*1卷积(followed by 激活层)等价于类patch级别的MLP
- 提出用全局均值池化提到全连接层: 比如输出$k$类, 最后一层conv layer就有$k$个channel, 最后经过全局均值池化输出一个$k$维向量
- 原作把MLP conv和maxout进行比较, 并表示
maxout network imposes the prior that instances of a latent concept lie within a convex set in the input space, which does not necessarily hold
Inception v1
出自Google Brain. C Szegedy, CVPR 2015
- 整个网络由9个上图形成的block组成
- 第三个和第五个block有辅助分类器处理梯度消失问题
- 图中的1x1 conv降维不仅可以降低计算量, 还可以使得数据更加dense:
Clustering sparse matrices into relatively dense submatrices tends to give state of the art practical performance for sparse matrix multiplication
Inception v2/v3
出自Google Brain. C Szegedy, CVPR 2016.
-
论文首先提出了一些在构建深度网络时值得借鉴的意见.
- 不要过早地引入Bottleneck. 并且Bottleneck之间过多地减少维度可能会造成信息的损失. 当卷积不会大幅度改变输入维度时,神经网络可能会执行地更好
- Higher dimensional representations are easier to process locally within a network. 没太理解. 似乎是说特征维度越高, 越容易训练
- 在卷积之前提前降维信息损失会很低. 这可能是因为相邻层之间有较大的协方差(strong correlation between adjacent unit), 所以可以先降维来降低运算量, 训练速度也会提升, 这就是Bottleneck概念的来源
- 平衡网络的深度和宽度
-
提出了分解大卷积核为小卷积核的想法(Factorizing Convolutions with Large Filter Size).
- 感受野相同的情况下, 将 5×5 的卷积分解为两个 3×3 的卷积, 降低了2.78倍运算量
- 将 n*n 的卷积核尺寸分解为 1×n 和 n×1 两个卷积
-
提出Bottleneck概念, 先降维再升维. 这个概念取自于自编码器? 例如:
- 输入输出皆为256 channel的卷积层, 由3x3x256个卷积核组成
- 转换成一组1x1x64, 3x3x64, 1x1x256维的卷积层, 计算量降低了接近10倍
最后提出了Label Smoothing来对网络输出正则化, 也是率先使用了batch norm的网络之一 v3是同一篇论文提出的, 增加了RMSProp优化器, Factorized 7x7 卷积, 辅助分类器使用了 BatchNorm
Inception v4
使用了更多骨骼惊奇的building block, 并且结合了resnet的跳跃式结构.
Xception
Xception: Deep Learning with Depthwise Separable Convolutions 某层卷积层输入channel为$16$, 输出channel为$32$
- 使用32个$k \times k \times 16$的卷积核, 参数数量为: $$32 \times k \times k \times 16$$
- 使用$16$个$k \times k \times 1$的卷积核分别在$16$个channel上独自进行卷积, 输出为$16$个channel, 再用$32$个$1 \times 1 \times 16$的一维卷积核, 输出为$32$个channel, 参数数量为: $$16 \times k \times k \times 1 + 32 \times 1 \times 1 \times 16$$
由此可见参数量被大大减小. 在实现上, Depthwise Conv
等价于一个$k \times k \times 16$的卷积核在尚未sum各个channel的值之前就输出成16个channel, 然后再接$32$个Pointwise Conv
, 即$1 \times 1$卷积核
注: Depthwise Conv
在pytorch中可以用groups
参数实现:
|
|
ResNet
resnet由四个stage
组成, 而每个stage
又由数个bottleneck
组成.
bottleneck
结构借鉴了Inception v2
一个Bottleneck由3层CBR(conv-batch norm-relu)层组成, 见下:
同时一个stage
由若干重复bottleneck
组成, 整个网络由4个stage
组成
- 每个
stage
的开头第一个bottleneck
的3x3卷积层的步长是2, 使得每个stage
将feature map尺寸缩小一半 - 每个
stage
的开头第一个bottleneck
需要处理上一个stage
的输出通过shortcut与该bottleneck
的输出相加时通道不匹配的问题, 故需要增加一层Conv-BN处理通道一致性
构造Bottleneck
:
|
|
构造第一层conv1
|
|
构造四个stage
|
|
几个小问题
1大量使用BatchNorm. BN应该在激活函数之前还是之后呢? - https://zhuanlan.zhihu.com/p/28124810 - https://www.zhihu.com/question/64494691 - https://zhuanlan.zhihu.com/p/28749411 2. 为什么resnet? - https://www.zhihu.com/question/64494691
ResNeXt
核心思路是在Bottleneck
中:
- 利用1x1卷积核, 先降维再升维的方式降低计算开销(下图c)
- 在降维过程中, 利用Xception的
Depthwise Conv
进一步降低计算开销(下图b)- 将输入的128通道分成32组, 每组4个通道
- 对每组使用4个核为3x3的卷积层, 输出4个通道
- 将32个卷积层的4x32=128个通道concat为128个输出层
与ResNet的比较:
构造Bottleneck
, 和resnet相比改动很简单, 参考上图最右边的实现, 在每个stage的第二个卷积层启用group
参数即可.
SENet
大体思路是对各个channel(或者说整张图片)的一个attention, 个人理解就是结合了文章开头NIN的理念和Attention机制
- 通过全局均值池化将$C$个channel变成$C$维向量.
- 第一个FC层称为squeeze层, 将维度压缩为$reduction$, 使用ReLU, 起到LSTM中门控的作用
- 第二个FC层称为excitation层, 将维度还原为$C$, 使用Sigmoid, 起到输出权重作用, 重新赋予每个channel权重. 核心思想是建模通道间的相关性
- 最后输出的向量作为各层的权重乘到输出上
|
|
带SEScale的ResNext:
|
|