目录
GoogLeNet的22层网路已经接近当时探索的网络深度的极限了。知道残差网络的出现,使得1000层的网络构建已经不再是梦想;
1,CNN演化
先引入一张CNN结构演化图:
2012年AlexNet做出历史突破以来,直到GoogLeNet出来之前,主流的网络结构突破大致是网络更深(层数),网络更宽(神经元数)。所以大家调侃深度学习为“深度调参”,但是纯粹的增大网络的缺点:
参数太多,容易过拟合,若训练数据集有限;
网络越大计算复杂度越大,难以应用;
网络越深,梯度越往后穿越容易消失(梯度弥散),难以优化模型
1)什么是梯度消失和爆炸问题
梯度消失
我们发现很深的网络层,由于参数初始化一般更靠近0,这样在训练的过程中更新浅层网络的参数时,很容易随着网络的深入而导致梯度消失,浅层的参数无法更新。
可以看到,假设现在需要更新b1,w2,w3,w4参数因为随机初始化偏向于0,通过链式求导我们会发现,w1w2w3相乘会得到更加接近于0的数,那么所求的这个b1的梯度就接近于0,也就产生了梯度消失的现象。
梯度爆炸
在这里再举一个例子
注:这里的反向传播假设输出端接受之前回传的梯度为1(也可以是输出对输出求导=1)
观察上述反向传播,不难发现,在输出端梯度的模值,经过回传扩大了3~4倍。
这是由于反向传播结果的数值大小不止取决于求导的式子,很大程度上也取决于输入的模值。当计算图每次输入的模值都大于1,那么经过很多层回传,梯度将不可避免地呈几何倍数增长(每次都变成3~4倍,重复上万次,想象一下310000有多大……),直到Nan。这就是梯度爆炸现象。
2)什么是网络退化问题
举个例子,假设已经有了一个最优化的网络结构,是18层。当我们设计网络结构的时候,我们并不知道具体多少层次的网络时最优化的网络结构,假设设计了34层网络结构。那么多出来的16层其实是冗余的,我们希望训练网络的过程中,模型能够自己训练这16层为恒等映射,也就是经过这层时的输入与输出完全一样。但是往往模型很难将这16层恒等映射的参数学习正确,那么就一定会不比最优化的18层网络结构性能好,这就是随着网络深度增加,模型会产生退化现象。它不是由过拟合产生的,而是由冗余的网络层学习了不是恒等映射的参数造成的。
2,残差连接想法的基础
shortcut
x、y是相邻两层,通过WH连接,通过将多个这样的层前后串接起来就形成了深度网络。其中H表示网络中的变换。
为了解决深度网络的梯度发散问题,Highway在两层之间增加了(带权的)shortcut。
其中C=1-T,可以将公式更改为:
可以看出当的值等于0的时候,当值为1的时候得到的结果如图所示:
当门为1的时候,全部输出原x,不用激活。
物理意义:
1)假设所有的门t的均值为0.5的话,就是把所有的原始信息一半激活,一半不变直接输入下一层,保留了很多信息。
2)反向传播的时候,可以让更多的(梯度)信息直接回流到输入,而不需要经过一个非线性转化。
3,残差结构
ResNet 的动机是解决深度模型中的退化(即更深的网络收敛时的loss数值反而比更小的网络大,精度也不如小网络。)问题:层数越深,梯度越容易发散,误差越大,难以训练。
理论上,模型层数越深,误差应该越小才对,因为我们总可以根据浅层模型的解构造出深层模型的解(将深层模型与浅层模型对应的层赋值为浅层模型的权重,将后面的层取为恒等映射),使得这个深层模型的误差不大于浅层模型的误差。但是实际上,深度模型的误差要比浅层模型的误差要大。
ResNet最根本的动机就是所谓的“退化”问题。退化就是当模型的层次加深时,错误率却提高了,例如下图中的例子。
“退化”问题产生的原因归结于优化难题,当模型变复杂时,SGD的优化变得更加困难,导致了模型达不到好的学习效果。因此剔除了残差结构,其示意图如图所示
可以看到X是这一层残差块的输入,也称作F(x)为残差,x为输入值,F(X)是经过第一层线性变化并激活后的输出,该图表示在残差网络中,第二层进行线性变化之后激活之前,F(x)加入了这一层输入值X,然后再进行激活后输出。在第二层输出值激活前加入X,这条路径称作shortcut连接。
网络更深,一种很简单的方式就是让层与层之间进行恒等映射,可能这样学不到什么东西,但确实能加深网络的层数,那么用什么可以描述网络进行了恒等映射呢?当然就是残差的形式。我们看上图,x是输入,经过两个映射得到F(x),最终的输出是:
relu(F(x)+x)
那么如果F(x)为0,输出就是relu(x),因为x本身就经过上一层的relu了,所以输出和x相等,这样就实现了恒等映射。说明残差是可以描述网络是否进行恒等映射的。作者也设想残差映射的优化要比普通的学习映射要容易。
残差结构增加一个identity mapping(恒等映射),将原始所需要学的函数H(x)转换成F(x)+x,
而作者认为这两种表达的效果相同,但是优化的难度却并不相同,作者假设F(x)的优化 会比H(x)简单的多。
这一想法也是源于图像处理中的残差向量编码,通过一个reformulation,将一个问题分解成多个尺度直接的残差问题,能够很好的起到优化训练的效果。
作用:
这个简单的加法并不会给网络增加额外的参数和计算量,同时却可以大大增加模型的训练速度、提高训练效果
并且当模型的层数加深时,这个简单的结构能够很好的解决退化问题。因为identity map是的梯度可以直接回流到了输入层
残差结构直接将一个输入添加到函数输出时,任然可以来描述输入和输出的关系。但是这种操作可以明确的拆分为连个线性的叠加,使学习变得更加简单,同时缓解了深层网络的训练的问题,为上千层网络的训练提供了可能性;将输出表述为输入和输入的一个非线性变换的线性叠加
1)普通网络(Plain Network)
2) 残差网络
4,为什么残差连接有效
4.1 简化学习过程,增强了梯度传播解决梯度消散
相对于学习原始信号,残差连接学习的是信号的差值。在一定程度上,网络越深越宽其表达能力越好性能越好。但是随着网络的深度变深就带来了许多优化问题吗,如梯度消散,梯度爆炸。
为什么残差结果可以很好的防止梯度消散,通过以下三个例子说明
1) 通过公式推导
图中求解偏导的公式,是一个反向传播的过程。可以看到,链式求导后的结果如图所示,不管括号内右边部分的求导参数有多小,因为左边的1的存在,且右边的残差梯度不会那么巧全为-1。都能保证该节点参数更新不会发生梯度消失或梯度爆炸现象。
2)简单网络举例
再举个例子看看残差网络是如何改善梯度消失现象的:
假设输入只有一个特征,没有偏置单元,每层只有一个神经元:
我们先进行前向传播,这里将Sigmoid激励函数写为s(x):
z1 = w1*x
a1 = s(z1)
z2 = w2*a1
a2 = s(z2)
…
zn = wn*an-1 (这里n-1是下标)
an = s(zn)
根据链式求导和反向传播,我们很容易得出,其中C是代价函数
那如果在a1和a2之间加入残差连接,如下所示:
那么z2=a1*w2+a1
所以z2对a1求导的结果就是(w2+1)
上边的链式求导、反向传输的结果中的w2就变成了(w2+1)
所以残差连接可以有效缓解梯度消失的现象。
3)实际数据举例
4.2 为什么可以解决网络退化问题
要想学习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来让该层网络恒等映射上一层的输入,使得有了这些冗余层的网络效果与没有这些冗余层的网络效果相同,这样很大程度上解决了网络的退化问题
4.3 残差打破了网络的不对称性
残差连接正是强制打破了网络的对称性
第1种(图a),输入权重矩阵(灰色部分)完全退化为0,则输出W已经失去鉴别能力,此时加上残差连接(蓝色部分),网络又恢复了表达能力。第2种(图b),输入对称的权重矩阵,那输出W一样不具备这两部分的鉴别能力,添加残差连接(蓝色部分)可打破对称性。第3种(图c)是图b的变种,不再说明。
4.4 增加模型的泛化能力
使用残差网络训练完一个深层的网络,在测试的时候去除一部分网络层,并不会使得模型的性能有很大的退化,但是对VGGNet 等非残差网络,删减任何一层都会造成性能的奔溃。
以上部分内容摘自有三的《深度学习之模型设计》书中,并将几个好的博文的内容做了整合。