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

PyTorch 深度学习专题【左扬精讲】—— 目标检测与语义分割:CNN 的下游任务应用

PyTorch 深度学习专题【左扬精讲】—— 目标检测与语义分割:CNN 的下游任务应用

掌握了经典 CNN 架构(LeNet、AlexNet、VGGNet、GoogLeNet、ResNet、MobileNet、DenseNet)之后,一个关键问题是:这些特征提取网络是如何被应用于实际的计算机视觉下游任务的?

图像分类只告诉我们 "图像里有什么",而目标检测需要回答 "在哪里、是什么",语义分割需要回答 "每个像素属于哪个类别"

本文将系统讲解目标检测(两阶段与单阶段检测器)和语义分割(FCN、DeepLabV3、U-Net)的架构设计与 PyTorch 官方 API 使用方法。

torchvision.models.detection.fasterrcnn_resnet50_fpn    ← 两阶段检测器(Faster R-CNN + FPN)
torchvision.models.detection.fasterrcnn_resnet50_fpn_v2 ← 改进版 Faster R-CNN(V2)
torchvision.models.detection.ssd300_vgg16               ← 单阶段检测器(SSD + VGG 主干)
torchvision.models.detection.retinanet_resnet50_fpn     ← 单阶段检测器(RetinaNet + FPN)
torchvision.models.detection.maskrcnn_resnet50_fpn      ← 实例分割(Mask R-CNN)
torchvision.models.segmentation.fcn_resnet50            ← 语义分割(FCN + ResNet-50)
torchvision.models.segmentation.fcn_resnet101           ← 语义分割(FCN + ResNet-101)
torchvision.models.segmentation.deeplabv3_resnet50      ← 空洞卷积语义分割(DeepLabV3)
torchvision.models.segmentation.deeplabv3_resnet101     ← DeepLabV3 + ResNet-101

PyTorch目标检测语义分割Faster R-CNNSSDRetinaNetFCNDeepLabV3U-Nettorchvision

学习重点

  • 必须掌握
  • Faster R-CNN 两阶段检测流程:Backbone → RPN → RoI Pooling → 检测头
  • Anchor 机制与 NMS 原理
  • FCN 全卷积化与上采样的设计
  • 语义分割的评测指标:mIoU 与 pixel accuracy
  • torchvision.detection 和 torchvision.segmentation 的 API 使用
  • 理解即可
  • 单阶段检测器(SSD、RetinaNet)与两阶段检测器的权衡
  • DeepLabV3 的 ASPP 多尺度空洞卷积
  • Grad-CAM 特征可视化的原理

目录

  1. 从图像分类到下游任务的架构演进
  2. 目标检测:两阶段 vs 单阶段
  3. 两阶段检测器:Faster R-CNN 详解
  4. 单阶段检测器:SSD 与 RetinaNet
  5. 语义分割:逐像素分类
  6. 全卷积网络:FCN
  7. DeepLabV3:空洞卷积的多尺度分割
  8. U-Net:编码器-解码器结构
  9. 特征图可视化:理解 CNN 学到了什么
  10. FAQ(20 组)
  11. Roadmap 预告

一、从图像分类到下游任务的架构演进

Why — 为什么 CNN 架构可以直接迁移到下游任务?

图像分类网络(如 ResNet、VGG)通过大量数据学习了通用的视觉特征——边缘、纹理、形状、物体部件等。这些层次化的特征在目标检测和语义分割中同样适用。因此,下游任务通常以预训练的分类网络作为骨干(Backbone),在其基础上添加任务特定的头部(Head)。这种"预训练 Backbone + 任务 Head"的设计范式大幅降低了训练成本。

三大下游任务的本质区别

  • 图像分类(Image Classification):整张图像输出一个类别标签,不需要空间定位。
  • 目标检测(Object Detection):同时预测多个物体的类别标签和边界框(Bounding Box),输出 N 个 [x, y, w, h, class] 元组。
  • 语义分割(Semantic Segmentation):为图像中每个像素预测一个类别标签,输出与输入分辨率相同的分割掩码。

统一架构模式:Backbone + Head

  • Backbone:预训练的分类 CNN(如 ResNet-50),负责从图像中提取层次化特征
  • Head:任务特定的输出头,负责将特征图转换为最终预测结果

本节小结

  • 迁移学习:预训练 Backbone 学到的通用视觉特征可以直接迁移到检测和分割任务
  • Backbone + Head:统一的架构设计范式,Backbone 提取特征,Head 完成任务特定输出

二、目标检测:两阶段 vs 单阶段

目标检测的核心挑战是什么?

图像分类是 "单标签输出",而目标检测需要同时解决定位和分类两个问题——一张图中可能有多个不同类别的物体,每个物体需要用边界框精确框出。核心难点在于:物体的数量、位置、尺度都是未知的。

两阶段检测器(Two-Stage Detector)

第一阶段(RPN)生成高质量候选区域(Region Proposals),第二阶段对候选区域进行分类和边界框精修。代表模型:R-CNN → Fast R-CNN → Faster R-CNN。速度较慢但精度高。

单阶段检测器(One-Stage Detector)

直接在特征图的每个位置预测物体类别和边界框,无需生成候选区域。代表模型:SSDRetinaNet、YOLO。速度快但对小物体召回率较低。

Anchor 机制(锚框机制)

两阶段和单阶段检测器都依赖 Anchor(锚框)来枚举可能的物体尺度和长宽比。通常在每个特征图位置预设 3 种尺度 × 3 种长宽比 = 9 个 Anchor 框。模型学习的是每个 Anchor 与真实物体(Ground Truth)之间的偏移量(Offset),而非直接预测坐标。

两阶段 vs 单阶段对比

维度两阶段(Faster R-CNN)单阶段(SSD / RetinaNet)
代表模型 Faster R-CNN SSD、RetinaNet、YOLO
检测流程 RPN 生成候选区 → 分类+精修 一步直接回归类别和坐标
速度 较慢(5-20 FPS) 较快(25-100+ FPS)
精度 高(尤其小物体) 略低(类别不平衡问题)
Anchor 数量 约 2,000(RPN 筛选后) 大量(数十万,覆盖密集)

本节小结

  • 两阶段:RPN 生成候选区 → RoI Pooling → 检测头,精度高,速度较慢
  • 单阶段:一步到位预测类别和坐标,速度快,小物体召回率相对较低
  • Anchor:枚举预设尺度和长宽比,模型学习偏移量而非绝对坐标

三、两阶段检测器:Faster R-CNN 详解

What — Faster R-CNN 是什么?

Faster R-CNN 由 Shaoqing Ren 等人在 2015 年提出(论文《Faster R-CNN: Towards Real-Time Object Detection with Region Proposal Networks》),是两阶段目标检测的里程碑。它通过将区域候选网络(Region Proposal Network, RPN)嵌入到主干网络中,实现了候选区域生成和目标检测的端到端联合训练,消除了传统方法中依赖外部区域候选算法(如 Selective Search)的瓶颈。

Why — Faster R-CNN 为什么分两个阶段?

