深度学习笔记(28) 残差网络

深度学习笔记(28) 残差网络

  • 1. 残差块
  • 2. 深度网络的训练错误
  • 3. ResNets的作用
  • 4. ResNets的细节
  • 5. ResNets的结构


1. 残差块

非常深的神经网络是很难训练的,因为存在梯度消失梯度爆炸问题
这时可以用 跳跃连接(Skip connection)
从某一层网络层获取激活,然后迅速反馈给另外一层,甚至是更深层

可以利用跳跃连接构建能够训练深度网络的ResNets,有时深度能够超过100层
残差网络(ResNets)是由残差块(Residual block)构建的
在这里插入图片描述
这是一个两层神经网络,在L层进行激活,得到 a[l+1]
再次进行激活,两层之后得到 a[l+2]

计算过程是从a[l]开始,首先进行线性激活
根据这个公式:z[l+1] = W[l+1] a[l] + b[l+1] ,通过 a[l] 算出 z[l+1]
即a^([l])乘以权重矩阵,再加上偏差因子

然后通过ReLU非线性激活函数得到 a[l+1] ,a[l+1] = g( z[l+1] )计算得出
接着再次进行线性激活,依据等式 z[l+2] = W[2+1] a[l+1] + b[l+2]
最后再次进行ReLu非线性激活,即 a[l+2] =g( z[l+2] )
这里的g是指ReLU非线性函数,得到的结果就是 a[l+2]
换句话说,信息流从 a[l] 到 a[l+2] 需要经过以上所有步骤,即这组网络层的主路径

深度学习笔记(28) 残差网络_第1张图片
在残差网络中有一点变化,
将 a[l] 直接向后,拷贝到神经网络的深层,在ReLU非线性激活函数前加上a[l] ,这是一条捷径
a[l] 的信息直接到达神经网络的深层,不再沿着主路径传递
这就意味着最后这个等式 a[l+2] = g( z[l+2] )去掉了
取而代之的是另一个ReLU非线性函数
仍然对 z[l+2] 进行 g 函数处理,但这次要加上 a[l]
即:a[l+2] = g( z[l+2] + a[l] ),也就是加上的这个 a[l] 产生了一个残差块

也可以画一条捷径,直达第二层
实际上这条捷径是在进行ReLU非线性激活函数之前加上的
而这里的节点都执行了线性函数和ReLU激活函数
所以 a[l] 插入的时机是在线性激活之后,ReLU激活之前

除了捷径,还会听到另一个术语“跳跃连接”,就是指 a[l] 跳过一层或者好几层
从而将信息传递到神经网络的更深层


2. 深度网络的训练错误

如果使用标准优化算法训练一个普通网络,比如说梯度下降法,或者其它热门的优化算法
深度学习笔记(28) 残差网络_第2张图片
如果没有残差,没有这些捷径或者跳跃连接
凭经验会发现随着网络深度的加深,训练错误会先减少,然后增多

而理论上,随着网络深度的加深,应该训练得越来越好才对
也就是说,理论上网络深度越深越好

但实际上,如果没有残差网络
对于一个普通网络来说,深度越深意味着用优化算法越难训练
实际上,随着网络深度的加深,训练错误会越来越多

但有了ResNets就不一样了,即使网络再深,训练的表现却不错
比如说训练误差减少,就算是训练深达100层的网络也不例外
对 x 的激活,或者这些中间的激活能够到达网络的更深层

这种方式确实有助于解决梯度消失和梯度爆炸问题
让训练更深网络的同时,又能保证良好的性能


3. ResNets的作用

通常来讲,网络在训练集上表现好,才能在交叉验证集或dev集和测试集上有好的表现
所以至少在训练集上训练好ResNets是第一步

一个网络深度越深,它在训练集上训练的效率就会有所减弱
这也是有时候不希望加深网络的原因
而事实并非如此,至少在训练ResNets网络时,并非完全如此

