温馨提示:这篇文章已超过469天没有更新,请注意相关的内容是否还可用!
摘要:残差网络(Residual Network,ResNet)是一种深度神经网络结构,旨在解决深度神经网络训练过程中的梯度消失和表示瓶颈问题。其原理基于残差学习的思想,通过引入残差块,使得网络学习的是输入与输出之间的残差,而非直接的映射。这种结构有助于减轻网络深度增加时的优化难度,加快训练速度,提升性能。ResNet的结构包括多个残差块,每个残差块包含至少两个卷积层,通过跳跃连接直接将输入信息传输到深层网络,实现特征的跨层传递。
模型原理与优点
残差网络是为了解决在深度神经网络中随着层数增加出现的梯度消失或梯度爆炸问题而提出的,在传统的神经网络中,尤其是图像处理方面,卷积层、池化层等堆叠在一起,每一层都从前一层提取特征,但随着层数增加,通常会出现退化问题,残差网络通过引入跳跃连接,有效地避免了这些问题。
我们将网络层视为映射函数,在传统的前馈网络中,网络将输入x映射为F(x),整体网络的输出为H(x),其中F(x)=H(x),对于恒等映射函数f(x)=x(即网络的输入与输出相等),直接让这样的层去拟合这样的映射函数是很困难的,我们可以让输出H(x)=F(x)+x,这样如果整体网络需要是恒等映射,只需将堆叠层拟合成F(x)=0即可。
从另一角度考虑,残差网络的目的并不是学习从x到H(x)的映射,而是学习x与H(x)的差异,即“残差”F(x)=H(x)-x,我们尝试学习F(x)+x,而不是直接学习H(x)。
模型的优点在于,通过引入残差连接,使得网络更容易学习恒等映射和残差映射,从而避免梯度消失和爆炸问题,使网络能够向更深层次发展。
模型结构
ResNet的种类很多,如ResNet-18、ResNet-34、ResNet-50、ResNet-101、ResNet152等,但它们的基本结构相同,都是由多层相同的ResNet block重复堆叠而成,ResNet block由若干层网络(这里称为Layers)组成,输出为网络的输出与输入的加和。
(此处可以插入ResNet block和重复结构的图片)
这里的加是两个张量相加,我们要保证输入x与Layers后的输出形状相同,以便相加,这取决于Layers的内部结构,在图像处理中,常用的是采取卷积核为3、padding为1的两个卷积层来处理,这样可以不改变张量的形状。
ResNet block的其他结构
除了最基本的输入与输出直接相加的结构外,实际的连接方式可以是多种多样的,虽然结构有所差异,但总体思想相同,即最终都是形状相同的张量相加。
(此处可以插入其他结构的图片)
关于跳跃连接、残差连接与捷径连接的问题
这几个词在ResNet、Inception、DenseNet等网络中很常见,跳跃连接(skip connection)是指模型内两个位置的直接连接;残差连接(residual connection)是残差网络中的跳跃连接,强调这种连接在残差网络中的作用;捷径连接(shortcut connection)可以理解为绕过中间的层去和后面的输出连接,本质上也是残差连接的一种体现。
算法实现
可以直接使用torchvision库中的ResNet模型,以下是使用示例代码:
from torchvision.models.resnet import resnet18 resnet18 = resnet18() print(resnet18)
上述代码可以查看模型内部结构,并且该模型可以直接进行训练,或者作为其他网络的一部分。
下面以第二部分为例,简要实现ResNet模型的部分代码:
import torch import torch.nn as nn import torch.nn.functional as F class ResNetBlock(nn.Module): def __init__(self): super(ResNetBlock, self).__init__() self.conv1 = nn.Conv2d(kernel_size=3, in_channels=3, out_channels=3, padding=1) # 修改了in_channels和padding以适应常见的图像输入尺寸 self.conv2 = nn.Conv2d(kernel_size=3, in_channels=3, out_channels=3, padding=1) # 修改了卷积核大小和padding以适应常见的图像输入尺寸和特征提取需求 self.bn1 = nn.BatchNorm2d(4) # BatchNorm层用于加速训练和提高模型性能,但此处参数可能有误(通常指定为与卷积层输出通道数一致),需要修正为正确的参数值或根据实际情况设置,同样适用于下面的bn2。 修正后的代码将在注释中给出。 修正后的代码为self.bn1 = nn.BatchNorm2d(out_channels=卷积层的输出通道数)。 同样的修改也适用于下面的bn2定义处。 修正后的代码将在注释中给出。 修正后的代码为self.
还没有评论,来说两句吧...