LEARNING LOG

第 2 课:CNN 骨干网络原理与残差学习(ResNet 底层实现)

  • 目标检测
  • CNN
  • ResNet
  • 残差网络
  • 感受野推导

[!info] 知识库导航 [[00_目标检测知识库总览_MOC|🏠 返回知识库总览 (MOC)]] | ⬅️ [[Lesson01_Overview|第01讲]] | ➡️ [[Lesson03_Transformer_and_Metrics|第03讲:Transformer 与指标]] | 💻 [[end_to_end_detector_pipeline.py|配套代码:检测流水线]]

学习要点:从高维张量物理机理建立底层认知,推导感受野(RF)递推式与有效感受野高斯衰减,掌握 ResNet 残差梯度反传与结构重参数化(RepConv)算子折叠代数说明,掌握会议论文 Related Work 撰写规范。


0.0 参数与符号对照字典

在卷积神经网络与骨干网络表征体系中,以下参数与符号构成了核心数学字典:

符号英文全称物理机理与代数定义常见取值工程设计直觉
KKernel Size(卷积核尺寸)局部空间滑动窗口的空间连续几何边长3 (3×33\times3)<br>1 (1×11\times1)空间局部特征相关性的聚合窗口尺寸。
PPadding(边缘填充)在输入特征图外围边界补零的层数0 (无填充)<br>1 (四周各补1层)保持输出空间拓扑分辨率或对齐边界信息。
SStride(滑动步长)卷积核在空间维度滑动采样的像素跨距1 (密集连续)<br>2 (下采样)控制输出空间分辨率降采样率与感受野扩张率。
H / WHeight / Width特征张量在垂直高度与水平宽度维度的空间分辨率512, 128, 16 等空间离散网格点的矩阵行列规模。
CChannels(通道数)并行堆叠的独立正交特征图基底数量3 (RGB), 64, 512独立特征检测模式的表征维度容量。
BBatch Size(批大小)单次前向推理与梯度反传打包计算的样本数量2, 4, 16, 32矩阵并行计算规模与随机梯度估计的稳定性。
RF\mathbf{RF}Receptive Field(感受野)特征图上某点在原始输入空间上所映射的物理影响区域边长1,7,11,35…1, 7, 11, 35 \dots特征单元能够感知全局上下文的最大理论空间跨度。
μ,σ\mathbf{\mu, \sigma}Mean, Variance(均值、方差)mini-batch 内激活分布的一阶矩与二阶中心矩统计统计量归一化激活分布,约束协变量偏移。
ϵ\mathbf{\epsilon}Epsilon(数值微调稳定常数)极小的常数(如 1e−51e-5)1e−51e-5数值截断保护,防止分母除以零引发浮点溢出。
η\mathbf{\eta}Learning Rate(学习率)梯度下降优化步长缩放标量0.0010.001, 0.00010.0001沿损失函数负梯度方向更新权重矢量的步幅。

0.1 核心机制与架构精要速览

1. 卷积操作与局部归纳偏置(Inductive Bias)

  • 机制:通过可学习的局部权重核在输入张量上执行滑动空间加权内积,全图共享参数。
  • 物理收益:内生具备平移等变性(Translation Equivariance)与局部像素高度相关性先验,参数量与计算复杂度显著低于全连接密集网络。

2. 感受野逐层扩张规律(Receptive Field Expansion)

  • 递推公式:第 ll 层感受野为 RFl=RFl−1+(Kl−1)×∏i=1l−1Si\text{RF}_{l} = \text{RF}_{l-1} + (K_l - 1) \times \prod_{i=1}^{l-1} S_i。步长 S>1S > 1 的下采样操作促使后续层感受野呈乘法级快速放大。
  • 空间矛盾:深层大感受野捕获丰富全局宏观语义,但空间下采样会损失部分高频几何信息,形成目标检测小目标定位的固有挑战。

3. 残差跳跃连接机制(Residual Learning)

  • 设计动机:打破深度网络因梯度连乘衰减引发的网络退化(Degradation Problem)。
  • 数学本质:构造恒等映射通道 H(x)=F(x)+x\mathcal{H}(x) = \mathcal{F}(x) + x。反向传播梯度为 ∂H∂x=∂F∂x+1\frac{\partial \mathcal{H}}{\partial x} = \frac{\partial \mathcal{F}}{\partial x} + 1;即使残差分支梯度变小,短路分支仍提供直接的梯度传递路径。

