当前位置: 首页 > news >正文

ResNet详解

ResNet(Residual Neural Network)是2015年由Kaiming He等人提出的革命性深度神经网络架构,在ImageNet竞赛中以3.57%的错误率夺冠,并深刻影响了深度学习的发展方向。

1. 深度神经网络的关键问题

1.1 梯度消失/爆炸问题

在传统深度网络中:

  • 反向传播时梯度需要逐层传递
  • 梯度值可能指数级减小(消失)或增大(爆炸)
  • 导致深层网络难以训练

数学表达
对于L层网络,第l层的梯度:
∂ L o s s ∂ W l = ∂ L o s s ∂ f L ⋅ ∏ k = l L − 1 ∂ f k + 1 ∂ f k ⋅ ∂ f l ∂ W l \frac{\partial Loss}{\partial W_l} = \frac{\partial Loss}{\partial f_L} \cdot \prod_{k=l}^{L-1} \frac{\partial f_{k+1}}{\partial f_k} \cdot \frac{\partial f_l}{\partial W_l} WlLoss=fLLossk=lL1fkfk+1Wlfl
当层数L很大时,连乘积项极易变得极小或极大

1.2 网络退化问题

实验发现:

  • 并非网络越深性能越好
  • 56层网络比20层网络在训练集和测试集上表现都更差
  • 这不是过拟合问题(训练误差也更高)

2. ResNet核心创新

2.1 残差学习框架

传统映射:直接学习H(x)
残差映射:学习F(x) = H(x) - x,因此H(x) = F(x) + x

关键优势

  • 当最优映射接近恒等映射时,网络只需使F(x)→0
  • 相比学习H(x)→x,学习F(x)→0更容易

2.2 跳跃连接(Shortcut Connection)

实现形式:
y = F ( x , { W i } ) + x y = F(x, \{W_i\}) + x y=F(x,{Wi})+x

两种实现方式

  1. 恒等映射(Identity Shortcut):当输入输出维度相同
    # PyTorch实现
    out = F(x) + x
    
  2. 投影映射(Projection Shortcut):当维度不同时
    # 使用1×1卷积调整维度
    shortcut = nn.Sequential(nn.Conv2d(in_channels, out_channels, kernel_size=1, stride=stride),nn.BatchNorm2d(out_channels)
    )
    out = F(x) + shortcut(x)
    

2.3 残差块详细结构

基本残差块(Basic Block)
Input│├──────────────┐↓              │
Conv3×3          │
BN               │
ReLU             │
Conv3×3          │
BN               ││              │└─────(+)──────┘│ReLU│Output

参数计算:对于C通道输入输出
参数量 = 3×3×C×C + 3×3×C×C = 18C²

瓶颈残差块(Bottleneck Block)
Input│├────────────────┐↓                │
Conv1×1 (降维至C/4) │
BN                 │
ReLU               │
Conv3×3            │
BN                 │
ReLU               │
Conv1×1 (升维至C)   │
BN                 ││                │└──────(+)───────┘│ReLU│Output

参数计算:对于C通道输入输出
参数量 = 1×1×C×C/4 + 3×3×C/4×C/4 + 1×1×C/4×C = C²/4 + 9C²/16 + C²/4 ≈ 0.81C²

对比:当C=256时,Basic Block参数量≈1.18M,Bottleneck≈0.53M

3. 完整网络架构

3.1 ResNet-34详细结构

Layer NameOutput Size34-layer参数计算
conv1112×1127×7, 64, stride 2(7×7×3)×64 = 9,408
56×563×3 max pool, stride 2-
conv2_x56×563×3, 64 ×3(3×3×64)×64×3 = 110,592
conv3_x28×283×3, 128 ×4下采样块: (3×3×64)×128 + (1×1×64)×128 = 73,728 + 8,192
普通块: (3×3×128)×128×3 = 442,368
conv4_x14×143×3, 256 ×6下采样块: 类似计算
conv5_x7×73×3, 512 ×3类似计算
1×1global avg pool-
fc-1000-d fc512×1000 = 512,000

总参数量:约21.8M

3.2 不同版本ResNet配置

NetworkLayersBasic/Bottleneck BlocksParams (M)FLOPs (G)
ResNet-1818Basic: [2,2,2,2]11.71.8
ResNet-3434Basic: [3,4,6,3]21.83.6
ResNet-5050Bottleneck: [3,4,6,3]25.63.8
ResNet-101101Bottleneck: [3,4,23,3]44.57.6
ResNet-152152Bottleneck: [3,8,36,3]60.211.3

4. 训练细节与技巧

4.1 初始化方法

采用Kaiming初始化(He初始化):

  • 针对ReLU的初始化方法
  • 权重从N(0, √(2/n))采样,其中n是输入单元数
def init_weights(m):if isinstance(m, nn.Conv2d):nn.init.kaiming_normal_(m.weight, mode='fan_out', nonlinearity='relu')

4.2 学习率策略

使用热身学习率(Learning Rate Warmup):

  1. 前5个epoch线性增加学习率:0 → 初始学习率
  2. 然后按cosine衰减
scheduler = torch.optim.lr_scheduler.CosineAnnealingLR(optimizer, T_max=200)

4.3 正则化技术

  1. 权重衰减:0.0001
  2. BatchNorm:ε=1e-5,momentum=0.1
  3. 标签平滑(Label Smoothing):0.1
criterion = nn.CrossEntropyLoss(label_smoothing=0.1)

5. 数学原理深入

5.1 残差连接的理论解释

