十分钟一起学会ResNet残差网络

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了十分钟一起学会ResNet残差网络相关的知识,希望对你有一定的参考价值。

参考技术A 深度卷积网络自然的整合了低中高不同层次的特征,特征的层次可以靠加深网络的层次来丰富。从而,在构建卷积网络时,网络的深度越高,可抽取的特征层次就越丰富。所以一般我们会倾向于使用更深层次的网络结构,以便取得更高层次的特征。但是在使用深层次的网络结构时我们会遇到两个问题,梯度消失,梯度爆炸问题和网络退化的问题。

但是当使用更深层的网络时,会发生梯度消失、爆炸问题,这个问题很大程度通过标准的初始化和正则化层来基本解决,这样可以确保几十层的网络能够收敛,但是随着网络层数的增加,梯度消失或者爆炸的问题仍然存在。

还有一个问题就是网络的退化,举个例子,假设已经有了一个最优化的网络结构,是18层。当我们设计网络结构的时候,我们并不知道具体多少层次的网络时最优化的网络结构,假设设计了34层网络结构。那么多出来的16层其实是冗余的,我们希望训练网络的过程中,模型能够自己训练这五层为恒等映射,也就是经过这层时的输入与输出完全一样。但是往往模型很难将这16层恒等映射的参数学习正确,那么就一定会不比最优化的18层网络结构性能好,这就是随着网络深度增加,模型会产生退化现象。它不是由过拟合产生的,而是由冗余的网络层学习了不是恒等映射的参数造成的。

ResNet是在2015年有何凯明,张翔宇,任少卿,孙剑共同提出的,ResNet使用了一个新的思想,ResNet的思想是假设我们涉及一个网络层,存在最优化的网络层次,那么往往我们设计的深层次网络是有很多网络层为冗余层的。那么我们希望这些冗余层能够完成恒等映射,保证经过该恒等层的输入和输出完全相同。具体哪些层是恒等层,这个会有网络训练的时候自己判断出来。将原网络的几层改成一个残差块,残差块的具体构造如下图所示:

可以看到X是这一层残差块的输入,也称作F(x)为残差,x为输入值,F(X)是经过第一层线性变化并激活后的输出,该图表示在残差网络中,第二层进行线性变化之后激活之前,F(x)加入了这一层输入值X,然后再进行激活后输出。在第二层输出值激活前加入X,这条路径称作shortcut连接。

我们发现,假设该层是冗余的,在引入ResNet之前,我们想让该层学习到的参数能够满足h(x)=x,即输入是x,经过该冗余层后,输出仍然为x。但是可以看见,要想学习h(x)=x恒等映射时的这层参数时比较困难的。ResNet想到避免去学习该层恒等映射的参数,使用了如上图的结构,让h(x)=F(x)+x;这里的F(x)我们称作残差项,我们发现,要想让该冗余层能够恒等映射,我们只需要学习F(x)=0。学习F(x)=0比学习h(x)=x要简单,因为一般每层网络中的参数初始化偏向于0,这样在相比于更新该网络层的参数来学习h(x)=x,该冗余层学习F(x)=0的更新参数能够更快收敛,如图所示:

假设该曾网络只经过线性变换,没有bias也没有激活函数。我们发现因为随机初始化权重一般偏向于0,那么经过该网络的输出值为[0.6 0.6],很明显会更接近与[0 0],而不是[2 1],相比与学习h(x)=x,模型要更快到学习F(x)=0。

并且ReLU能够将负数激活为0,过滤了负数的线性变化,也能够更快的使得F(x)=0。这样当网络自己决定哪些网络层为冗余层时,使用ResNet的网络很大程度上解决了学习恒等映射的问题,用学习残差F(x)=0更新该冗余层的参数来代替学习h(x)=x更新冗余层的参数。

这样当网络自行决定了哪些层为冗余层后,通过学习残差F(x)=0来让该层网络恒等映射上一层的输入,使得有了这些冗余层的网络效果与没有这些冗余层的网络效果相同,这样很大程度上解决了网络的退化问题。

我们发现很深的网络层,由于参数初始化一般更靠近0,这样在训练的过程中更新浅层网络的参数时,很容易随着网络的深入而导致梯度消失,浅层的参数无法更新。

