ResNet(残差神经网络)

ResNetResidual Networks,残差网络)是由 Microsoft Research 提出的深度卷积神经网络架构,首次在 2015 年的 ImageNet 竞赛中提出,并取得了惊人的成功。ResNet 以其 残差学习 的思想为核心,成功地解决了随着网络深度增加,训练变得越来越困难的问题。它的提出解决了“加深网络”时出现的退化问题,开创了更加高效和深度的神经网络架构。

ResNet 的核心思想:残差学习

在传统的深层神经网络中,随着网络层数的增加,模型的训练和优化变得越来越困难。为了应对这个问题,ResNet 引入了 残差学习(Residual Learning) 的思想,通过引入跳跃连接(skip connection)捷径连接(shortcut connection) 来帮助信息流在网络中更容易传播。

残差块(Residual Block)

ResNet 的基本单元是 残差块,它由两层或更多层卷积组成,并且在这些层之间加入了“跳跃连接”。这些跳跃连接直接将输入加到输出上,从而避免了深层网络训练中的梯度消失问题。

数学上,残差块的输出是:

                y=F(x,{Wi})+x

其中:

  • x 是输入
  • F(x,{Wi}) 是通过卷积等操作计算得到的特征
  • x 被直接加到 F(x,{Wi}) 上,作为网络的输出。

通过这种结构,网络学到的目标变成了学习输入和输出之间的“残差”(即差异),而不是直接学习输出。这种结构能够大大加速训练过程,并且使得更深的网络能够更容易地训练。

残差块的优点
  1. 避免梯度消失问题: 跳跃连接允许梯度直接从更深的层反向传播到更浅的层,使得即使在非常深的网络中,梯度也不会迅速消失。

  2. 加深网络而不增加训练难度: 残差连接使得网络能够非常容易地加深,且不会因为层数增加而导致训练困难。这使得 ResNet 可以训练上百甚至上千层的深度网络。

  3. 提高性能: 由于有效地利用了更深的网络,ResNet 在许多计算机视觉任务中,尤其是图像分类、目标检测和图像分割等任务中,表现得非常优异。


ResNet 架构

ResNet 的基本结构由多个 残差块 堆叠而成,通常每个阶段的残差块数目会有所不同。

ResNet 网络结构示意图
  • 输入图像通常为 224×224×3。
  • 初始阶段:一个大的卷积层,大小为 7×7,步长为 2,后跟一个最大池化层。
  • 多个阶段:每个阶段由多个残差块组成,每个残差块由两个或三个卷积层组成(卷积、批归一化、ReLU 激活)。
  • 输出阶段:全局平均池化层(Global Average Pooling),输出一个固定长度的向量。
  • 全连接层:最后经过全连接层进行分类。

ResNet-50、ResNet-101 和 ResNet-152

ResNet 有不同的变种,其中最常见的是 ResNet-50ResNet-101ResNet-152。这些数字表示网络中的残差块数量。

  • ResNet-50:由 50 层组成,使用了一个名为 Bottleneck 的残差块,它比传统的残差块更高效,适用于更深层的网络。
  • ResNet-101:由 101 层组成,适用于更复杂的任务,能够提取更深层次的特征。
  • ResNet-152:由 152 层组成,具有更深的层次,可以捕捉到更多的细节信息。

ResNet 中的 Bottleneck 结构

为了提高效率,ResNet-50 和更深的 ResNet 网络使用了 Bottleneck 结构,它通过减少中间层的通道数来减少计算量。传统的残差块通过两层卷积(3×3)进行特征提取,而 Bottleneck 结构将每个残差块分解成三部分:

  1. 一个 1×1 卷积用于降维
  2. 一个 3×3 卷积用于特征提取
  3. 一个 1×1 卷积用于恢复通道数。

这种结构通过减少计算量而不牺牲网络的表现力,使得 ResNet 在加深网络层数的同时不会导致计算开销过大。


ResNet 的应用场景

  1. 图像分类: ResNet 在 ImageNet 数据集上取得了突破性的成绩,成为图像分类任务中的标准架构。它能够处理非常复杂的图像分类任务,并且在大规模数据集上表现优异。

  2. 目标检测: ResNet 可以作为目标检测框架(如 Faster R-CNNMask R-CNN)的基础网络。由于其深层次特征提取的能力,ResNet 在检测小物体和复杂场景时表现更好。

  3. 图像分割: 由于 ResNet 能够提取丰富的图像特征,它也被广泛应用于图像分割任务中(如 FCNU-Net),尤其是在医学图像分析中取得了显著成果。

  4. 迁移学习: ResNet 由于其良好的泛化能力,通常作为迁移学习的基础模型,在许多其他领域(如文本分类、语音识别等)中得到应用。


