看论文看到 densenet,结构图里一个模块内每层都和后面所有层连线,像一团毛线。这就是它的核心设计:Dense Block 里每一层的输入,是前面所有层输出的拼接。
和 ResNet 的关键差别
ResNet 把前面层的输出加到当前层上,是元素级相加;densenet 换成沿通道维度拼接。别小看这个改动:浅层的边缘、纹理信息可以被深层直接取用,不用靠网络重新学一遍;梯度也能沿捷径直接流回前面,深网络难训练的问题被进一步缓解。
几个名词一次记住
- growth rate 增长率:每个新层产出多少个新通道,论文里常见取值 12 到 32,特征图按这个数线性增长;值越大模型越肥,精度收益却边际递减,一般从小值试起
- bottleneck 结构:先 1x1 卷积降维,再做 3x3 卷积,带这个设计的版本叫 DenseNet-BC
- transition 层:两个 Dense Block 之间用 1x1 卷积加池化压缩特征,DenseNet-BC 的压缩因子是 0.5,通道数直接砍半
以 DenseNet-121 为例,4 个 Dense Block 依次包含 6、12、24、16 层,加上开头卷积、过渡层和分类层凑成 121 个带权重层。torchvision 里指定 densenet121 就能加载预训练权重,输入按 224 尺寸准备,数据增强用随机裁剪加水平翻转这套常规操作就够,迁移学习换掉最后的分类头直接用。
它的优势在小数据集上很明显:达到相近精度时参数量比 ResNet 系少一截。代价是显存吃得多,中间特征图都要留着拼接,batch size 开不大。实际取舍:数据量不大、想充分复用特征的项目,用 densenet 调参很舒服;显存紧张的大规模训练,ResNet 系反而更省心。