可以看到,假设现在需要更新 参数因为随机初始化偏向于0,通过链式求导我们会发现, 相乘会得到更加接近于0的数,那么所求的这个 的梯度就接近于0,也就产生了梯度消失的现象。

ResNet最终更新某一个节点的参数时,由于 ,由于链式求导后的结果如图所示,不管括号内右边部分的求导参数有多小,因为左边的1的存在,并且将原来的链式求导中的连乘变成了连加状态(正是 ),都能保证该节点参数更新不会发生梯度消失或梯度爆炸现象。

这样ResNet在解决了阻碍更深层次网络优化问题的两个重要问题后,ResNet就能训练更深层次几百层乃至几千层的网络并取得更高的精确度了。

这里是应用了ResNet的网络图,这里如果遇到了h(x)=F(x)+x中x的维度与F(x)不同的维度时,我们需要对identity加入Ws来保持Ws*x的维度与F(x)的维度一致。

x与F(x)维度相同时:

x与F(x)维度不同时:

下边是ResNet的网络结构图:

使用1*1卷积减少参数和计算量:

如果用了更深层次的网络时,考虑到计算量,会先用1 * 1的卷积将输入的256维降到64维,然后通过1*1恢复。这样做的目的是减少参数量和计算量。

左图是ResNet34,右图是ResNet50/101/152。这一个模块称作building block,右图称之为bottleneck design。在面对50,101,152层的深层次网络,意味着有很大的计算量,因此这里使用1 * 1卷积先将输入进行降维,然后再经过3 * 3卷积后再用 卷积进行升维。使用1*1卷积的好处是大大降低参数量计算量。

通过上述的学习,你应该知道了,现如今大家普遍认为更好的网络是建立在更宽更深的网络基础上,当你需要设计一个深度网络结构时,你永远不知道最优的网络层次结构是多少层,一旦你设计的很深入了,那势必会有很多冗余层,这些冗余层一旦没有成功学习恒等变换 ,那就会影响网络的预测性能,不会比浅层的网络学习效果好从而产生退化问题。

ResNet的过人之处,是他很大程度上解决了当今深度网络头疼的网络退化问题和梯度消失问题。使用残差网络结构 代替原来的没有shortcut连接的 ,这样更新冗余层的参数时需要学习 比学习 要容易得多。而shortcut连接的结构也保证了反向传播更新参数时,很难有梯度为0的现象发生,不会导致梯度消失。

这样,ResNet的构建,使我们更朝着符合我们的直觉走下去,即越深的网络对于高级抽象特征的提取和网络性能更好,不用在担心随着网络的加深发生退化问题了。

近段时间,准备持续发表一些CNN常见的网络模型讲解。好了,今天的十分钟就带你一起学会ResNet,下次的十分钟我们再见。

残差网络 ResNet 为什么能训练出1000层的模型 动手学深度学习v2

1. 残差网络 ResNet

假设你在CNN卷积神经网络中只了解一个什么网络,那就是残差网络 ResNet。ResNet 是一个很简单,也很有用的网络。

增加更多的层总是改进精度吗?不一样,比如左边的图F6比F3,距离目标函数f*更远,所以效果是更差的。

残差块 f(x) = x + g(x)



https://cv.gluon.ai/model_zoo/classification.html

2. 代码实现







10个epoch,train acc 0.996, test acc 0.885

3. ResNet为什么能训练出1000层的模型

因为乘法会使得梯度消失或者梯度爆炸;假设都能控制成梯度消失,ResNet就是把累积乘法变成了加法,解决了梯度消失的问题。

4. Q&A

    1. 残差网络ResNet f(x) = x + g(x), 如果g(x) 对网络训练是变化的,不是减弱了这个效果么? 是的,残差网络ResNet是保证深的神经网络下,不会变差。
    1. 为什么ImageNet不能达到测试准确率100%。 因为 ImageNet中的测试集,有一些label是错的。

5. 第二部分完结竞赛:图片分类

竞赛地址:https://www.kaggle.com/c/classify-leaves





参考

https://www.bilibili.com/video/BV1bV41177ap?p=1

以上是关于十分钟一起学会ResNet残差网络的主要内容,如果未能解决你的问题,请参考以下文章

Pytorch Note31 深度残差网络 ResNet

Resnet 残差网络使用案例

残差网络

从零学习PyTorch 如何残差网络resnet作为pre-model +代码讲解+残差网络resnet是个啥

残差网络ResNet笔记

残差网络