DenseNet(全称 Densely Connected Convolutional Networks)是由 Gao Huang 等人在 2016 年提出,并在 CVPR 2017 获得最佳论文奖的卷积神经网络架构。它的核心思想是 在同一块(dense block)内部让每一层都直接接收所有前面层的特征图,并把自己的特征图再传递给后续所有层,实现特征的高效复用。
论文链接:https://arxiv.org/pdf/1608.06993.pdf
代码的github链接:https://github.com/liuzhuang13/DenseNet
1. 关键组成模块
模块 | 作用 | 典型实现 |
---|---|---|
Dense Block | 将块内每一层的输出 按通道维度拼接(concatenation)后作为后续层的输入,实现特征重用。每层通常采用 BN‑ReLU‑Conv 结构,常配合 bottleneck(1×1 卷积) 以降低计算量。 | |
Growth Rate (k) | 每层新增的特征图数量。若块内有 L 层,则块的输出通道数为 initial_channels + L·k ,控制模型宽度。 |
|
Transition Layer | 位于相邻 dense block 之间,用 1×1 卷积 + BatchNorm + 平均池化 将特征图数目压缩(compression),防止通道爆炸并实现下采样。 | |
Bottleneck‑&‑Compression (DenseNet‑BC) | 在每个 dense layer 前加入 1×1 卷积(bottleneck),并在 transition 中使用压缩率 < 1(常取 0.5),显著降低参数量和 FLOPs。 |
2. 设计优势
- 特征复用:每层都能直接使用前面所有层的特征,避免信息丢失,提升表达能力。
- 梯度流畅:密集连接形成多条短路,缓解梯度消失,使得非常深的网络也易于训练。
- 参数高效:由于特征共享,DenseNet 在保持或提升精度的同时,参数量往往只有 ResNet 的 1/3–1/4(如 DenseNet‑121 约 8 M 参数 vs ResNet‑50 的 25 M)。
- 更好的特征传递:拼接而非相加保留了所有通道信息,适合后续的特征融合或注意力机制。
3. 常见变体与规模
变体 | 参数量 | 典型增长率 (k) | 说明 |
---|---|---|---|
DenseNet‑121 | 7.9 M | 32 | 4 个 dense block,常用作 ImageNet 骨干网络 |
DenseNet‑169 | 14 M | 32 | 增加了第 3 块的层数,提高了特征表达 |
DenseNet‑201 | 20 M | 32 | 更深的网络,适合大规模数据 |
DenseNet‑BC(如 DenseNet‑121‑BC) | 8 M 左右 | 12–24 | 采用 bottleneck + 压缩,参数更紧凑 |
4. 性能表现(ImageNet)
模型 | 参数量 | Top‑1 准确率 | Top‑5 准确率 |
---|---|---|---|
ResNet‑50 | 25.5 M | 76.3 % | 92.3 % |
DenseNet‑121 | 7.9 M | 75.8 % | 92.3 % |
DenseNet‑121 (官方 PyTorch) | 7.98 M | 74.4 % | 91.9 % |
DenseNet‑169 | 14 M | 76.2 % | 92.9 % |
虽然在 Top‑1 上略低于 ResNet‑50,但 参数仅为其约 1/3,在资源受限的场景(移动端、嵌入式)表现更具优势。
5. 典型应用场景
- 图像分类:CIFAR‑10/100、ImageNet 等基准数据集的主干网络。
- 医学影像:如肺部 X‑光、皮肤病变检测等,利用特征复用提升小样本学习效果。
- 目标检测 & 语义分割:在 Faster‑RCNN、Mask‑RCNN、U‑Net 等框架中常把 DenseNet 作为特征提取器,以获得更细粒度的特征图。
- 跨模态任务:结合注意力或 Transformer,DenseNet 的稠密特征有助于视觉‑语言对齐。
6. 实现要点(以 PyTorch 为例)
import torch.nn as nn
from torchvision.models import densenet121
model = densenet121(pretrained=True) # 直接加载 ImageNet 预训练权重
# 关键属性
print("参数量:", sum(p.numel() for p in model.parameters())/1e6, "M")
# 输出特征维度
x = torch.randn(1, 3, 224, 224)
logits = model(x)
print(logits.shape) # torch.Size([1, 1000])
- growth_rate 与 num_init_features 可在
torchvision.models.densenet
的源码中自行调节,以构建自定义规模的 DenseNet。 - 若需 压缩(DenseNet‑BC),在构造
DenseBlock
时使用bn_size=4
(bottleneck)并在Transition
中设置compression=0.5
。
7. 小结
DenseNet 通过 密集连接 实现了特征的高效复用和梯度的顺畅传播,在 参数紧凑、计算高效 的同时保持了与主流网络相当的识别性能。它已成为 图像任务的常用骨干网络,并在医学影像、目标检测、语义分割等多个领域得到广泛应用。若在资源受限或需要更强特征表达的场景,选择 DenseNet‑BC 系列往往是一个兼顾精度与效率的理想方案。
声明:文章均为AI生成,请谨慎辨别信息的真伪和可靠性!