纸上得来终觉浅,绝知此事要躬行。
网上分析 resnet 的帖子和博客有很多,但是我还是建议大家去看一下论文的原文,一定会有不一样的收获。
按照原文的意思,将underlying mapping H(x) , 表示为 F(x ) + x 的这种形式;
但是使用加法的前提就是 F(x) 和 x 的 dimension 要是相同的,如果没有下采样层存在的话,我们单单使用卷积操作,
是可以控制 padding的方式来达到 dimension 相同的效果的。
但是一个神经网络不能没有下采样层的存在, 所以要想办法解决dimension的问题。
文章中给出了两种方案,一种是 ‘ 补0 ’, 也就是维度减少后,简单的补充0进去,以达到dimension相同的目的。
另一种方案就是使用 projection shortcut 的方法,具体的方法大家可以自行翻看论文的原文,我认为这是非常有必要的,虽然会需要一点时间,但是这确实是值得的。
所以,残差网络在搭建的时候要考虑两种形式的 shortcut ,一种是 identity shortcut 另一种是projection shortcut。
下面我们就这两种形式来分开说;
首先是 identity shortcut
这是两种 identity mapping 的结构图, 左图为普通结构,右图为bottle neck结构
任意一种结构的左侧的直线结构是神经网络的主路 ; 右侧的曲线称为 ‘ shortcut ’, 它允许梯度直接反向传播到更浅的层。
通过这些残差块堆叠在一起,可以形成一个非常深的网络。
并且这种方式使得每一个残差块能够很容易学习到恒等映射(identity mapping),这意味着我们可以添加很多的残差块而不会损害训练集的表现 (因为如果出现精度下降,就会做恒等映射,保持和之前的精度相同)。
其实在每个残差模块内部不仅仅只是有conv 操作,还配有相应的BN 与 ReLU激活,
具体的情况可以参照下面的这张图;
对于主路径:
主路径的第一部分:
第一个CONV2D有F1个过滤器,其大小为(1,1),步长为(1,1),使用填充方式为“valid”,
命名规则为conv_name_base + '2a',使用00作为随机种子为其初始化。
第一个BatchNorm是通道的轴归一化,其命名规则为bn_name_base + '2a'。
接着使用ReLU激活函数,它没有命名也没有超参数。
主路径的第二部分:
第二个CONV2D有F2个过滤器,其大小为(f,f),步长为(1,1),使用填充方式为“same”,命名规则为conv_name_base + '2b',使用00作为随机种子为其初始化。
第二个BatchNorm是通道的轴归一化,其命名规则为bn_name_base + '2b'。
接着使用ReLU激活函数,它没有命名也没有超参数。
主路径的第三部分:
第三个CONV2D有F3个过滤器,其大小为(1,1),步长为(1,1),使用填充方式为“valid”,命名规则为conv_name_base + '2c',使用00作为随机种子为其初始化。
第三个BatchNorm是通道的轴归一化,其命名规则为bn_name_base + '2c'。
注意这里没有ReLU函数
# 注, 这里的filter 的 size 为 &#