ResNet 的优缺点

优点

  1. 深层网络的训练变得可行
    通过引入残差连接,ResNet 可以训练数百层的深度网络,极大提高了模型的表达能力。

  2. 减少梯度消失问题
    残差连接允许梯度直接传播,使得深度网络在训练时更加稳定。

  3. 高效且易于扩展
    ResNet 使用了高效的 Bottleneck 结构,可以在不增加计算复杂度的情况下加深网络。

缺点
  1. 计算复杂性较高
    尽管 ResNet 的参数较少,但随着网络的加深,计算复杂度仍然较高,特别是在更深的网络(如 ResNet-152)上。

  2. 内存消耗较大
    深层的网络会导致更多的内存消耗,尤其是在训练阶段。


ResNet 的实现代码示例

以下是使用 PyTorch 加载和使用 ResNet-34 模型的代码示例:

import torch
import torch.nn as nn


class Conv(nn.Module):
    def __init__(self, in_channels, out_channels, kernel_size, padding=0, groups=1, stride=1):
        super(Conv, self).__init__()
        self.conv = nn.Conv2d(in_channels=in_channels, out_channels=out_channels, kernel_size=kernel_size, stride=stride, padding=padding, groups=groups)
        self.bn = nn.BatchNorm2d(num_features=out_channels)
        self.relu = nn.ReLU6()

    def forward(self, x):
        x = self.conv(x)
        x = self.bn(x)
        x = self.relu(x)
        return x

class ResNet_Block(nn.Module):
    def __init__(self, in_channels, out_channels, stride=1):
        super(ResNet_Block, self).__init__()
        if in_channels == out_channels and stride == 1:
            self.fage = False
        else:
            self.fage = True
        self.conv = Conv(in_channels=in_channels, out_channels=out_channels, kernel_size=1, stride=stride)
        self.conv1 = Conv(in_channels=in_channels, out_channels=out_channels, kernel_size=3, padding=1, stride=stride)
        self.conv2 = Conv(in_channels=out_channels, out_channels=out_channels, kernel_size=3, padding=1)

    def forward(self, x):
        x1= self.conv1(x)
        x1 = self.conv2(x1)
        if self.fage:
            x = self.conv(x)
        return x+x1

class ResNet_mod(nn.Module):
    def __init__(self, in_channels,out_channels,num,stride=1):
        super(ResNet_mod, self).__init__()
        self.num = num
        self.resnet_block1 = ResNet_Block(in_channels=in_channels, out_channels=out_channels, stride=stride)
        self.resnet_block2 = ResNet_Block(in_channels=out_channels, out_channels=out_channels, stride=1)

    def forward(self, x):
        x = self.resnet_block1(x)
        for i in range(self.num-1):
            x = self.resnet_block2(x)
        return x




class MyNetwork(nn.Module):
    '''一般在init中来构建网络算子层的初始属性'''

    def __init__(self, num_class):
        # 继承父类中的初始构造函数
        super(MyNetwork, self).__init__()
        self.conv = nn.Sequential(
            Conv(in_channels=3, out_channels=64, kernel_size=7, stride=2, padding=3),
            nn.MaxPool2d(kernel_size=3, stride=2, padding=1),
            ResNet_mod(in_channels=64, out_channels=64,num=3, stride=1),
            ResNet_mod(in_channels=64, out_channels=128,num=4, stride=2),
            ResNet_mod(in_channels=128, out_channels=256,num=6, stride=2),
            ResNet_mod(in_channels=256, out_channels=512,num=3, stride=2),
            nn.AdaptiveAvgPool2d(output_size=1),
            Conv(in_channels=512, out_channels=num_class, kernel_size=1)
        )
        self.flat = nn.Flatten()
        self.softmax = nn.Softmax(dim=1)  # 分类层

    ''' forward,必须叫这个名称。但是输入的参数,可以有多少。至少有1个input_X'''

    def forward(self, input_X):
        x = self.conv(input_X)
        x = self.flat(x)
        out = self.softmax(x)
        return out

总结

ResNet 的创新之处在于引入了残差学习,解决了深层网络训练中的退化问题。它使得训练非常深的神经网络成为可能,同时通过跳跃连接保持了良好的训练稳定性。ResNet 作为一种高效且深度可扩展的架构,已经成为计算机视觉领域的重要模型,并广泛应用于图像分类、目标检测、图像分割等任务中。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值