问题:直接对所有可能的区域做分类,计算量巨大且背景框过多

如果对图像中每个滑动窗口位置都做分类,200×200 图像就有 4 万个位置,每个位置还要枚举多个尺度和长宽比——计算量根本无法承受。Faster R-CNN 的解决方案是:先用轻量级的 RPN 网络快速筛选出最有可能是物体的区域(Region Proposals),再用更精确的检测头对这些候选区域做分类和精修。

端到端联合训练的意义

RPN 和检测头共享主干网络的卷积特征(Feature Pyramid Network, FPN 提供多尺度特征),两者可以联合优化,RPN 学到的候选区域质量直接影响检测精度。

Faster R-CNN 流水线图解
输入图像 (H×W×3)│▼
┌─────────────────────────────────────────────────────┐
│  Backbone(ResNet-50 + FPN)                        │
│  → 提取多尺度共享特征图(P2/P3/P4/P5/P6)           │
└─────────────────────────────────────────────────────┘│▼
┌─────────────────────────────────────────────────────┐
│  RPN(Region Proposal Network)                     │
│  输入:特征图每个位置预设 9 个 Anchor(3尺度×3比)  │
│  输出:每个 Anchor 的 objectness score(前景/背景) │
│       + bounding box regression(坐标偏移量)       │
│  → NMS 筛选,保留约 1000-2000 个候选框              │
└─────────────────────────────────────────────────────┘│▼
┌─────────────────────────────────────────────────────┐
│  RoI Align(双线性插值对齐,替代 RoI Pooling)      │
│  → 将不同尺寸的候选框映射为固定尺寸(如 7×7)       │
└─────────────────────────────────────────────────────┘│▼
┌─────────────────────────────────────────────────────┐
│  Detection Head(R-CNN Head,Sibling Head)         │
│  固定尺寸特征 → 并行两支:                        │
│    ① 分类分支(FC+Softmax)→ K+1 类概率          │
│    ② 边界框精修(FC+smooth L1)→ K 类坐标偏移     │
└─────────────────────────────────────────────────────┘│▼输出:[boxes, scores, labels](每张图 N 个检测结果)

RPN 的工作原理

RPN 在特征图的每个空间位置放置 k 个 Anchor 框(通常 k=9:3 种尺度 × 3 种长宽比),对每个 Anchor 预测两个值:objectness score(该位置是否包含物体)和 4 个 bounding box regression 偏移量(x, y, w, h 的调整量)。RPN 的损失函数为:

  • 分类损失:对每个 Anchor 的 objectness 做二分类交叉熵(前景 vs 背景)
  • 回归损失:对标记为正样本的 Anchor 做 smooth L1 回归

NMS(非极大值抑制)

同一物体可能被多个重叠的 Anchor 预测,NMS 按 objectness score 降序排列所有候选框,保留与最高分框 IoU(Intersection over Union)低于阈值的框,抑制重叠框。典型阈值为 IoU=0.7。

Faster R-CNN PyTorch 官方加载方式
import torch
import torchvision.models.detection as detection
from torchvision.models.detection import (fasterrcnn_resnet50_fpn_v2,FasterRCNN_ResNet50_FPN_V2_Weights,FasterRCNN_MobileNet_V3_Large_FPN_Weights,FasterRCNN_MobileNet_V3_Large_320_FPN_Weights,
)# 推荐使用 V2 版本(基于 Benchmarking Detection Transfer Learning with Vision Transformers)
model = fasterrcnn_resnet50_fpn_v2(weights=FasterRCNN_ResNet50_FPN_V2_Weights.DEFAULT
)
model.eval()# 输入:图像列表(Tensor[C, H, W] 或 PIL.Image)
# 输出:每张图一个字典,包含 boxes, labels, scores
images = [torch.rand(3, 640, 480)]
with torch.no_grad():predictions = model(images)
print(predictions[0].keys())  # dict_keys(['boxes', 'labels', 'scores'])
print(f"检测到 {len(predictions[0]['boxes'])} 个物体")
print(f"类别: {predictions[0]['labels']}")
print(f"置信度: {predictions[0]['scores']}")# 自定义类别数(默认 91 类 COCO)
num_classes = 21  # Pascal VOC 20 类 + 背景
model = fasterrcnn_resnet50_fpn_v2(weights=None, num_classes=num_classes)# MobileNetV3 主干(轻量版)
mobilenet_model = detection.fasterrcnn_mobilenet_v3_large_fpn(weights=FasterRCNN_MobileNet_V3_Large_FPN_Weights.DEFAULT
)# Low-resolution 移动端版本
mobilenet_320_model = detection.fasterrcnn_mobilenet_v3_large_320_fpn(weights=FasterRCNN_MobileNet_V3_Large_320_FPN_Weights.DEFAULT
)

Faster R-CNN 的输出 boxes 格式为 [x_min, y_min, x_max, y_max](像素坐标),labels 为类别索引(COCO 数据集共 91 类),scores 为 [0, 1] 之间的置信度分数。推理时需要将 model.eval() 切换到评估模式,以禁用 Dropout 和 BatchNorm 的训练行为。

Faster R-CNN V1 vs V2 的区别

特性V1V2
骨干网络 ResNet-50 + FPN ResNet-50 + FPN(改进训练配方)
RoI 处理 RoI Pooling(量化取整) RoI Align(双线性插值,无量化误差)
COCO Box mAP 约 37.9% 约 47.4%(显著提升)
出处 Faster R-CNN 原论文 Benchmarking Detection Transfer Learning with Vision Transformers

V2 版本的改进主要来自:RoI Align 替代 RoI Pooling(消除量化误差)、更优的训练超参数、以及新的数据增强策略。

本节小结

  • Faster R-CNN:两阶段检测,Backbone 共享 RPN 和检测头的特征,RPN 生成候选区,检测头做分类+精修
  • RPN:在特征图每个位置用 Anchor 预测前景/背景得分和坐标偏移量
  • RoI Align:双线性插值对齐,解决 RoI Pooling 的量化误差问题
  • V2 版本:改进训练配方,COCO mAP 从约 37.9% 提升至约 47.4%

四、单阶段检测器:SSD 与 RetinaNet

What — 为什么需要单阶段检测器?

单阶段检测器(如 SSD、RetinaNet、YOLO)的核心优势是速度。Faster R-CNN 在 RPN 阶段需要生成和筛选大量候选框,导致推理速度受限于检测头的计算。而单阶段检测器跳过了候选区生成阶段,直接在特征图上预测类别和边界框,实现实时检测(25-100+ FPS)。

SSD(Single Shot MultiBox Detector)的设计

SSD 在主干网络(如 VGG-16)输出的多个尺度特征图上同时做检测:浅层特征图空间分辨率大(适合检测小物体),深层特征图语义信息丰富(适合检测大物体)。SSD 在每个特征图位置预设多个 Anchor,直接预测每个 Anchor 的类别置信度和边界框偏移量。

RetinaNet 与 Focal Loss

单阶段检测器的核心问题是"类别不平衡":背景 Anchor 占绝对多数,导致正样本(物体)梯度信号被淹没。RetinaNet 提出了 Focal Loss,通过降低易分类样本的权重,使模型专注于难分类的正样本和困难负样本:

