当我们试图搭建一个非常深的神经网络时,会发现一个让人抓狂的问题:训练误差反而越来越高!这就像是你越往上爬,越发现路越来越陡,步子不稳,最后还可能摔下来。理论上,更深的网络应该能学习到更复杂、更抽象的特征,但实际上,由于梯度在反向传播过程中不断变小(或者反而爆炸),网络很难学习到有效的信息,导致模型表现反而比浅层网络还差。
想象一下,假如我们希望网络能够直接从输入到输出做一个完美的转换,但其实这转换过程如果本身就是个“恒等映射”(也就是原样输出),我们为什么还要让几十层复杂的神经元去逼近这个简单的函数呢?难道这还不累吗?
ResNet 的灵感正是来源于上面的疑问:如果一个简单的恒等映射已经足够好,为什么不直接告诉网络“嘿,就这么简单,把你要学习的东西当作和恒等映射之间的差值(残差)来学习”?也就是说,我们把原本要直接学习的映射 H(x) 转换为 F(x)+x,其中 F(x)=H(x)−x。这样一来,即便最优解就是恒等映射,网络只需要把 F(x) 学习成零就可以了。
这就像你在做数学题时,直接计算出答案与参考答案的差值,而不是从零开始一遍遍地推导,难道不是更轻松吗?
那么如何实现这种“残差学习”呢?答案就是使用“快捷连接”!在每个需要学习残差的地方,我们在输入与经过几层非线性变换后的输出之间直接相加。这种直接相加的“捷径”不仅不需要额外的参数,还能保证信息能够直接传递到更深的层次,避免梯度在层层传递时被“耗尽”。
快捷连接就像是在一条崎岖不平的山路上铺设了一条直达山顶的高速公路,既保证了信息的畅通,又大大加快了训练速度。
在 ResNet 中,核心构件就是残差块(Residual Block)。一个简单的残差块通常包含两个卷积层,每个卷积层后面跟一个激活函数(ReLU)。具体来说,假设输入为 x,经过两层卷积后得到 F(x),然后我们将 F(x) 与原始输入 x 相加,最终的输出就是 y = F(x) + x。
这种设计的妙处在于,如果两层卷积什么都不做(即 F(x)=0),网络也能直接传递 x,不会因为加了过多的非线性操作而导致训练困难。
在残差块中,我们假设输入和输出的维度相同时,直接采用身份映射(即直接把 x 加到 F(x) 上)。但如果输入和输出的维度不同(比如通道数发生变化),我们就需要一个“投影映射”来调整维度。投影映射通常通过 1×1 的卷积来实现,它既能调整通道数,也能在一定程度上保持信息的连续性。
简单来说,身份映射就像你穿着同款衣服走路,直接传递信息;而投影映射则像是换装后,通过换装让信息依然无缝对接。
ResNet 有多个不同的版本,如 ResNet-18、ResNet-34、ResNet-50、ResNet-101、ResNet-152 等。不同版本主要在于层数的不同,而设计原则都是相同的:利用残差块让网络可以非常深,同时保持训练的稳定性和收敛速度。
其中,ResNet-50 及以上的版本采用了“瓶颈结构”。所谓瓶颈结构,就是在一个残差块中,先通过 1×1 卷积将通道数降低,然后用 3×3 卷积进行处理,最后再用 1×1 卷积恢复通道数。这样可以大幅减少参数量和计算量,同时保持网络的表达能力。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。