4. 结构重参数化(Structural Re-parameterization)

  • 设计动机:化解“训练期多分支表征丰富度”与“推理期单路直连高效访存”之间的工程冲突。
  • 机制:在推理前将训练阶段的多分支(3×33\times 3 卷积、 1×11\times 1 卷积、Identity 直连与 BN)通过矩阵代数折叠为单一的 3×33\times 3 卷积核与偏置,减少推理分支;性能变化需要结合具体实现和硬件测试。

1. 骨干网络(Backbone)在目标检测中的角色与张量流转

目标检测网络通常拆解为主干、颈部与检测头三大模块:

+---------------+     +--------------------+     +-------------------+
|  输入图像      | --> |  骨干网 (Backbone) | --> |  颈部 (Neck: FPN) | --> 检测头 (Head: Cls + Reg)
|  [B, 3, H, W] |     |  多尺度特征提取器   |     |  跨尺度特征融合   |
+---------------+     +--------------------+     +-------------------+
                             │
                             ├── C2: Stride 4  (高空间分辨率,低层边缘纹理丰富)
                             ├── C3: Stride 8  (局部几何部件响应)
                             ├── C4: Stride 16 (中尺度语义抽象)
                             └── C5: Stride 32 (大感受野,强类别语义,低空间分辨率)

1.1 特征图层级抽象提纯机理

  1. 输入原图:形状 [B,3,H,W][B, 3, H, W],包含原始光度像素值。
  2. 浅层阶段(C2/C3):通过小步长卷积与早期特征变换提取边缘轮廓与基本形状模式,保留精细的空间几何对齐关系。
  3. 深层阶段(C4/C5):经过多级跨度为 2 的下采样与残差块堆叠,空间分辨率缩小为原来的 1/161/16 与 1/321/32,特征通道维度扩充至 256 与 512,激活响应对应宏观实体类别存在性。

2. 卷积基础算子代数推导与空间尺寸控制

2.1 输出尺寸计算闭式解

标准二维卷积的输出空间尺寸由输入尺寸 HinH_{\text{in}}、填充 PP、核大小 KK 与步长 SS 严格决定:

Hout=⌊Hin+2P−KS⌋+1H_{\text{out}} = \left\lfloor \frac{H_{\text{in}} + 2P - K}{S} \right\rfloor + 1
  • +2P+2P:空间边界双侧填充扩展。
  • −K-K:卷积核在无位移初始放置状态下所消耗的基底空间。
  • /S/S:沿空间坐标滑动的有效位移步数。
  • +1+1:包含初始零位移起点离散栅格采样点。

2.2 批归一化(Batch Normalization)数学推导

对输入 mini-batch B={x1…m}\mathcal{B} = \{x_{1 \dots m}\}:

  1. 小批量均值与方差:

    μB=1m∑i=1mxi,σB2=1m∑i=1m(xi−μB)2\mu_{\mathcal{B}} = \frac{1}{m} \sum_{i=1}^m x_i, \quad \sigma_{\mathcal{B}}^2 = \frac{1}{m} \sum_{i=1}^m (x_i - \mu_{\mathcal{B}})^2
  2. 标准化处理:

    x^i=xi−μBσB2+ϵ\hat{x}_i = \frac{x_i - \mu_{\mathcal{B}}}{\sqrt{\sigma_{\mathcal{B}}^2 + \epsilon}}
  3. 尺度缩放与平移可学习恢复:

    yi=γx^i+βy_i = \gamma \hat{x}_i + \beta
  • 物理机理:约束层间输入分布的协变量漂移,平滑损失曲面的 Lipschitz 连续性,允许模型在更高学习率下稳定收敛。

3. 感受野(Receptive Field)递推与有效感受野理论

3.1 感受野递推方程

设第 l−1l-1 层的理论感受野为 RFl−1\text{RF}_{l-1},第 ll 层核尺寸为 KlK_l,步长为 SlS_l:

RFl=RFl−1+(Kl−1)×Scumul\text{RF}_l = \text{RF}_{l-1} + (K_l - 1) \times S_{\text{cumul}}

