深度学习-神经网络backbone
主要介绍VGG, ResNet, ResNeXt, DenseNet, SENet这四种网络
VGG
该论文主要论证了网络深度对图片识别任务精度的影响。VGG网络的主要贡献在于提出用连续的3X3的conv代替5X5以及7X7等更加大的filters,进而提升网络的深度。因为进行两次3X3filter得到的感受野等于进行一次5x5filter,而且参数量也减少了, 两个3X3的filter参数量是2x3x3=18, 一个5x5的filter参数量是25(VGG是在15年的时候提出的,那个时候22层都称得上是very deep了)
官方给出的可用模型如下
可视化结果为
注意到VGG深度的差异就是体现在block数目的差异以及block内部conv数目的差异, 每个block内部就是n个3x3的conv,后接一个2X2的max pooling,但是其中有一个网络(table 1, configuration C),3x3后跟了一个1x1的conv,目的是做线性变换
ResNet
随着越来越多的研究发现网络模型深度对计算机视觉任务的影响,该论文作者提出了一个问题:简单的加深网络是不是就能学到更好的模型? 首先我们要知道深度神经网络在训练过程中会遇到两个难题:
1)模型的加深会带来梯度消失或者爆炸,进而影响网络的收敛速度。该问题很大程度上可以通过归一化初始值或者中间层批归一化解决。利用批归一化可以使得深层网络利用SGD和反向传播进行收敛,
2)随着深度增加,精度逐渐饱和然后快速下降。
退化并不是由过拟合造成的,在一个稳定的深度模型上添加更多的层会带来更高的训练误差。
第二点并不符合常理,假设我们有一个浅层的网络,想要在此基础上构建深层网络。一种方法就是直接在浅层网络上添加恒等映射层。这种构建方式表明的深层网络产生的训练的误差不应该大于浅层网络的训练误差,也就是说深层网络不应该比浅层网络差。但是作者将手头的其他深层网络与简单添加恒等映射的网络进行实验比较,发现其他的深层网络的结果并没有直接添加恒等映射的效果好。因此,一个合理的猜测就是,对神经网络来说,恒等映射并不容易拟合。
基于这一点作者提出了深度残差网络。对于不断堆叠的神经层与其让他们去拟合我们想要的映射,不如让这些神经层去拟合残差映射。具体来说,记我们待求的映射为,让我们的网络去拟合残差, 原始的映射被重写成。这样做的原因是基于假设:求残差映射比求原始映射要简单。 表达式可通过前馈网络加跳跃连接实现(注意这里的+号是对应位置的元素相加)。
因此ResNet的贡献主要在于提出了残差网络解决了深度网络的退化问题,该网络能够加深网络的同时保持一个较低计算量。residual block具体结构如下
我们将上图以公式化的形式表达为。 这里的x和y是某一具体层的输入输出,表示要学习的残差映射。 上图中有两层那么, 表示RELU激活函数。和的维度必须保持一致,如果输入输出的维度不一样的话,我们可以用一个简单的线性映射增加x的维度,使两者保持一致。 实际上论文里提出了三种方式,1)直接填充0来增加维度;2)利用线性映射增加额外的维度,其他维度仍然用恒等映射得到;3)所有维度都是通过线性映射得到。实验结果显示3优于2优于1,但差别非常小,也就是说线性映射并不影响最后的效果,因此为了减少内存和时间复杂度,控制模型大小,作者在论文中没有使用第三种方法。
此外作者还提出了residual bottleneck,见下图右边的网络结构。对于残差方程,作者这次在里边堆叠了三个卷积层 1X1,3x3, 1X1。其中1X1使用来减少和恢复通道数目的,这样经过3X3卷积层的输入输出的维度就更少
ResNeXt
论文对模型的网络结构进行分析,为了提升模型性能,目前主要有两个改进方向:
1)像VGG, ResNet,通过不断堆叠相同的模块构建深度网络来提升模型性能;
2)像Inception,仔细的设计了网络拓扑结构来获得好的精确度。
Inception中一个非常重要的性质是split-transforme-merge。在inception module中,用1X1的卷积将输入分成若干低纬度嵌入,由3X3,5X5等等的特定滤波进行变换(transform),最后将结果concat起来,但是inception的问题在于他的模块都是针对数据集做过经过精心设计,可迁移性不强。该论文提出的结构既采用了VGG的堆叠神经层的方法,又设计了一种简易的split-transforme-merge,从而在和ResNet近似同等参数量的情况下,且比Inception更好的迁移性的条件下,实现了更好的acc。下图右边就是ResNeXt
从上图中可以一窥ResNet和ResNeXt的区别,对于一个ResNet block而言实际上有两个分支,一个是非线性分支,一个是恒等映射分支。对于ResNeXt block而言,除了一个恒等映射而言还有若干个完全相同的非线性分支,这里作者把一个分线性分支称之为transformation。ResNeXt block中累加的transformation(就是除了恒等映射的那一堆)可以表示为, C是transformation的数目,论文里称之为基数(cardinality)。整个block的公式表示为。
作者展示了三种效果相同的ResNeXt block
对于一个标准的ResNet bottleneck block,参数量为256 · 64 + 3 · 3 · 64 · 64 + 64 · 256 ≈ 70k(这里是1 1 conv 的参数 加上 3 3 conv的参数加上 1 1 conv的参数), 而对于ResNeXt blcok, 假设宽度为d,一个block有C个transormation, 他的参数量为C · (256 · d + 3 · 3 · d · d + d · 256), 当C为32, d为4的时候,上式约等于70K。下表解释了cardinality和width的关系
关于基数和宽度的消融实验结果:从下边的表格可以看出随着C的增加,error在不断减小
增加基数 vs 更深,更宽
从结果可以看出,增加基数比增加深度或者宽度能带来更好的效果
DensNet
随着CNN网络深度的增加,一个新的研究问题出现了:通过的层数越多,输入图片的信息和梯度信息会逐渐消失。目前常见的解决办法就是在网络中添加shortcut。本篇论文就是将这个方法提炼成一种简单的连接模式:将所有层(有相同尺寸的特征图)相互连接。为了保持前馈神经网络的特质,每一层都会额外获得前边所有层的输出,而每一层的输出又将作为其后所有层的输入. 这种特征重用充分利用了网络的每一层输出,有利于网络的训练和以及提高对参数利用率。具体结构如下图, 需要注意的是,在Resnet中特征是通过element-wise相加后再输入下一层, 而在densenet中则是直接将这些feature 沿着通道维度拼接(concat)在一起,对于每一层而言,它的输入是由前边所有层的输出拼接到一起的,这样输入数据的多样性增加了
优点:1)参数量小2)提高了梯度和信息在网络中的流通,是训练更加容易,每一层都能直接从损失函数里获取梯度和原始输入信号,这有助于训练更深层网络 30)稠密链接起到了正则化的效果, 避免是小型训练数据上过拟合
下面详细介绍一下DenseNet的一些特征
-
先复习一下ResNet, 传统的卷积前向网络将层的输出作为 层的输入,因此得到转移方程。 ResNet添加了一个skip-connection,通过一个恒等映射绕过了非线性变换,其优势在于梯度可以通过恒等映射直接从后边的层传递到前边的层,但是恒等映射和的输出是以element-wise方式相加后再输入下一层,这可能会损害网络中的信息流。
-
稠密连接:为了进一步提高层与层之间的信息流,论文提出将每一层与其后的所有层直接相连,如上DenseNet的结构图所示, 因此对于他的输入是他之前所有层的输出的特征图$x_0,...,x_{l-1} x_l = H_l()[x_0, x_1...,x_{l-1}]$。 指的是将第0 层到第l-1层输出的output沿着通道维度拼接在一起
-
组合函数:论文将定义为三个连续操作的复合函数,他们分别是:批归一化(BN), ReLU, 3x3的卷积
-
池化层:当特征图的尺寸变化时不能直接应用前述特征拼接操作,论文中给出的解决方法是首先将网络分成若干稠密连接的dense blocks, 如下图, 每个block之间的层作为transition layer(转换层)用于进行卷积和池化,可以改变特征图的大小。论文中用到的transition layer包括一个BN层,一个1x1的卷积层和2x2的平均池化层
-
增长率:如果每个产生k个特征图,那对于第层,它的输入将会包含个特征图, 是输入数据的通道数。DenseNet与其他模型不同的一点在于,DenseNet非常窄,也就是说每层输出的通道数少, 例如k=12, 论文中将k成为增长率,且实验证明一个相对小的增长率就可以在测试集上获得足够好的效果。关于增长率论文中也提出了另一种理解的角度:在一个block中每一层都可以获得他前边所有层输出的特征图。我们可以把特征图看做网络的全局状态,每层都拿出k个特征添加到这个全局状态中,这个增长率确定了每层可以向全局状态贡献多少信息。一旦被写入全局状态就可以被其后网络中的任何一层访问到。
-
Bottleneck layer:每一层虽然只输出k个特征 ,但可能接收非常多个输入,常见的做法是添加一个1x1的卷积用来减少特征图的数量提高计算效率,具体来说先用1x1 卷积减少通道数量,然后用3x3卷积提取特征,最后再用1x1的卷积恢复通道数目
-
压缩:为了使模型变得更加精悍我们可以在transition layer 中进一步减少特征数目。具体来说如果一个dense block 产生m个特征图,那么接在其后的transition layer产生个特征图, 其中称为压缩因子。如果 则通过transition layer 的特征图数目保持不变
和ResNet的比较
从中间的图中可以看出,在相同参数量的情况下,DenseNet的test error更低,在同样test error的情况下,DenseNet所需参数量更少。
SENet
为了学到更好的表征目前常见的方法包括
1):加深网络;
2):(自动化)设计更好的网络拓扑结构;
3):在网络中添加注意力方法。
本篇论文所提出的方法是对卷积特征通道间的相互依赖进行建模,对特征进行校准。具体来说就是利用已经掌握的全局信息对重要的特征添加更过关注,减少对不重要特征的关注
模型的结构如下。跟定一个变换函数, 将输入映射到,其中 . 首先对特征进行squeeze操作,沿着空间维度(H W)聚合特征图生成通道描述子,得到channel的全局分布, 之后通多Exctiation得到每个通道的权重。通道权重作用到上得到SE block的输出, 这个输入会直接输入到后续网络中。
,
SE Block
首先利用变换方程, 将输入映射到,其中 . 在神经网络中就是卷积算子, 是学习到的滤波核,指的是第c个滤波的参数, 对于而言 。 是卷积操作 , .因为上述操作中存在加法操作,会导致channel之间的依赖与卷积核的局部空间特征纠缠在一起, 为了解决这个问题直接学到通道间的依赖关系,论文提出了使用squeeze和excitation
-
squeeze:获取全局信息
由于卷积操作应用于局部感受野,因此中的每一个像素点无法有效利用除了自身区域以外的信息。为了获取全局信息,论文使用全局平均池化将全局空间信息压缩成一个通道描述子, 具体操作如下其中是中的第c个特征图,是第c个特征图的描述子
-
Excitation:
Squeeze为每个通道描述子获取到全局信息后, Excitation就是要利用这些信息捕获通道间的依赖关系。要实现这一点,所用的函数必须满足以下两点:1.灵活,要能捕获通道间的非线性关系; 2.要能学到通道间非互斥的关系。可学到多个通道的特征,而非one-hot形式。该论文采用带有sigmoid函数的gating 机制,具体操作如下是sigmoid激活函数, 是ReLU函数, , 。
出于对模型复杂度和模型泛化能力的考虑,这里的gating 机制采用两个全连接层构成bottleneck结构。第一个FC对维度进行压缩,然后经过ReLU,第二个FC对维度进行恢复。最后将学习到的各个通道的与对应位置的相乘
-
应用
SE block可以灵活的应用到诸如VGG,或者ResNet中,如下给出了将SE嵌入到Inception(左),ResNet(右)中的形式。 对于图左而言,就是整个inception模块, 对于图右,就是非恒等映射的分支
当然还可以将SE block整合到其他模型结构中,比如ResNeXt,论文中也给出了相关的模型结构结构,见下表
SE模块引入的额外参数,主要来自于两个FC层,具体的增长量为r是降维系数, S指的是stage的数目(一个stage包含若干block), 是输出通道的数目, 是一个stage中block的数目。以ResNet为例,SE-ResNet-50比ResNet-50(25 million)多了2.5million的参数。下图展示了不同模型的复杂度和在ImageNet 验证集上的表现
Reference
1. VERY DEEP CONVOLUTIONAL NETWORKS FOR LARGE-SCALE IMAGE RECOGNITION
2. Deep Residual Learning for Image Recognition
3. Aggregated Residual Transformations for Deep Neural Networks
4. Densely Connected Convolutional Networks
5. Squeeze-and-Excitation Networks
6. https://zhuanlan.zhihu.com/p/65459972
7. https://zhuanlan.zhihu.com/p/80226180
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· 百万级群聊的设计实践
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
· 永远不要相信用户的输入:从 SQL 注入攻防看输入验证的重要性