Focal Loss = -α_t · (1 - p_t)^γ · log(p_t)
# α_t: 类别平衡权重
# p_t: 模型预测的置信度
# γ (gamma): 聚焦参数,γ越大越关注难分类样本
# 典型值:α=0.25, γ=2

当模型对某样本的置信度 p_t 很高时,(1-p_t)^γ 趋近于 0,该样本的损失贡献被大幅压低,实现了自动的难例挖掘。

SSD 与 RetinaNet PyTorch 官方加载方式
import torch
import torchvision.models.detection as detection
from torchvision.models.detection import (ssd300_vgg16, retinanet_resnet50_fpn,SSD300_VGG16_Weights, RetinaNet_ResNet50_FPN_Weights,
)# SSD300(以 VGG-16 为骨干,300×300 输入)
ssd_model = ssd300_vgg16(weights=SSD300_VGG16_Weights.DEFAULT)
ssd_model.eval()# RetinaNet(以 ResNet-50 + FPN 为骨干)
retinanet_model = retinanet_resnet50_fpn(weights=RetinaNet_ResNet50_FPN_Weights.DEFAULT)
retinanet_model.eval()# 推理示例
images = [torch.rand(3, 640, 480)]
with torch.no_grad():ssd_pred = ssd_model(images)retinanet_pred = retinanet_model(images)print(f"SSD 检测数: {len(ssd_pred[0]['boxes'])}")
print(f"RetinaNet 检测数: {len(retinanet_pred[0]['boxes'])}")# 两种模型均输出: boxes, labels, scores

YOLO 的特殊性

YOLO(You Only Look Once)是最流行的单阶段检测器之一,但 PyTorch 官方 torchvision 不包含 YOLO 实现。社区常用的 YOLO 实现主要依赖 Ultralytics 的 ultralytics 库(支持 YOLOv8/v11 等),通过 pip install ultralytics 安装。实际项目中推荐使用 Ultralytics 官方库加载 YOLO 模型。

本节小结

  • SSD:多尺度特征图并行检测,浅层检测小物体,深层检测大物体
  • RetinaNet:Focal Loss 解决单阶段检测的类别不平衡问题
  • YOLO:不包含在 torchvision 官方库中,需使用 ultralytics 等第三方库

五、语义分割:逐像素分类

What — 语义分割与实例分割有何不同?

语义分割(Semantic Segmentation)为图像中每个像素分配一个类别标签,同一类别的不同物体不加区分(如两张人脸都标记为"人")。实例分割(Instance Segmentation)更进一步,不仅分类每个像素,还区分同类物体的不同个体(如将两张人脸分别标记为"人_1"和"人_2")。Mask R-CNN 是实例分割的代表性模型。

语义分割的核心挑战:如何恢复空间分辨率?

CNN 中的池化(MaxPool)和步长卷积会不断缩小特征图的空间尺寸(如 224→112→56→28→7),而语义分割需要输出与输入相同分辨率的分割掩码。解决方案主要有两种:

  • 上采样(Upsampling):通过转置卷积(Transposed Convolution)或双线性插值将特征图放大回原始分辨率
  • 空洞卷积(Atrous / Dilated Convolution):在不下采样损失分辨率的前提下扩大感受野(DeepLabV3 采用此策略)

语义分割的评测指标

  • mIoU(Mean Intersection over Union):各类别 IoU 的平均值,是最核心的分割评测指标
  • Pixel Accuracy:正确分类像素占总像素的比例

IoU 的计算方式

对于类别 c:IoU_c = |预测为 c 的像素 ∩ 真实为 c 的像素| / |预测为 c 的像素 ∪ 真实为 c 的像素|。mIoU 是所有类别 IoU 的算术平均。典型值:FCN-ResNet50 在 VOC 上约 60.5%,DeepLabV3-ResNet50 约 66.4%。

本节小结

  • 语义分割:为每个像素分配类别标签,输出 H×W 的分割掩码
  • 实例分割:区分同类物体的不同个体(如 Mask R-CNN)
  • mIoU:语义分割的核心评测指标,各类别的平均交并比

六、全卷积网络:FCN

What — FCN 是什么?

FCN(Fully Convolutional Network)由 Jonathan Long 等人在 2014 年提出(论文《Fully Convolutional Networks for Semantic Segmentation》),是深度学习语义分割的开山之作。FCN 的核心创新是将图像分类网络(如 VGG-16)的全连接层替换为卷积层,使网络可以接受任意尺寸的输入并输出对应尺寸的分割掩码。

Why — 为什么分类网络不能直接用于分割?

问题:全连接层要求固定尺寸输入,且输出是向量而非空间图

VGG-16 等分类网络的最后几层是全连接层(4096→4096→1000),输出是 1000 维向量而非空间特征图。全连接层丢弃了所有空间信息,无法做逐像素预测。FCN 的解决方案是将全连接层等效替换为 1×1 卷积:

  • VGG-16 的 FC1(4096 维)→ Conv1×1(输入 512×7×7 → 输出 4096×1×1)
  • VGG-16 的 FC2(4096 维)→ Conv1×1(输入 4096 → 输出 4096)
  • VGG-16 的 FC3(1000 维)→ Conv1×1(输入 4096 → 输出 1000)

替换后网络输出变为 H/32 × W/32 × 1000 的特征图(H 和 W 为输入图像的高和宽)。

上采样策略

FCN 通过转置卷积(Transposed Convolution,也称反卷积)将 1/32 分辨率的特征图上采样 32 倍回原始分辨率。FCN-32s 直接一步上采样 32 倍,FCN-16s 将 1/16 和 1/32 特征图融合后再上采样 16 倍,FCN-8s 则融合 1/8、1/16、1/32 三层,精度最高。

FCN PyTorch 官方加载方式
import torch
import torchvision.models.segmentation as segmentation
from torchvision.models.segmentation import (fcn_resnet50, fcn_resnet101,FCN_ResNet50_Weights, FCN_ResNet101_Weights,
)# FCN-ResNet50(以 ResNet-50 为骨干)
fcn_model = fcn_resnet50(weights=FCN_ResNet50_Weights.DEFAULT)
fcn_model.eval()# FCN-ResNet101(更深骨干,精度更高)
fcn_model101 = fcn_resnet101(weights=FCN_ResNet101_Weights.DEFAULT)# 输入预处理(权重自带的 transforms)
preprocess = FCN_ResNet50_Weights.DEFAULT.transforms()
x = torch.rand(1, 3, 520, 520)  # Batch of 1
x_processed = preprocess(x)# 前向传播
with torch.no_grad():output = fcn_model(x_processed)["out"]
print(f"输出尺寸: {output.shape}")  # torch.Size([1, 21, 520, 520])
# 21 通道:Pascal VOC 20 类 + 背景# 获取每个像素的预测类别
pred_labels = output.argmax(dim=1)  # torch.Size([1, 520, 520])
print(f"分割掩码形状: {pred_labels.shape}")  # H×W 分割图# 自定义类别数
custom_model = segmentation.fcn_resnet50(weights=None, num_classes=5)# 显存估算:FCN-ResNet50 约 35.3M 参数,152.72 GFLOPS
total_params = sum(p.numel() for p in fcn_model.parameters())
print(f"FCN-ResNet50 参数量: {total_params:,}")  # 35,322,218