其中 Scumul=∏i=1l−1SiS_{\text{cumul}} = \prod_{i=1}^{l-1} S_i 代表从输入层到达第 l−1l-1 层的累积步长乘积。

3.2 堆叠小卷积的代数优势(VGG 哲学)

  • 两层 3×33\times 3 卷积串联(S=1S=1):

    RF1=1+(3−1)×1=3\text{RF}_1 = 1 + (3 - 1) \times 1 = 3 RF2=3+(3−1)×1=5\text{RF}_2 = 3 + (3 - 1) \times 1 = 5
    • 其理论感受野与单层 5×55\times 5 卷积完全一致。
    • 参数量比值:两层 3×33\times 3 参数为 2×(32×C2)=18C22 \times (3^2 \times C^2) = 18C^2;单层 5×55\times 5 参数为 25C225C^2。参数量降低 28%。
    • 表达能力:引入两次连续非线性激活(ReLU),使得模型决策边界的拓扑复杂度大幅提升。

3.3 有效感受野(Effective Receptive Field, ERF)高斯衰减

虽然理论感受野(Theoretical RF)随网络加深呈线性扩张,但根据中心极限定理,输出特征对输入像素的偏导数 ∂y∂x\frac{\partial y}{\partial x} 呈现以中心为峰值的典型二维高斯分布:

ERF(u,v)∝exp⁡(−u2+v22σERF2)\text{ERF}(u, v) \propto \exp\left( -\frac{u^2 + v^2}{2\sigma_{\text{ERF}}^2} \right)

因此,边缘区域像素对最终特征激活的影响呈指数衰减。在设计目标检测主干时,单纯依赖理论大感受野不足以确保对极端大目标的完整捕捉,需借助空洞卷积(Dilated Conv)或自注意力机制拉平高斯衰减方差。


4. 残差网络(ResNet)反向传播说明与架构演变

4.1 梯度反向传播单位项说明

标准残差单元定义为:

xl+1=xl+F(xl,Wl)x_{l+1} = x_l + \mathcal{F}(x_l, \mathcal{W}_l)

通过递归展开,任意深层 LL 的特征可表示为浅层 ll 特征与所有中间残差映射的线性累加:

xL=xl+∑i=lL−1F(xi,Wi)x_L = x_l + \sum_{i=l}^{L-1} \mathcal{F}(x_i, \mathcal{W}_i)

根据微分链式法则,损失函数 E\mathcal{E} 对浅层状态 xlx_l 的梯度反向传播公式为:

∂E∂xl=∂E∂xL∂xL∂xl=∂E∂xL(I+∂∂xl∑i=lL−1F(xi,Wi))\frac{\partial \mathcal{E}}{\partial x_l} = \frac{\partial \mathcal{E}}{\partial x_L} \frac{\partial x_L}{\partial x_l} = \frac{\partial \mathcal{E}}{\partial x_L} \left( \mathbf{I} + \frac{\partial}{\partial x_l} \sum_{i=l}^{L-1} \mathcal{F}(x_i, \mathcal{W}_i) \right)

  • 关键结论:括号内包含单位矩阵项 I\mathbf{I}。即使深层残差导数 ∂F∂xl\frac{\partial \mathcal{F}}{\partial x_l} 变小,梯度 ∂E∂xL\frac{\partial \mathcal{E}}{\partial x_L} 仍可沿恒等分支直接传递到浅层 xlx_l,从而缓解梯度弥散。

4.2 BasicBlock 与 Bottleneck 架构差异

  • BasicBlock(ResNet-18 / 34):包含两层连续 3×33\times 3 卷积,适合轻量级任务。
  • Bottleneck(ResNet-50 / 101 / 152):采用三步降升维设计:
    1. 1×11\times 1 卷积降维(通道数压缩至 1/41/4);
    2. 3×33\times 3 空间卷积(在低维流形上执行特征抽取);
    3. 1×11\times 1 卷积升维(通道数恢复原始尺度)。
    • 该设计大幅削减了浮点运算量(FLOPs),使得极深网络计算开销处于可控边界以内。

5. 结构重参数化(Structural Re-parameterization / RepConv)机制与代数折叠说明

现代高效实时目标检测网络(如 YOLOv6/v7、RepVGG)广泛采用结构重参数化技术,成功平衡了模型训练表现力与硬件部署吞吐。