考虑传统网络第l层到第L层的映射:
x L = x l + ∑ i = l L − 1 F ( x i , W i ) x_L = x_l + \sum_{i=l}^{L-1} F(x_i, W_i) xL=xl+i=lL1F(xi,Wi)

反向传播时梯度:
∂ L o s s ∂ x l = ∂ L o s s ∂ x L ⋅ ( 1 + ∂ ∂ x l ∑ i = l L − 1 F ( x i , W i ) ) \frac{\partial Loss}{\partial x_l} = \frac{\partial Loss}{\partial x_L} \cdot \left(1 + \frac{\partial}{\partial x_l} \sum_{i=l}^{L-1} F(x_i, W_i)\right) xlLoss=xLLoss(1+xli=lL1F(xi,Wi))

关键点

  1. 梯度包含直接传播项(1)和残差项
  2. 即使残差项很小,梯度也不会完全消失

5.2 与Highway Networks对比

Highway Networks:
y = H ( x ) ⋅ T ( x ) + x ⋅ ( 1 − T ( x ) ) y = H(x) \cdot T(x) + x \cdot (1-T(x)) y=H(x)T(x)+x(1T(x))
其中T(x)是变换门

ResNet可视为T(x)=1的简化版本,实验表明这种简化反而更有效

6. 现代改进与变体

6.1 ResNeXt (2017)

引入**基数(Cardinality)**概念:

  • 在残差块中使用分组卷积
  • 超参数:基数C表示并行路径数
class ResNeXtBlock(nn.Module):def __init__(self, in_channels, out_channels, stride=1, cardinality=32):super().__init__()D = out_channels // 2  # 每组通道数self.conv1 = nn.Conv2d(in_channels, D, kernel_size=1)self.conv2 = nn.Conv2d(D, D, kernel_size=3, stride=stride, padding=1, groups=cardinality)self.conv3 = nn.Conv2d(D, out_channels, kernel_size=1)def forward(self, x):out = F.relu(self.conv1(x))out = F.relu(self.conv2(out))out = self.conv3(out)# ... 跳跃连接 ...

6.2 Res2Net (2019)

多尺度残差块:

  • 在单个残差块内构建层级残差连接
  • 将特征图分成几组,逐级处理

6.3 EfficientNet (2019)

结合ResNet思想与网络缩放:

  • 复合缩放深度、宽度和分辨率
  • 使用MBConv(含残差连接)

7. 实践应用指南

7.1 迁移学习技巧

  1. 不同数据集的处理

    • 大数据集:微调所有层
    • 小数据集:只微调最后几层
  2. 学习率设置

# 预训练层使用较小学习率
optim.SGD([{'params': model.conv1.parameters(), 'lr': lr*0.1},{'params': model.fc.parameters(), 'lr': lr}
], momentum=0.9)

7.2 可视化工具

梯度流向分析

# 注册钩子记录梯度
def backward_hook(module, grad_input, grad_output):print(f"{module.__class__.__name__} grad norm: {grad_output[0].norm()}")for layer in model.children():layer.register_full_backward_hook(backward_hook)

8. 前沿研究方向

  1. 神经架构搜索(NAS)优化ResNet

    • 自动搜索最优残差连接模式
    • 如EfficientNet的MBConv块
  2. 动态ResNet

    • 根据输入动态调整残差路径
    • 如SkipNet、CondConv等
  3. 跨模态ResNet

    • 将残差思想应用于多模态学习
    • 如CLIP中的图像-文本残差连接

ResNet的成功证明了简单而有效的设计可以产生深远影响,其核心思想仍在不断启发新的神经网络架构创新。

相关文章:

  • 全层微调:解锁预训练模型的无限潜力
  • js-getSelection获取选中内容
  • tcpdump 的用法
  • CDGP重点知识梳理(82个)
  • Auto DOP:让并行执行实现智能调优 | OceanBase 实践
  • 达梦、PostgreSQL数据库讲json解析成临时表(json_table函数的使用)
  • 通用外设驱动模型(四步法)
  • 微信小程序地图缩放scale隐性bug
  • [AI Tools] Dify 平台插件开发全解:如何构建 Tools 插件并解析输出逻辑
  • OpenCV中适用华为昇腾(Ascend)后端的逐元素操作(Per-element Operations)
  • 【质量管理】TRIZ因果链分析:解码质量问题的“多米诺效应“
  • 经典计算核心问题在于多项式时间内无法求解
  • 重庆工商职业学院“户卫者”团队为建筑外墙检测技术推广创新赋能
  • PostgreSQL创建只读账号
  • 自适应混合索引创建与管理:一种智能数据库优化机制的研究
  • PH热榜 | 2025-05-09
  • 『Python学习笔记』ubuntu解决matplotlit中文乱码的问题!
  • 鸿蒙电脑:五年铸剑开新篇,国产操作系统新引擎
  • 华为防火墙双机热备(负载分担)
  • 华为欧拉(EulerOS)系统全栈软件部署指南:从 Redis 到 MySQL 实战详解
  • 李在明正式登记参选下届韩国总统
  • 巴基斯坦称成功拦截印度导弹,空军所有资产安全
  • 上财发布“AI+课程体系”,人工智能如何赋能财经教育?
  • 850亿元!2025年中央金融机构注资特别国债(一期)拟第一次续发行
  • 重庆党政代表团在沪考察,陈吉宁龚正与袁家军胡衡华共商两地深化合作工作
  • 外卖员投资失败负疚离家流浪,经民警劝回后泣不成声给父母下跪