FCN 的输出 output["out"] 形状为 [B, num_classes, H, W],每张图每个通道对应一个类别的分割概率图。argmax(dim=1) 在通道维度取最大值,得到每个像素的预测类别索引。output.softmax(dim=1) 可以将通道维度转换为概率分布,便于计算置信度。

FCN 的性能指标(COCO-VOC 子集)

模型参数量GFLOPSmIoUPixel Acc
FCN-ResNet50 35.3M 152.72 60.5% 91.4%
FCN-ResNet101 54.3M 232.74 63.7% 91.9%

权重在 COCO 数据集的 Pascal VOC 子集(20 类)上训练,resize_size=[520],归一化参数为 mean=[0.485, 0.456, 0.406],std=[0.229, 0.224, 0.225]。

本节小结

  • FCN:将分类网络的全连接层替换为 1×1 卷积,实现全卷积化,可处理任意尺寸输入
  • 转置卷积:将低分辨率特征图上采样回原始分辨率
  • 多尺度融合:FCN-8s 融合 1/8、1/16、1/32 特征图,精度优于 FCN-32s
  • FCN-ResNet50:mIoU 60.5%,Pixel Acc 91.4%

七、DeepLabV3:空洞卷积的多尺度分割

What — DeepLabV3 是什么?

DeepLabV3 由 Google 团队提出(论文《Rethinking Atrous Convolution for Semantic Image Segmentation》),是当前最主流的语义分割架构之一。DeepLabV3 的核心创新是空洞卷积(Atrous Convolution / Dilated Convolution),在不下采样特征图的前提下扩大感受野,同时保持高空间分辨率。

Why — 为什么 FCN 的上采样方案有局限性?

问题:多次下采样导致空间细节丢失,上采样无法完全恢复

FCN 的多次下采样(stride=2)导致 224×224 图像最终只有 7×7 的特征图,虽然上采样可以恢复尺寸,但在此过程中丢失的细节(如物体边界、细小结构)无法通过上采样完全恢复。DeepLabV3 的解决方案是:使用空洞卷积,在不降低分辨率的情况下增大感受野。

空洞卷积的工作原理

标准卷积(dilation=1)的卷积核元素之间间隔 0;空洞卷积(dilation=r)在元素之间插入 r-1 个空洞(零值)。对于 k×k 卷积核,空洞卷积的有效感受野为 k + (k-1)×(r-1)。例如,3×3 卷积核在 dilation=2 时,有效感受野相当于 5×5,但参数量仍为 3×3。

ASPP(Atrous Spatial Pyramid Pooling)模块

DeepLabV3 的 ASPP 模块在特征图上并行使用多个不同空洞率的卷积分支(dilation=12, 24, 36),同时捕捉多尺度语义信息:

  • 大 dilation(如 36):大物体、大尺度特征
  • 小 dilation(如 12):小物体、细粒度特征
  • Image-level pooling:全局上下文信息
DeepLabV3 PyTorch 官方加载方式
import torch
import torchvision.models.segmentation as segmentation
from torchvision.models.segmentation import (deeplabv3_resnet50, deeplabv3_resnet101, deeplabv3_mobilenet_v3_large,DeepLabV3_ResNet50_Weights, DeepLabV3_ResNet101_Weights,DeepLabV3_MobileNet_V3_Large_Weights,
)# DeepLabV3-ResNet50(以 ResNet-50 为骨干,含 ASPP 模块)
deeplabv3_model = deeplabv3_resnet50(weights=DeepLabV3_ResNet50_Weights.DEFAULT)
deeplabv3_model.eval()# DeepLabV3-ResNet101(更深骨干,精度更高)
deeplabv3_model101 = deeplabv3_resnet101(weights=DeepLabV3_ResNet101_Weights.DEFAULT)# DeepLabV3-MobileNetV3-Large(轻量版)
deeplabv3_mobilenet = deeplabv3_mobilenet_v3_large(weights=DeepLabV3_MobileNet_V3_Large_Weights.DEFAULT
)# 推理
preprocess = DeepLabV3_ResNet50_Weights.DEFAULT.transforms()
x = torch.rand(1, 3, 520, 520)
x_processed = preprocess(x)with torch.no_grad():output = deeplabv3_model(x_processed)["out"]
print(f"输出尺寸: {output.shape}")  # torch.Size([1, 21, 520, 520])# 获取分割结果
pred_labels = output.argmax(dim=1)# 参数量对比:DeepLabV3-ResNet50 约 42.0M
total_params = sum(p.numel() for p in deeplabv3_model.parameters())
print(f"DeepLabV3-ResNet50 参数量: {total_params:,}")  # 42,004,074

DeepLabV3 的 model(x)["out"] 输出与 FCN 相同格式的分割 logits(未归一化),model(x)["aux"] 是辅助损失头的输出(训练时使用,推理时被丢弃)。ASPP 模块中的多分支空洞卷积是 DeepLabV3 在 Pascal VOC 上达到 66.4% mIoU 的关键。

DeepLabV3 性能指标(COCO-VOC 子集)

模型骨干网络参数量GFLOPSmIoUPixel Acc
DeepLabV3-ResNet50 ResNet-50 42.0M 178.72 66.4% 92.4%
DeepLabV3-ResNet101 ResNet-101 60.1M 256.38 67.4% 92.4%
DeepLabV3-MobileNetV3 MobileNetV3-Large 3.5M 12.37 60.3% 91.2%

本节小结

  • DeepLabV3:通过空洞卷积(dilation>1)在不下采样分辨率的前提下扩大感受野
  • ASPP:多尺度空洞卷积分支并行,捕捉不同尺度的语义信息
  • mIoU 66.4%(ResNet-50),比 FCN-ResNet50(60.5%)高约 6 个百分点

八、U-Net:编码器-解码器结构

What — U-Net 是什么?

U-Net 由 Olaf Ronneberger 等人在 2015 年提出(论文《U-Net: Convolutional Networks for Biomedical Image Segmentation》),最初为生物医学图像分割设计,因其简洁有效的编码器-解码器结构成为医学影像、遥感分割等领域的标准 Baseline。U-Net 的名称来源于其对称的 U 形架构。

Why — 为什么需要编码器-解码器架构?

问题:语义分割需要同时满足"语义理解"和"空间定位"两个目标

深层特征图有丰富的语义信息(知道"是什么"),但空间分辨率低(不知道"在哪里");浅层特征图空间分辨率高(知道"在哪里"),但语义信息弱。编码器-解码器架构通过下采样提取深层语义特征,再通过上采样恢复空间分辨率,同时通过 Skip Connection 将浅层的空间细节信息传递到深层。