5.1 训练与推理的多分支矛盾

  • 训练阶段:多分支网络(3×33\times 3 卷积分支 + 1×11\times 1 降维分支 + Identity 直连分支)引入多路径梯度流,有效缓解优化曲面退化并拓宽特征表征子空间。
  • 推理阶段:多分支结构引入频繁的 GPU 访存操作(Memory Access Cost, MAC),分支张量缓存与相加开销使得实际帧率(FPS)远落后于理论 FLOPs。

5.2 卷积与 BN 融合的严密代数说明

设输入张量为 x\mathbf{x},卷积核权重为 W∈RCout×Cin×K×K\mathbf{W} \in \mathbb{R}^{C_{\text{out}} \times C_{\text{in}} \times K \times K},偏置为 b\mathbf{b}。卷积后紧跟批量归一化层:

yconv=W∗x+b\mathbf{y}_{\text{conv}} = \mathbf{W} * \mathbf{x} + \mathbf{b}

ybn=γyconv−μσ2+ϵ+β\mathbf{y}_{\text{bn}} = \gamma \frac{\mathbf{y}_{\text{conv}} - \mu}{\sqrt{\sigma^2 + \epsilon}} + \beta

将 yconv\mathbf{y}_{\text{conv}} 展开代入可得:

ybn=γσ2+ϵ(W∗x+b−μ)+β=(γWσ2+ϵ)∗x+(γ(b−μ)σ2+ϵ+β)\mathbf{y}_{\text{bn}} = \frac{\gamma}{\sqrt{\sigma^2 + \epsilon}} (\mathbf{W} * \mathbf{x} + \mathbf{b} - \mu) + \beta = \left( \frac{\gamma \mathbf{W}}{\sqrt{\sigma^2 + \epsilon}} \right) * \mathbf{x} + \left( \frac{\gamma (\mathbf{b} - \mu)}{\sqrt{\sigma^2 + \epsilon}} + \beta \right)

由此定义等效融合卷积核与融合偏置:

Wfused=γσ2+ϵW,bfused=β+γ(b−μ)σ2+ϵ\mathbf{W}_{\text{fused}} = \frac{\gamma}{\sqrt{\sigma^2 + \epsilon}} \mathbf{W}, \quad \mathbf{b}_{\text{fused}} = \beta + \frac{\gamma (\mathbf{b} - \mu)}{\sqrt{\sigma^2 + \epsilon}}

