深度神经网络因其能够高效学习复杂函数而受到青睐。然而,在训练过程中,随着网络深度的增加,模型性能却出现了下降,这种现象被称为退化问题。本文将探讨跳跃连接如何帮助解决深度学习中的一些复杂问题。
深度神经网络的魅力在于它们能够比浅层网络更有效地学习复杂函数。但在训练深度神经网络时,随着架构深度的增加,模型性能却出现了下降,这被称为退化问题。让尝试理解退化问题背后的原因。
一个可能的原因是过拟合。随着深度的增加,模型倾向于过拟合,但这里并非如此。从下面的图表中可以看出,具有56层的深层网络比具有20层的浅层网络具有更多的训练误差。显然,过拟合并不是这里的问题。
另一个可能的原因是梯度消失或梯度爆炸问题。然而,ResNet的(He等人)认为,通过归一化确保权重的健康范数,使用批量归一化和适当的权重初始化可以解决这些问题。那么,问题出在哪里呢?让通过构造来理解这个问题。
考虑一个在数据集上训练的浅层神经网络。同时考虑一个更深的网络,其中初始层具有与浅层网络相同的权重矩阵(下图中的蓝色层),并添加了一些额外的层(绿色层)。将添加层的权重矩阵设置为单位矩阵(恒等映射)。从这种构造来看,深层网络不应该比浅层网络产生更高的训练误差,因为实际上是在深层网络中使用浅层模型的权重,并添加了恒等层。但实验证明,深层网络与浅层网络相比产生了更高的训练误差。这表明深层层无法学习即使是恒等映射。
训练精度的下降表明,并非所有系统都同样容易优化。一个主要原因是权重的随机初始化,其均值约为零,以及L1和L2正则化。因此,模型中的权重将始终接近零,因此深层层无法很好地学习恒等映射。
这就是跳跃连接的概念,它将使能够训练非常深的神经网络。让现在学习这个了不起的概念。
跳跃连接(或简称捷径连接)顾名思义,跳过神经网络中的一些层,并将一个层的输出作为下一个层的输入。跳跃连接被引入以解决不同架构中的不同问题。在ResNets的情况下,跳跃连接解决了之前讨论的退化问题;而在DenseNets的情况下,它确保了特征的可重用性。将在以下部分详细讨论它们。
跳跃连接在文献中早在残差网络之前就已经被引入。例如,高速公路网络(Srivastava等人)具有跳跃连接和控制并学习信息流向更深层的门控机制。这个概念与LSTM中的门控机制相似。尽管ResNets实际上是高速公路网络的一个特例,但与ResNets相比,其性能并不尽如人意。这表明,保持梯度高速公路畅通比选择任何门控更好——简单性在这里获胜!
神经网络可以学习任意复杂度的任何函数,这些函数可能是高维和非凸的。可视化有助于回答关于神经网络为何有效的几个重要问题。实际上,Li等人已经完成了一些出色的工作,使能够可视化复杂的损失曲面。具有跳跃连接的网络的结果更加令人惊讶!让看看它们。
具有和不具有跳跃连接的ResNet-56的损失曲面。如所见,具有跳跃连接的神经网络的损失曲面更平滑,因此比没有任何跳跃连接的网络更快地收敛。让在下一部分看看跳跃连接的变体。
在本节中,将看到不同架构中跳跃连接的变体。跳跃连接可以在神经网络中以两种基本方式使用:加法和连接。
残差网络(ResNets):残差网络由He等人在2015年提出,以解决图像分类问题。在ResNets中,通过矩阵加法将来自初始层的信息传递到更深层。此操作没有任何额外的参数,因为前一层的输出被添加到后续层。具有跳跃连接的单个残差块如下所示:
# 残差块的代码实现
由于ResNets的深层层表示,该网络的预训练权重可以用于解决多种任务。它不仅仅限于图像分类,还可以解决图像分割、关键点检测和目标检测等一系列问题。因此,ResNet是深度学习社区最有影响力的架构之一。
接下来,将了解DenseNets中跳跃连接的另一个变体,它受到ResNets的启发。
密集连接卷积网络(DenseNets):DenseNets由Huang等人在2017年提出。ResNets和DenseNets之间的主要区别在于DenseNets将层的输出特征图与下一层连接,而不是求和。
# 密集连接网络的代码实现
连接的背后思想是在使用更深层的同时,也使用从早期层学到的特征。这个概念被称为特征可重用性。因此,DenseNets可以学习比传统CNN更少参数的映射,因为不需要学习冗余的映射。
U-Net:用于生物医学图像分割的卷积网络:跳跃连接的使用也影响了生物医学领域。U-Nets由Ronneberger等人提出,用于生物医学图像分割。它有一个编码器-解码器部分,包括跳跃连接。
# U-Net的代码实现
整体架构看起来像英文字母“U”,因此得名U-Nets。编码器部分的层通过跳跃连接并与解码器部分的层(上图中提到的灰色线)连接。这使得U-Nets使用编码器部分学到的细粒度细节来构建解码器部分的图像。
这些连接是长跳跃连接,而在ResNets中看到的是短跳跃连接。更多关于U-Nets的信息可以在这里找到。
在本节中,将从零开始构建ResNets和DenseNets,并使用跳跃连接。兴奋吗?让开始吧!
残差网络- 残差块:首先,将使用跳跃连接实现一个残差块。由于其面向对象的结构,首选PyTorch。
# 实现残差块的代码
现在有了残差块,可以构建任意深度的ResNet模型!让快速构建ResNet-34的前五层,以了解如何连接残差块。
# 构建ResNet模型的代码
PyTorch为提供了一个简单的方法来加载在ImageNet数据集上训练的预训练权重的ResNet模型。
# 加载预训练ResNet模型的代码
# 实现DenseNet层的代码
# 构建密集块的代码
# 构建DenseNet模型的代码