U-Net 的核心设计

  • 编码器(下采样路径):交替堆叠 3×3 卷积 + ReLU + 2×2 MaxPool,逐步降低分辨率、提高通道数(如 64→128→256→512)
  • 解码器(上采样路径):交替堆叠 3×3 转置卷积(2× 上采样)+ Concat(与编码器同尺度特征拼接)+ 3×3 卷积,逐步恢复分辨率
  • Skip Connection:编码器每个阶段的特征图直接传递给解码器对应阶段(Concat 而非 Add),保留空间细节

Skip Connection 为什么用 Concat 而不是 Add?

ResNet 的残差连接使用 Add(逐元素相加),通道数不变。U-Net 的 Skip Connection 使用 Concat(沿通道维度拼接),使解码器能同时利用来自编码器的浅层细节(高分辨率)和来自深层上采样的语义特征(丰富通道信息),通道数翻倍。这是 U-Net 保留边界细节的关键。

U-Net PyTorch 从零实现
import torch
import torch.nn as nnclass DoubleConv(nn.Module):"""连续两个 3x3 卷积 + BN + ReLU"""def __init__(self, in_ch, out_ch):super().__init__()self.conv = nn.Sequential(nn.Conv2d(in_ch, out_ch, kernel_size=3, padding=1),nn.BatchNorm2d(out_ch),nn.ReLU(inplace=True),nn.Conv2d(out_ch, out_ch, kernel_size=3, padding=1),nn.BatchNorm2d(out_ch),nn.ReLU(inplace=True),)def forward(self, x):return self.conv(x)class UNet(nn.Module):def __init__(self, in_channels=3, num_classes=1, base_ch=64):super().__init__()# 编码器(下采样)self.enc1 = DoubleConv(in_channels, base_ch)       # 64self.enc2 = DoubleConv(base_ch, base_ch*2)         # 128self.enc3 = DoubleConv(base_ch*2, base_ch*4)        # 256self.enc4 = DoubleConv(base_ch*4, base_ch*8)       # 512self.pool = nn.MaxPool2d(kernel_size=2, stride=2)# 瓶颈层self.bottleneck = DoubleConv(base_ch*8, base_ch*16)  # 1024# 解码器(上采样)self.up4 = nn.ConvTranspose2d(base_ch*16, base_ch*8, kernel_size=2, stride=2)self.dec4 = DoubleConv(base_ch*16, base_ch*8)  # Concat 后通道翻倍self.up3 = nn.ConvTranspose2d(base_ch*8, base_ch*4, kernel_size=2, stride=2)self.dec3 = DoubleConv(base_ch*8, base_ch*4)self.up2 = nn.ConvTranspose2d(base_ch*4, base_ch*2, kernel_size=2, stride=2)self.dec2 = DoubleConv(base_ch*4, base_ch*2)self.up1 = nn.ConvTranspose2d(base_ch*2, base_ch, kernel_size=2, stride=2)self.dec1 = DoubleConv(base_ch*2, base_ch)# 输出层:1×1 卷积到指定类别数self.out_conv = nn.Conv2d(base_ch, num_classes, kernel_size=1)def forward(self, x):# 编码器e1 = self.enc1(x)e2 = self.enc2(self.pool(e1))e3 = self.enc3(self.pool(e2))e4 = self.enc4(self.pool(e3))# 瓶颈b  = self.bottleneck(self.pool(e4))# 解码器(每个阶段:上采样 → Concat → DoubleConv)d4 = self.dec4(torch.cat([self.up4(b), e4], dim=1))   # Concat 保留细节d3 = self.dec3(torch.cat([self.up3(d4), e3], dim=1))d2 = self.dec2(torch.cat([self.up2(d3), e2], dim=1))d1 = self.dec1(torch.cat([self.up1(d2), e1], dim=1))return self.out_conv(d1)model = UNet(in_channels=3, num_classes=21)
x = torch.randn(1, 3, 224, 224)
print(model(x).shape)  # torch.Size([1, 21, 224, 224])

U-Net 的 torch.cat([up_feature, encoder_feature], dim=1) 是其核心设计:编码器特征(高分辨率、低通道)与解码器特征(低分辨率、高通道)拼接后,再通过 DoubleConv 融合。转置卷积(ConvTranspose2d)的 stride=2 使特征图尺寸翻倍,与对应编码器层的分辨率精确对齐。

U-Net 变体概览

  • U-Net++(Nested U-Net):在编码器和解码器之间增加了密集的嵌套 Skip Connection,融合更多尺度的特征,提升边界精度
  • ResU-Net:在 U-Net 的每个 DoubleConv 块中引入残差连接,缓解深层网络的梯度问题
  • 3D U-Net:将 2D 卷积替换为 3D 卷积,直接处理体数据(如 CT、MRI)
  • TransU-Net:用 Transformer 编码器替代 ResNet 作为骨干,将自注意力机制引入医学图像分割

本节小结

  • U-Net:对称 U 形架构,编码器下采样提取语义,解码器上采样恢复空间分辨率
  • Skip Connection:Concat 而非 Add,使解码器同时获得高分辨率和丰富语义
  • 转置卷积:stride=2 的转置卷积实现特征图尺寸翻倍
  • 核心优势:在小数据集(如医学影像)上也能取得优秀效果

九、特征图可视化:理解 CNN 学到了什么

为什么需要特征图可视化?

CNN 常被称为"黑箱"——我们很难直观理解一个神经元在响应什么。特征图可视化通过将 CNN 的中间层激活映射回输入图像,帮助我们理解网络在每一层学到了什么样的视觉模式(如边缘、纹理、物体部件、完整物体)。这既是模型调试工具,也是模型可解释性(Explainable AI)研究的基础。

方法一:直接激活可视化

取某层的特征图,直接可视化其空间热力图。通过 PyTorch 的 Hook 机制可以在不修改模型的情况下提取任意层的输出:

import torch
import torchvision.models as models
import matplotlib.pyplot as pltmodel = models.resnet50(weights=models.ResNet50_Weights.DEFAULT)
model.eval()# 注册 Hook:提取 conv1 层的输出
activations = {}
def get_activation(name):def hook(module, input, output):activations[name] = output.detach()return hook# 在目标层注册 Hook
model.conv1.register_forward_hook(get_activation("conv1"))# 前向传播
x = torch.randn(1, 3, 224, 224)
with torch.no_grad():_ = model(x)# 可视化 conv1 的 64 个通道(部分)
act = activations["conv1"][0]  # [64, 112, 112]
fig, axes = plt.subplots(4, 8, figsize=(16, 8))
for i, ax in enumerate(axes.flat):ax.imshow(act[i].numpy(), cmap="viridis")ax.axis("off")
plt.suptitle("ResNet-50 conv1 激活图(64 通道)")
plt.tight_layout()
plt.show()

方法二:CAM(Class Activation Mapping)

CAM 通过分类层的权重,将最后一个卷积层的特征图加权求和,生成类别相关的热力图。CAM 只适用于以 Global Average Pooling + 全连接层结尾的分类网络(如原始的 GoogLeNet)。公式:

CAM_c(x, y) = Σ_k w_k^c · f_k(x, y)
# w_k^c: 第 k 个通道对类别 c 的分类权重(来自 GAP 后的 FC 层)
# f_k(x, y): 最后一层卷积在 (x, y) 位置的第 k 个通道激活

方法三:Grad-CAM(Gradient-weighted Class Activation Mapping)

Grad-CAM 是 CAM 的通用化版本,通过计算类别得分对特征图的梯度作为权重,适用于任意包含卷积层的网络:

import torch
import torchvision.models as modelsmodel = models.resnet50(weights=models.ResNet50_Weights.DEFAULT)
model.eval()# 目标层(通常是最后一个卷积层)
target_layer = model.layer4[-1].conv2
activations = {}
gradients = {}# Forward hook:保存特征图
def forward_hook(module, input, output):activations["feature"] = output.detach()# Backward hook:保存梯度
def backward_hook(module, grad_input, grad_output):gradients["grad"] = grad_output[0].detach()handle_fwd = target_layer.register_full_backward_hook(forward_hook)
handle_bwd = target_layer.register_full_backward_hook(backward_hook)# 前向 + 反向
x = torch.randn(1, 3, 224, 224, requires_grad=True)
output = model(x)
# 选择置信度最高的类别
target_class = output.argmax(dim=1).item()
# 反向传播(只对目标类别求梯度)
model.zero_grad()
output[0, target_class].backward()# 提取特征图和梯度
feature = activations["feature"]       # [B, C, H, W]
grad = gradients["grad"]                 # [B, C, H, W]# 全局平均池化梯度作为通道权重
weights = grad.mean(dim=(2, 3))         # [B, C]
# 加权求和
cam = (weights[0, :, None, None] * feature[0]).mean(dim=0)
cam = torch.relu(cam)                   # ReLU 只保留正响应
# 上采样到原始图像尺寸
cam = torch.nn.functional.interpolate(cam.unsqueeze(0).unsqueeze(0),size=(224, 224),mode="bilinear",align_corners=False
)[0, 0]# 可视化
import matplotlib.pyplot as plt
plt.imshow(cam.numpy(), cmap="jet")
plt.axis("off")
plt.show()handle_fwd.remove()
handle_bwd.remove()

Grad-CAM 的核心思想是:用梯度衡量每个特征图通道对目标类别的重要程度,然后对特征图做加权求和并用 ReLU 过滤负响应,最终上采样到原始图像尺寸。热力图中高亮区域即为网络判断该类别时关注的关键区域。

主流 CAM 类方法对比

方法适用条件是否需要梯度特点
CAM GAP + FC 分类头 简单快速,但只适用特定架构
Grad-CAM 任意卷积网络 通用性好,PyTorch Hook 实现
Grad-CAM++ 任意卷积网络 是(二阶) 梯度加权改进,边界更精确
Score-CAM 任意网络 无需梯度,用置信度变化衡量重要性

本节小结

  • Hook 机制:register_forward_hook / register_full_backward_hook 提取任意层的激活和梯度
  • CAM:用 GAP 后的 FC 权重对特征图加权,生成类别激活图
  • Grad-CAM:用梯度作为通道权重,是 CAM 的通用化版本,适用于任意 CNN
  • ReLU + 上采样:保留正响应热力图,上采样到原始图像尺寸可视化

十、FAQ(20 组)

FAQ — 精选 20 问,深入理解下游任务架构

Q1. RoI Pooling 和 RoI Align 有什么区别?

RoI Pooling 通过量化取整将候选框映射到特征图,存在两次量化误差;RoI Align 使用双线性插值精确采样,完全消除了量化误差。 RoI Pooling 的过程:将候选框区域划分为固定数量的子区域(如 7×7),对每个子区域做最大池化。由于候选框坐标通常是浮点数,取整会引入位置偏差(通常偏移 0-1 个像素)。RoI Align 通过在每个采样点使用双线性插值计算浮点位置的特征值,保留了亚像素级精度。Mask R-CNN 和 Faster R-CNN V2 均使用 RoI Align。

Q2. Anchor 机制中的 IoU(Intersection over Union)是什么?

IoU 是预测框与真实框的交集面积除以并集面积,衡量两个框的重叠程度,取值范围 [0, 1]。 IoU = |B_pred ∩ B_gt| / |B_pred ∪ B_gt|。在 RPN 中,IoU > 0.7 的 Anchor 标记为正样本(包含物体),IoU < 0.3 的标记为负样本,介于两者之间的忽略。IoU=1 表示完全重叠,IoU=0 表示完全不相交。

Q3. 为什么单阶段检测器(如 SSD)的小物体召回率通常低于两阶段检测器?

单阶段检测器在深层特征图上做预测,空间分辨率低(通常为输入的 1/32),小物体在特征图上只有几个像素甚至完全消失。 SSD 在多个尺度特征图上检测,其中浅层特征图负责小物体,但浅层的语义信息不足,容易被背景干扰。两阶段检测器通过 RPN 可以对小候选区做二次精修,小物体信息在 RoI Align 后有专门的特征表达。FPN(Feature Pyramid Network)通过多尺度特征融合改善了单阶段检测器的小物体检测能力。

Q4. NMS(Non-Maximum Suppression)是如何工作的?

NMS 按置信度降序排列所有检测框,选择最高分的框作为保留框,删除与其 IoU 超过阈值的其余框,重复此过程直到处理完所有框。 典型流程:输入检测框列表 [{score=0.9, box=A}, {score=0.8, box=B}, ...] → 保留 A(最高分),删除与 A 的 IoU > 0.7 的框 → 剩余最高分为 B,重复。通常 IoU 阈值设为 0.5~0.7:过低会过度抑制重叠的相邻物体,过高会导致同一物体的多个重复框被保留。

Q5. FCN 的"全卷积化"是如何实现的?

FCN 将 VGG 等分类网络的全连接层等效替换为 1×1 卷积层,使网络输出从固定长度的向量变为空间特征图。 具体来说:输入 512×7×7 的全连接层(7×7 是 VGG 在 224×224 输入下的特征图尺寸),等效为输入通道 512、输出通道 4096 的 1×1 卷积。这样替换后,网络可以接受任意 H×W 的输入图像,输出 H/32 × W/32 × num_classes 的分割 logits。

Q6. 为什么 DeepLabV3 使用空洞卷积而不是更多的上采样?

空洞卷积在保持特征图高分辨率的同时扩大感受野,避免了上采样无法恢复的细节损失。 如果只用 FCN 的上采样方法,需要经过多次下采样(每次分辨率减半)再上采样回来。以 ResNet 为例,stride=2 的卷积导致 224→56 的分辨率损失,即使上采样 4 倍也达不到原始精度。空洞卷积在 dilation=2 时感受野相当于 5×5(比标准 3×3 大),但分辨率不变,使 DeepLabV3 在 Pascal VOC 的边界分割精度显著优于 FCN。

Q7. U-Net 的 Skip Connection 为什么用 Concat 而不是 Add?