假设有一个大型神经网络,其输入为X,输出激活值 a[l]
想增加神经网络的深度,那么用 Big NN 表示,输出为 a[l]
再给网络额外添加两层,依次添加两层,最后输出为 a[l+2]
可以把这两层看作一个ResNets块,即具有捷径连接的残差块为了方便说明
假设在整个网络中使用 ReLU 激活函数
所以激活值都大于等于0,包括输入X的非零异常值
因为ReLU激活函数输出的数字要么是0,要么是正数

深度学习笔记(28) 残差网络_第3张图片
看一下 a[l+2] 的值,即 a[l+2] = g( z[l+2] + a[l] ),添加项 a[l] 是刚添加的跳跃连接的输入
展开这个表达式 a[l+2] = g( W[l+2] a[l+1] + b[l+2] + a[l] ),其中 z[l+2] =W[l+2] a[l+1] +b[l+2]

注意一点,如果使用L2正则化或权重衰减,它会压缩 W[l+2] 的值
如果对 b 应用权重衰减也可达到同样的效果
尽管实际应用中,有时会对 b 应用权重衰减,有时不会

这里的 W 是关键项,如果 W[l+2] =0,为方便起见,假设 b[l+2] =0,这几项就没有了
因( W[l+2] a[l+1] + b[l+2] )= 0
最后 a[l+2] = g( a[l] ) = a[l]
因为假定使用ReLU激活函数,并且所有激活值都是非负的
g( a[l] )是应用于非负数的ReLU函数,所以 a[l+2] = a[l]

结果表明,残差块学习这个恒等式函数并不难,跳跃连接很容易得出a[l+2] =a[l]
则即使给神经网络增加了这两层,它的效率也并不逊色于更简单的神经网络
因为学习恒等函数对它来说很简单
尽管它多了两层,也只把 a[l] 的值赋值给 a[l+2]
所以给大型神经网络增加两层,不论是把残差块添加到神经网络的中间还是末端位置
都不会影响网络的表现

当然,目标不仅仅是保持网络的效率,还要提升它的效率
想象一下,如果这些隐藏层单元学到一些有用信息
那么它可能比学习恒等函数表现得更好
而这些不含有残差块或跳跃连接的深度普通网络情况就不一样了
当网络不断加深时,就算是选用学习恒等函数的参数都很困难
所以很多层最后的表现不但没有更好,反而更糟

残差网络起作用的主要原因就是这些残差块学习恒等函数非常容易
能确定网络性能不会受到影响
很多时候甚至可以提高效率
或者说至少不会降低网络的效率
因此创建类似残差网络可以提升网络性能


4. ResNets的细节

除此之外,另一个值得探讨的细节是,假设 z[l+2] 与 a[l] 具有相同维度
所以ResNets使用了许多same卷积,a[l] 的维度等于这个输出层的维度
之所以能实现跳跃连接是因为same卷积保留了维度
所以很容易得出捷径连接,并输出这两个相同维度的向量
深度学习笔记(28) 残差网络_第4张图片
如果输入和输出有不同维度,比如输入的维度是128,a[l+2] 的维度是256
再增加一个矩阵,这里标记为 Ws,是一个256×128维度的矩阵
所以Ws a[l] 的维度是256,这个新增项是256维度的向量
不需要对Ws做任何操作,它是网络通过学习得到的矩阵或参数
它是一个固定矩阵,padding值为0,其维度为256


5. ResNets的结构

深度学习笔记(28) 残差网络_第5张图片
普通网络和ResNets网络常用的结构是:
卷积层 - 卷积层 - 卷积层 - 池化层 - 卷积层 - 卷积层 - 卷积层 - 池化层 …… 依此重复
直到最后,有一个通过softmax进行预测的全连接层


参考:

《神经网络和深度学习》视频课程


相关推荐:

深度学习笔记(27) 经典卷积网络
深度学习笔记(26) 卷积神经网络
深度学习笔记(25) 池化层
深度学习笔记(24) 卷积层
深度学习笔记(23) 卷积维度


谢谢!

你可能感兴趣的:(深度学习笔记)