1. ResNet与FPN为何需要强强联合
目标检测任务中最大的挑战之一就是如何处理图像中不同尺度的目标。想象一下你要在一张街景照片中同时识别远处的行人和近处的汽车——前者可能只有几十个像素大小,后者则占据了大半个画面。传统卷积神经网络在处理这种多尺度问题时往往会顾此失彼:深层网络擅长捕捉大目标的语义特征,却会丢失小目标的细节;浅层网络保留了丰富的空间信息,但缺乏高级语义理解。
ResNet通过残差连接解决了深层网络的梯度消失问题,让网络可以延伸到上百层。但即便这样,单靠ResNet提取的特征金字塔仍然存在语义鸿沟——深层特征虽然语义丰富但空间分辨率低,浅层特征分辨率高但语义表达能力弱。这就好比用望远镜看远处很清晰,但换成显微镜就找不到原来的观察目标了。
FPN(特征金字塔网络)的聪明之处在于构建了一条"信息高速公路",让高层特征可以顺畅地回流到低层。具体来说,它通过三个关键设计实现了多尺度特征的和谐统一:
- 自底向上路径:这就是常规的ResNet前向传播过程,像流水线一样逐层提取特征
- 自顶向下路径:把高层特征通过上采样"反卷积"回低分辨率
- 横向连接:用1x1卷积对齐通道数后,将上下层特征像拼积木一样相加
实测表明,这种结构对小目标检测的提升尤为明显。在COCO数据集上,ResNet-50+FPN相比单尺度ResNet在小目标检测AP上能提高8-10个点,相当于把识别准确率从"大概猜得出"提升到"一眼就能确认"的水平。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. ResNet的残差结构精要
2.1 残差学习的数学本质
残差模块的核心思想可以用一个公式概括:H(x) = F(x) + x。这里的x是输入特征,F(x)是卷积层要学习的变化量,H(x)是最终输出。这种设计巧妙地让网络只需要学习"差值"而不是完整的变换,就像教你骑自行车时,教练只需要纠正你偏离平衡的部分,而不需要重新教整个平衡技巧。
实际应用中有两种典型的残差块:
python复制# BasicBlock(用于ResNet-18/34)
class BasicBlock(nn.Module):
def __init__(self, in_channels, out_channels, stride=1):
super().__init__()
self.conv1 = nn.Conv2d(in_channels, out_channels, 3, stride, padding=1)
self.bn1 = nn.BatchNorm2d(out_channels)
self.conv2 = nn.Conv2d(out_channels, out_channels, 3, padding=1)
self.bn2 = nn.BatchNorm2d(out_channels)
# 当输入输出维度不一致时需要投影 shortcut
self.shortcut = nn.Sequential()
if stride != 1 or in_channels != out_channels:
self.shortcut = nn.Se