Concat 拼接保留了编码器特征的全部信息(通道数翻倍),Add 则只是特征融合(通道数不变),后者会丢失一半的浅层细节。 U-Net 需要在解码器中同时获得高分辨率空间信息(来自编码器)和丰富的语义通道信息(来自解码器上采样路径)。使用 Concat 后 DoubleConv 可以学习如何最优地组合这两部分信息。如果使用 Add,两部分信息已经被混合,解码器的表达能力受限。

Q8. 语义分割中 mIoU 优于 Pixel Accuracy 的原因是什么?

Pixel Accuracy 是全局正确像素比例,容易被占面积大的类别(如背景)主导;mIoU 是各类别 IoU 的平均值,公平地衡量每个类别的分割质量。 举例:如果图像 90% 是背景(IoU=90%),10% 是目标(IoU=10%),Pixel Accuracy = 82%,但 mIoU = (90%+10%)/2 = 50%,后者更真实地反映了目标类别的分割质量。mIoU 是语义分割的事实标准评测指标。

Q9. 为什么 RetinaNet 需要 Focal Loss,而两阶段检测器不需要?

单阶段检测器中正样本(物体)Anchor 远少于负样本(背景)Anchor,类别极度不平衡,Focal Loss 通过降低易分类样本的权重自动平衡。 两阶段检测器的 RPN 已经筛选出约 2000 个候选区,其中正负样本比例相对可控。而 SSD/RetinaNet 直接在数十万个 Anchor 上做预测,99% 以上的 Anchor 是负样本(背景),标准交叉熵损失中负样本的梯度会淹没正样本的梯度。Focal Loss 的 (1-p_t)^γ 因子自动降低了高置信度负样本的贡献,使模型专注于难分类的样本。

Q10. FPN(Feature Pyramid Network)的多尺度特征融合是如何工作的?

FPN 通过自顶向下的路径和横向连接,将深层特征图上采样后与同尺度的浅层特征图逐元素相加,融合高语义和低语义的特征。 FPN 的结构:主干网络的深层特征图(如 C5)经过 1×1 卷积降维后上采样 2 倍,与同分辨率的浅层特征图(C4)逐元素相加,得到 P4。重复此过程得到 P3、P2。所有金字塔层级(P2-P6)用于 RPN 或检测头,实现多尺度目标检测:浅层 P2 负责小物体,深层 P5 负责大物体。

Q11. Faster R-CNN 中 RPN 和检测头是否可以独立训练?

Fast R-CNN 的 RPN 和检测头是独立训练的,而 Faster R-CNN 可以端到端联合训练,两者的卷积特征完全共享。 早期 Fast R-CNN 使用 Selective Search 生成候选区,独立于检测头训练。Faster R-CNN 将 RPN 嵌入主干网络,两者共享 ResNet-FPN 的卷积特征,通过交替优化(alternating training)联合训练:先训练 RPN,再固定 RPN 用其候选区训练检测头,循环迭代。现代实现通常使用近似联合训练(4 步交替优化),在端到端反向传播中同时优化 RPN 和检测头。

Q12. 语义分割的输出如何从 logits 转换为可视化的分割图?

对分割 logits 的通道维度取 argmax 得到每个像素的类别索引,再通过颜色映射表将索引转换为彩色分割图。 步骤:output = model(x)["out"](形状 [B, num_classes, H, W])→ pred = output.argmax(dim=1)(形状 [B, H, W])→ 创建一个调色板(palette),如 VOC 有 21 类对应的 RGB 值 → 将 pred 中的类别索引替换为对应颜色 → 转换为 PIL Image 或 matplotlib 可视化。也可以用 softmax 得到概率分布后取 argmax,或直接用 PIL Image 的 putpalette 方法。

Q13. 为什么 U-Net 在小数据集上表现良好?

U-Net 的 Skip Connection 将编码器的浅层特征直接传递给解码器,这些浅层特征是通用的视觉模式(如边缘、纹理),不依赖大量数据即可学习,因此 U-Net 在小数据集上也能有效训练。 同时,U-Net 的参数量适中(医学影像数据集通常只有几百到几千张标注图像),不易过拟合。而 VGG-16 等大型分类 Backbone 在小数据集上容易过拟合。U-Net 的编码器可以使用在大型数据集(如 ImageNet)上预训练的 ResNet 权重作为初始化,进一步提升小数据集上的表现。

Q14. Grad-CAM 为什么选择最后一个卷积层而不是更浅的层?

最后一个卷积层在空间分辨率和语义信息之间达到最佳平衡——既有足够的空间细节(物体的大致轮廓),又有丰富的类别语义信息。 浅层(如 conv1)的激活图空间精度高但语义弱,热力图只能显示边缘和纹理等通用视觉模式,对类别没有区分性。深层(如 fc 层)有强语义但空间信息已完全丢失,无法定位。Grad-CAM 论文建议使用最后一个卷积层(对 ResNet 是 layer4),以获得既有类别区分性(语义)又有空间定位能力的热力图。

Q15. 目标检测中 One-stage 和 Two-stage 各自的适用场景是什么?

Two-stage(Faster R-CNN)适合精度优先的场景(自动驾驶、医疗影像);One-stage(SSD/RetinaNet/YOLO)适合速度优先的场景(视频监控、移动端推理)。 自动驾驶中对小物体(行人、锥桶)的召回率要求极高,且帧率要求在 15-30 FPS,通常使用 Faster R-CNN + FPN 或 Cascade R-CNN。视频监控需要实时处理大量帧,One-stage 检测器(YOLO 系列)在 30-100+ FPS 下仍能保持可接受的精度,是工业界的主流选择。实时性要求极高时,可选 YOLOv8-nano 等极致轻量模型(仅约 3M 参数)。

Q16. 为什么语义分割在物体边界处的精度通常最低?

物体边界处两类像素交错分布(背景与前景交替),特征图的感受野通常覆盖多个像素,导致边界像素的激活同时受到两侧类别的影响,难以准确分类。 同时,CNN 的多次下采样会平滑边界信息,上采样难以精确恢复。解决方向包括:使用空洞卷积保持高分辨率(DeepLabV3);在边界处使用专门的损失权重(如 boundary loss);使用 U-Net 的多尺度 Skip Connection 保留边界细节;使用 CRF(条件随机场)等后处理做边界精细化。

Q17. FCN-8s 相比 FCN-32s 精度更高的原因是什么?

FCN-8s 融合了更浅层的高分辨率特征图,这些特征图包含更精确的空间位置信息,能恢复更多边界细节。 FCN-32s 一步上采样 32 倍,信息损失严重。FCN-16s 融合 1/16 和 1/32 特征图后上采样 16 倍。FCN-8s 进一步融合 1/8 特征图,上采样仅 8 倍,空间精度最高。以 224×224 图像为例:FCN-32s 的分割图上采样 32 倍回到原始分辨率,FCN-8s 上采样 8 倍(28→224),中间差值更少,边界更精确。

Q18. Mask R-CNN 与 Faster R-CNN 的核心区别是什么?