5.3 三分支合并为单一 3×33\times 3 卷积核

  1. 3×33\times 3 分支:直接根据上述公式计算得 W(3×3)\mathbf{W}^{(3\times 3)} 与 b(3×3)\mathbf{b}^{(3\times 3)}。

  2. 1×11\times 1 分支:通过在边界补零(Zero-padding)将 1×11\times 1 卷积核中心对齐嵌入 3×33\times 3 空间尺寸:

    Wcout,cin,i,j(1×1→3×3)={Wcout,cin(1×1),i=1,j=10,其他\mathbf{W}^{(1\times 1 \to 3\times 3)}_{c_{\text{out}}, c_{\text{in}}, i, j} = \begin{cases} \mathbf{W}^{(1\times 1)}_{c_{\text{out}}, c_{\text{in}}}, & i=1, j=1 \\ 0, & \text{其他} \end{cases}
  3. Identity 分支:当输入输出通道一致时,恒等映射等价于一个中心权重为 1、其余位置全为 0 的单位脉冲(Dirac Delta)卷积核:

    Wcout,cin,i,j(id→3×3)={1,cout=cin 且 i=1,j=10,其他\mathbf{W}^{(\text{id} \to 3\times 3)}_{c_{\text{out}}, c_{\text{in}}, i, j} = \begin{cases} 1, & c_{\text{out}} = c_{\text{in}} \text{ 且 } i=1, j=1 \\ 0, & \text{其他} \end{cases}
  4. 最终等价卷积合成:

    Wdeploy=W(3×3)+W(1×1→3×3)+W(id→3×3)\mathbf{W}_{\text{deploy}} = \mathbf{W}^{(3\times 3)} + \mathbf{W}^{(1\times 1 \to 3\times 3)} + \mathbf{W}^{(\text{id} \to 3\times 3)} bdeploy=b(3×3)+b(1×1)+b(id)\mathbf{b}_{\text{deploy}} = \mathbf{b}^{(3\times 3)} + \mathbf{b}^{(1\times 1)} + \mathbf{b}^{(\text{id})}

5.4 RepConv PyTorch 实现与验证

import torch
import torch.nn as nn
import torch.nn.functional as F

class RepConv(nn.Module):
    def __init__(self, in_channels: int, out_channels: int, deploy: bool = False):
        super().__init__()
        self.deploy = deploy
        self.in_channels = in_channels
        self.out_channels = out_channels

        if deploy:
            self.rbr_reparam = nn.Conv2d(in_channels, out_channels, kernel_size=3, padding=1, bias=True)
        else:
            # 训练阶段三分支架构
            self.rbr_dense = nn.Sequential(
                nn.Conv2d(in_channels, out_channels, kernel_size=3, padding=1, bias=False),
                nn.BatchNorm2d(out_channels)
            )
            self.rbr_1x1 = nn.Sequential(
                nn.Conv2d(in_channels, out_channels, kernel_size=1, padding=0, bias=False),
                nn.BatchNorm2d(out_channels)
            )
            self.rbr_identity = nn.BatchNorm2d(in_channels) if out_channels == in_channels else None

        self.act = nn.ReLU(inplace=True)

    def forward(self, x: torch.Tensor) -> torch.Tensor:
        if self.deploy:
            return self.act(self.rbr_reparam(x))

        id_out = self.rbr_identity(x) if self.rbr_identity is not None else 0
        return self.act(self.rbr_dense(x) + self.rbr_1x1(x) + id_out)

    def switch_to_deploy(self):
        """将训练阶段多分支参数融合成单路 3x3 卷积核与偏置"""
        if self.deploy:
            return

        kernel, bias = self._get_equivalent_kernel_bias()
        self.rbr_reparam = nn.Conv2d(self.in_channels, self.out_channels, kernel_size=3, padding=1, bias=True)
        self.rbr_reparam.weight.data = kernel
        self.rbr_reparam.bias.data = bias

        # 释放训练分支结构与缓存
        self.__delattr__('rbr_dense')
        self.__delattr__('rbr_1x1')
        if hasattr(self, 'rbr_identity'):
            self.__delattr__('rbr_identity')
        self.deploy = True

    def _fuse_bn_tensor(self, conv: nn.Conv2d, bn: nn.BatchNorm2d):
        kernel = conv.weight
        running_mean = bn.running_mean
        running_var = bn.running_var
        gamma = bn.weight
        beta = bn.bias
        eps = bn.eps

        std = (running_var + eps).sqrt()
        t = (gamma / std).reshape(-1, 1, 1, 1)
        return kernel * t, beta - running_mean * gamma / std

    def _get_equivalent_kernel_bias(self):
        kernel3x3, bias3x3 = self._fuse_bn_tensor(self.rbr_dense[0], self.rbr_dense[1])
        kernel1x1, bias1x1 = self._fuse_bn_tensor(self.rbr_1x1[0], self.rbr_1x1[1])
        # 1x1 卷积核向 3x3 填充
        kernel1x1_padded = F.pad(kernel1x1, [1, 1, 1, 1])

        if self.rbr_identity is not None:
            # 构造脉冲卷积核
            id_kernel = torch.zeros_like(kernel3x3)
            for i in range(self.in_channels):
                id_kernel[i, i, 1, 1] = 1.0
            bn_id = self.rbr_identity
            std = (bn_id.running_var + bn_id.eps).sqrt()
            t = (bn_id.weight / std).reshape(-1, 1, 1, 1)
            kernel_id = id_kernel * t
            bias_id = bn_id.bias - bn_id.running_mean * bn_id.weight / std
        else:
            kernel_id = torch.zeros_like(kernel3x3)
            bias_id = torch.zeros_like(bias3x3)

        return kernel3x3 + kernel1x1_padded + kernel_id, bias3x3 + bias1x1 + bias_id

在学术论文第二章(Related Work)中应当严格遵循的写作关键规范:

违规写法(低效流水账)规范学术写法(会议论文标准)底层学术逻辑
以学者人名堆叠为主语:<br>Ren et al. [1] proposed Faster R-CNN. Then, Lin et al. [2] designed FPN...以方法体系为主语:<br>Faster R-CNN [1] introduces a Region Proposal Network (RPN) to... Subsequent work, FPN [2], constructs a top-down pathway to...学术共同体关注技术思想的演进脉络,而非作者生平。连篇的 "X et al." 体现归纳体系薄弱。
时态混乱交错:<br>YOLO was dividing the image... then DETR has eliminated NMS...统一采用一般现在时(Simple Present):<br>YOLO frames detection as a dense grid regression problem. DETR eliminates the need for hand-crafted NMS.客观科学机制与既定经典定理在学术英语中统一用一般现在时陈述。
按时间简单罗列论文:<br>缺乏专题归类,逐篇摘要拼贴。专题式模块化结构论述:<br>划分子章节:<br>- 2.1 Backbone Architectures<br>- 2.2 Feature Pyramid Networks<br>- 2.3 Loss Functions in Object Detection展现对整个研究领域演进图谱的宏观掌控力与分类批判性思维。

7. 典型问题技术答疑与深度分析

7.1 深度特征图的物理意义演进

  • 问题:特征图张量数值是如何从原始输入图像逐步演变到高维特征的?
  • 分析:输入图像是空间连续像素点阵,浅层卷积响应对应空间局部梯度变化(水平、垂直边界与角点)。伴随感受野与通道扩展,网络通过多级非线性映射将离散几何边缘逐步解耦重构为局部部件特征(车轮、门框、面部),最终在深层抽象为反映全局语义分布的概率特征基底。

7.2 堆叠两个 3×33\times 3 卷积覆盖 5×55\times 5 的光线追踪推导

  • 问题:为什么两个连续 3×33\times 3 卷积的感受野等价于单个 5×55\times 5 卷积?
  • 推导:
    • 设输入为一维离散序列:[P1, P2, P3, P4, P5];
    • 第 1 层卷积(K=3,S=1K=3, S=1):
      • 神经元 A1A_1 覆盖区间 [P1, P2, P3];
      • 神经元 A2A_2 覆盖区间 [P2, P3, P4];
      • 神经元 A3A_3 覆盖区间 [P3, P4, P5];
    • 第 2 层卷积(K=3,S=1K=3, S=1):
      • 高响应神经元 B1B_1 覆盖区间 [A1, A2, A3];
    • 映射反向回溯:
      • B1B_1 的感知范围为 A1∪A2∪A3=[P1,P2,P3,P4,P5]A_1 \cup A_2 \cup A_3 = [P1, P2, P3, P4, P5];
      • 因而单点在原始输入空间上实际覆盖了 5 个连续采样点,感受野精确扩张至 5。

8. 多尺度特征与下采样机理剖析

【核心议题】

对于分辨率仅为 8×88\times 8 像素的极端微小目标(如远景无人机或微小航标):

  1. 经过 32 倍下采样到达骨干网络 C5 层时,空间几何信息会发生何种演变?
  2. 目标检测器应当如何权衡浅层与深层特征的分工?

【物理机理深度剖析】

  1. 连续几何信息被稀疏化抹平:
    • 当原图尺寸为 8×88\times 8 时,在 32 倍跨度下采样后,其有效空间覆盖尺寸仅为 8/32=0.258 / 32 = 0.25 像素。
    • 在网格量化与大步长卷积池化计算中,该微小目标在离散采样网格中极易完全丢失采样中心点;即使参与求和,其微弱的激活响应也会被周围背景几百个像素的卷积求和权重大幅稀释,信噪比急剧恶化。
  2. 浅层高分辨率与深层高语义的协同需求:
    • 浅层特征图(C2/C3)拥有较高的空间分辨率与丰富的像素级边缘几何信息,但缺乏全局语义指导,容易产生虚警误检。
    • 深层特征图(C5)具备强判别性类别语义与宏观上下文,但空间网格严重退化,无法提供微小目标的精确定位边界。
    • 技术结论:单一依赖任何单层特征均无法完成全场景检测,必须引入自顶向下的跨尺度特征融合机制(FPN/PANet),将 C5 的强语义自上而下注入 C2/C3 的高清空间几何底图中。

9. 本地运行记录

以下截图来自本机 PyTorch 环境中的当前轮执行记录;本课对应模块均为 PASS。

ResNet 骨干网络

逐步视觉执行演示