Mask R-CNN 在 Faster R-CNN 的检测头基础上增加了并行的分割分支(Mask Head),输出每个候选区的二值分割掩码,实现实例分割。 Faster R-CNN 的检测头输出每个候选区的类别标签和边界框坐标。Mask R-CNN 在此基础上,从 RoI Align 提取的特征上并行接入一个 FCN(通常 4 个 3×3 卷积层),输出 K 个二值掩码(K 为类别数),每个掩码对应一个候选区的某个类别的像素级分割。Mask R-CNN 在 RoI Align 中使用双线性插值(替代 RoI Pooling)保证了像素级分割的空间对齐精度。

Q19. 目标检测中的 AP(Average Precision)是如何计算的?

AP 是 Precision-Recall 曲线下面积,衡量检测器在不同置信度阈值下的整体精度。 计算步骤:对所有检测框按置信度降序排列 → 按序逐一加入,绘制 PR 曲线(每个检测框要么是 TP(与 GT 的 IoU > 阈值),要么是 FP)→ AP = PR 曲线下面积。典型阈值:IoU=0.5(AP@.5)和 IoU∈[0.5:0.95](AP@[.5:.95])。COCO 数据集使用 AP@[.5:.95] 作为主要评测指标,mAP 是所有类别 AP 的平均值。

Q20. 为什么 DeepLabV3 的 ASPP 模块需要多个不同的空洞率?

不同尺度的物体需要不同的空洞率来捕捉,多个分支并行可以同时覆盖大、中、小不同尺度的语义信息。 空洞卷积的感受野公式为 k + (k-1)×(d-1)。对于 3×3 卷积核(k=3),torchvision 默认 ASPP 三个分支的空洞率分别为 d=12、d=24、d=36,对应感受野为:d=12 时 3+2×11=25,d=24 时 3+2×23=49,d=36 时 3+2×35=73。大物体(如建筑物)需要大空洞率(d=36,感受野约 73 像素)才能覆盖整体;小物体(如交通标志)需要小空洞率(d=12,感受野约 25 像素)才能保持局部精度。ASPP 通过 dilation=(12, 24, 36) 的并行分支,类似于空间金字塔池化(SPP),使网络能够同时处理多尺度的语义信息。注:原始 DeepLabV3 论文使用 (6, 12, 18),torchvision 实现调整为 (12, 24, 36),两者原理一致,只是感受野整体扩大了 2 倍。

FAQ 总结

  • RoI Align:双线性插值,消除量化误差,替代 RoI Pooling
  • Anchor + IoU:预设候选框,按 IoU 匹配真值框筛选正负样本
  • Focal Loss:自动降低易分类样本权重,解决单阶段类别不平衡
  • FCN 全卷积化:1×1 卷积替换 FC,输出空间分割图而非向量
  • 空洞卷积:dilation>1 扩大感受野,不下采样保留分辨率
  • U-Net Skip Concat:编码器特征与解码器拼接,保留空间细节
  • Grad-CAM:梯度加权特征图,可用于任意 CNN 的可解释性分析

十一、Roadmap 预告

下篇预告:《注意力机制与 Transformer:在视觉任务中超越 CNN》

从 ResNet 到 Faster R-CNN,我们见证了 CNN 在视觉任务中的强大能力。但近年来,注意力机制和 Vision Transformer(ViT)正在逐步超越传统 CNN,成为新的主流架构:

  • Vision Transformer(ViT):将图像切分为 Patch,Transformer 编码器替代 CNN 主干
  • Swin Transformer:层次化 Transformer,多尺度特征自然适配下游任务
  • DETR:端到端目标检测,Transformer 编码器-解码器架构,无需 Anchor 和 NMS
  • SegFormer:基于 Transformer 的语义分割,高效且高精度
  • CLIP / 视觉-语言模型:将视觉理解和自然语言统一建模

敬请期待!


http://www.jsqmd.com/news/1216531/

相关文章:

  • 智能开发环境架构:AI 增强的本地开发体验设计
  • 2026年7月靠谱的上海二手房买卖、借名买房、房产确权律师 - july123
  • 2026门窗密封专用TPV主流供应厂家综合评测梳理 - 奔跑123
  • 2026年7月最新长沙封窗靠谱商家综合排行全名单分享 - 奔跑123
  • Kimi LeetCode 3621. 位计数深度为 K 的整数数目 I Python3实现
  • 顶会论文的产品化落地路径:从论文伪代码到生产级Feature的工程评估体系
  • 2026年华东地区激光熔覆厂家联系方式盘点测评 - 奔跑123
  • 2026年口碑好的空气悬浮鼓风机厂家中立推荐参考指南 - 奔跑123
  • 二级市场核心认知误区全景拆解:别怕空仓、拒绝踏空焦虑,只赚确定性收益 / 会买是徒弟,会卖是师傅,会空仓才是交易祖师爷
  • 2026年7月18日更新:ChatGPT Plus / Pro 与 Codex——AI Agent 的上下文工程:为什么未来程序员竞争的是“信息组织能力”(GPT-5.6 最新技术分享)
  • 2026年高新区学生配镜现状:可靠服务商深度分析与决策指南 - 品牌鉴赏官2026
  • 2026年7月最新广东东莞主营坦克链电缆优质企业排行名录 - 奔跑123
  • 2026年唐山优秀竖炉制造厂推荐:探访唐山新拓科技有限公司 - 品牌鉴赏官2026
  • WAIC 2026 展会快讯 | 东软添翼医疗健康智能化解决方案2.0,全场景落地三甲医院内部
  • JavaScript 常用字符串方法详解(附实战代码)
  • 2026年深度体验之旅:留坝地道美食路线规划 - 品牌鉴赏官2026
  • 2026金华找寻靠谱GEO优化机构的日常经验分享 - 奔跑123
  • 2026 年新消息:锡林郭勒盟口碑好的K歌沐足整体隔音减震施工队哪家可靠,别再忍受吵闹!这套方案如何彻底拯救你的K歌体验? - 实业推荐官【官方】
  • 鸿蒙 ArkTS 实战:Menu Nutrition Advice 从智能助手到保存闭环完整解析
  • AI 电动窗帘电机智能功率 精准控制 完整选型方案
  • 浪琴官方售后服务中心地址及24小时服务电话实地考察报告_多信源验证(2026年7月最新) - 浪琴服务中心
  • 基于遗传算法的梯级水电站群联合火电厂优化调度研究(Python代码实现)
  • 2026 年武隆比较好的乳酸菌回收工厂哪家可靠,揭秘:乳酸菌回收如何颠覆你的健康投资? - 领域鉴赏官
  • 2026优选浙江家电继电器采购全场景适配指南 - 奔跑123
  • 原生JS手写轮播图(超详细保姆级教程)
  • Kimi LeetCode 3621. 位计数深度为 K 的整数数目 I JavaScript实现
  • 2026年大型化FD干燥机品牌综合实力排行盘点 - 奔跑123
  • 2026银行招聘培训优质机构推荐榜 - 互联网科技品牌测评
  • 2026 年开鲁热门的编码器组装机供应商深度解析与优选指南,揭秘!一个工具如何让你的生产效率翻倍 - 行业推荐官【官方】
  • 深圳劳力士回收价格查询和各大回收平台实测排行(2026年7月最新) - 天价名表回收平台