跳到主要内容

捷径的另外三种形态 — SENet、DenseNet、DPN

这一章讲三件事: 给通道装权重(SENet)、把加法换成拼接(DenseNet)、 两路并联取长补短(DPN)。读完你会拿到一个统一视角:捷径进化史就是 「信息该原样搬运、还是该加工后再传」的争论史——而这个争论到 DPN 才分出高下。

1. 这一章讲什么

第 03 章把「直通捷径」钉死了。但捷径这条路远没有走到头,这一章连讲三个后续:

  • SENet(2017 年 ILSVRC 收官冠军)问:所有通道一视同仁,合理吗?——让网络自己给 每个通道打个分;
  • DenseNet 问:捷径只传上一层,太浪费了——把前面所有层都接过来,而且用拼接 不用加法;
  • DPN 问:加法和拼接到底谁对?——把两个网络翻译成同一种语言,发现它们根本不是 对手,是互补的同事。

2. 顶层全景:三种捷径并排看

残差块: x ──►[卷积]──┐
└────────────⊕──► 相加:原样 + 加工(第 03 章)

SE 块: 特征图 ──►[压成 C 个数]──►[两层全连接]──► C 个权重 ──►逐通道乘
(不是捷径,是给每个通道调音量)

DenseNet: x0 ──►[卷积]──► x1 ──►[卷积]──► x2 ──► …
└────┴─────────┴────► 每层都把前面所有层的输出【拼接】进来

图说:三种形态各管一件事——残差管「深得下去」,SE 管「该听谁的」,
Dense 管「别丢任何前辈的原始产出」。

主走查走 SE 块:拿一张 56×56×256 的特征图(ResNet-50 中段的典型尺寸,数是我们取的 代表值),看着它怎么被压缩成 256 个数、再被还原成 256 个权重、最后乘回去。3.1 节走全程。

3. 核心原理

3.1 SENet:给每个通道配一个音量旋钮

SE 解决的问题是:卷积出来的各通道特征,重要程度其实不一样,但网络把它们平权对待。

SENet 的核心思想是「建模通道之间的依赖关系」:让网络为每一个通道学习一个权值—— 这种「自己给自己算权重」的机制,行话叫注意力(第 09、10 章会见到它的完整形态)1

SE 块分两步,压缩(squeeze)与激发(excitation)2:

主走查:一张 56×56×256 的特征图走进 SE 块

├─ ① 压缩:对每个通道整张求平均 → 256 个数(每个数概括一张 56×56 图)
│ 「粗糙但是全局」——书里对这步的定义就是拿到全局信息嵌入[^yasuo]

├─ ② 激发:256 → 16 → 256(两层全连接,中间夹 ReLU,出口用 sigmoid)
│ 得到 256 个 0~1 之间的权重;中间层宽度 r=16 是论文给的值[^r16]
│ (这些权重例如 0.9, 0.1, 0.7, … 为演示编的;结构不是)

└─ ③ 逐通道乘回原特征图:重要通道近原音量,不重要通道被压低

激发步骤为什么敢用两层全连接?书里给了两条设计要求:要足够适配(学出的权重要有 代表性),要足够简单(别把训练拖慢)3。而且通道之间是「非排他」的—— 激励重要的、抑制不重要的,可以同时发生4

这一步便宜得惊人。 书里算了三笔账(ResNet-50 对比 SE-ResNet-50;账的单位是 FLOPS——衡量乘加次数的 计数单位,1 GFLOPS 即十亿次):计算量 3.86 GFLOPS 只多了约 0.01 GFLOPS(十亿分之一量级的开销,对照是同量级的 GFLOPS 总账); 运行时间 190ms 变 209ms,多 10%;参数多约 250 万(也是约 10%),而且把最后几层的 SE 块省掉,参数只多 4%5。另一个反直觉的细节:如果直接把特征图摊平成 几万个数再接全连接,效果其实更好——但书里解释了 SENet 不这么干的原因: 「全连接操作往往是整个网络结构的性能瓶颈」[xingneng]。设计不是选最准的,是选最划算的。

书里还给了两个理解角度:SE 块学的是每个特征图的「动态先验」;它就是沿着通道方向做的 自注意力——注意力机制的本质也是学一组权值6。作者本人的延伸思考也值得记: 浅层其实更需要 SE 块,深层可以换成更便宜的版本7

3.2 DenseNet:把「加」换成「拼」,把「一层」换成「所有层」

残差捷径只连上一层,DenseNet 觉得亏:**低层学出的边缘、纹理,到深层就被加工得面目全非, 为什么不把原始版直接送到每一层?**书里的动机表述:如果目的是让信息「毫无阻碍地传播, 那么残差网络的堆叠残差块便不是信息流通最合适的结构」8

结构上的两个变化:

  1. 全接:每个密集块里,第 l 层的输入是「这个块中前面所有层的输出拼接后的结果」9; 一个 L 层的网络要加 L(L−1)/2 条捷径;
  2. 拼接代替相加:相加会把两组数搅在一起、分不出彼此;拼接是把两组数首尾排成 更长的一串,原样保留10

全接会让通道数越滚越大,DenseNet 用两个阀门控制:

阀门做法书里的值
成长率 k每层只新增 k 个通道,第 l 层输入 = k0+k×(l−1) 维论文 k=12
DenseNet-B每层先 1×1 压到 4k,再 3×3 出 k瓶颈结构
压缩层块与块之间把通道数乘 θ(θ<1 即 DenseNet-C)θ=0.5

(成长率与 4k 瓶颈见1112;压缩层与 θ 见13。)

代价书里写得直白:DenseNet 要在内存里保存密集块每个节点的输出,极大规模的 DenseNet 需要极大的显存——所以工业界的主流至今依旧是残差网络14。 它的优点同样三条:信息流通更顺畅、支持特征重用、网络更窄15。 一句话:准确率的逻辑赢了,工程的逻辑输了。

3.3 DPN:把两个网络翻译成同一种语言

DPN(双路网络)做了全书第一篇里最漂亮的一次统一推导。它引入高阶 RNN——RNN (循环神经网络:按先后次序一步一步往前算的网络,第 09 章的主角)的高阶版本—— 作为公共语言,把残差网络和 DenseNet 都翻译过去,然后读出三条结论16:

  1. 拼接再 1×1 卷积,等价于分组各做 1×1 卷积再求和——两种操作在数学上是近亲17;
  2. 高阶 RNN 里特征提取与聚合的权重是共享的,DenseNet 的各层参数不共享—— 不共享,意味着「DenseNet 具有产生新的特征的能力」18;
  3. 若把 DenseNet 的参数也改成共享,它「将退化为残差网络,也就是说残差网络是一种 特殊形式的 DenseNet」19

翻译完,优缺点自动浮出水面:残差网络「复用了前面网络提取的特征」,每层特征原封不动 往下传,冗余度低、但没有新东西;DenseNet 每层都重新加工前辈的输出,可能反复提取 「前面的层已经提取过的特征」,擅长造新特征、冗余度高20

DPN 的答案:双路并联。以残差路为主体保证低冗余,「添加一个非常小的 DenseNet 分支, 用于生成新的特征」21;工程细节也照着两路的脾气各自安排——两路共享第一个 1×1 卷积, 3×3 用分组卷积,残差路的通道数刻意多于 DenseNet 路,防止后者的通道膨胀过快、显存涨太快22。 DPN 由此拿下 2017 年 ILSVRC 物体定位任务的冠军23

判断(我们的,不是书里的): DPN 这章真正的遗产不是那个冠军,而是论证姿势—— 两个「竞争架构」先翻译成同一种表示,差异往往自动显形为「同一个旋钮的两个档位」。 这比「跑分比大小」高级得多。后来第 04 章之后的所有网络对比(ShuffleNet 对 Xception、 RegNet 对 ResNeXt)用的都是这个思路的变体。 如果错,会错在: 如果两个架构的差异根本不在参数共享这一个自由度上, 统一表示就可能把真正的原因翻译丢了;书里的推导对「通道如何增长」这个方面是简化的。

4. 作者的判断与证据

书里给了实验证据的: SE 的三笔账(GFLOPS/时间/参数,ResNet-50 对照)与「最后几层 SE 块可省」;DenseNet 的显存代价是结构事实推论;DPN 的「残差=特殊 DenseNet」 是一条数学证明(书里给了完整推导)。

作者的推测(书里明说): 「浅层更需要 SE 块」来自作者对论文复杂性分析的延伸, 属个人思考;DPN 的改进方向(更多分支、按深度配权)也是作者的展望,论文没有实现24

5. 边界与局限

  • SE 块的压缩方式是全局平均池化——「粗糙但是全局」;书里明确说换成别的方法也行, 只要保住全局性,所以后来各种 SE 变体层出不穷,本书不展开;
  • DenseNet 的显存墙在今天部分被「共享内存实现」缓解,但书成稿时的工程结论 (主流仍是残差)至今没有翻盘;
  • DPN 之后,「残差 vs 密集」之争被更轻的分组卷积接棒(第 06 章)—— 通道洗牌解决的正是 DPN 里那两组 1×1 卷积的沟通问题。

6. 可带走的

  1. 通道不是生而平等的:给每个通道配一个可学习的权重,只用 0.01 GFLOPS 就能涨点—— 这是「注意力」第一次在本书出场,形式是调音量;
  2. SE 块两头小中间宽(r=16)的两层全连接,是「又适配又简单」的折中样板;
  3. 相加混合信息,拼接保留信息;想让后辈看到前辈的原始输出,用拼接(DenseNet);
  4. 全接网络要用成长率和瓶颈阀门控制通道膨胀,否则显存先炸;
  5. 残差网络是参数共享版的 DenseNet——复用便宜,生成贵;两者并联(DPN)曾同时拿住 两边的优点;
  6. 「先翻译成同一种语言再比优劣」是分析竞争架构的通用招数;
  7. 设计的取舍对象不只是精度:SE 选了「不是最准但最便宜」的压缩方式,这是工程判断 压过理论最优的实例。

7. 原文地图

主题原书节原文位置
SENet 动机与通道权重1.5 注意力:SENettext/03-p41-60.txt:278(搜「建模通道之间」) · text/03-p41-60.txt:279(搜「为每一个通道学习一个权值」)
压缩-激发两步、易嵌入1.5 注意力:SENettext/03-p41-60.txt:280(搜「squeeze」) · text/03-p41-60.txt:283(搜「非常容易地嵌入」)
压缩=全局信息嵌入1.5.1 SE 块text/03-p41-60.txt:305(搜「全局信息嵌入」)
激发的两条要求、非排他1.5.1 SE 块text/03-p41-60.txt:316(搜「要足够简单」) · text/03-p41-60.txt:317(搜「非排他」)
r=161.5.1 SE 块text/03-p41-60.txt:325(搜「这个值是 16」)
两种理解、自注意力1.5.1 SE 块text/03-p41-60.txt:331(搜「动态先验」) · text/03-p41-60.txt:332(搜「特征图维度的自注意力」)
三笔复杂度账1.5.3 SENet 的复杂性分析text/03-p41-60.txt:355(搜「0.01GFLOPS」) · text/03-p41-60.txt:356(搜「209ms」) · text/03-p41-60.txt:359(搜「最后几层的 SE 块可以省掉」)
全连接瓶颈1.5.3 SENet 的复杂性分析text/03-p41-60.txt:351(搜「性能瓶颈」)
作者三点思考1.5.4 小结text/03-p41-60.txt:369(搜「感兴趣区域池化」) · text/03-p41-60.txt:374(搜「浅层更需要 SE 块」)
DenseNet 动机1.6 更密:DenseNettext/03-p41-60.txt:384(搜「无阻碍地传播」) · text/03-p41-60.txt:390(搜「拼接在一起」)
全接与拼接1.6.1 DenseNet 算法解析text/03-p41-60.txt:407(搜「前面所有层的输出拼接」)
成长率、DenseNet-B1.6.1 DenseNet 算法解析text/03-p41-60.txt:445(搜「成长率」) · text/03-p41-60.txt:428(搜「4k」)
压缩层、DenseNet-C1.6.2 压缩层text/03-p41-60.txt:452(搜「压缩层有降维和降采样两个」) · text/03-p41-60.txt:455(搜「DenseNet-C」)
显存墙与主流1.6.3 小结text/03-p41-60.txt:483(搜「极大的显存」) · text/03-p41-60.txt:481(搜「支持特征重用」)
DPN 融合与冠军1.7 模型集成:DPNtext/03-p41-60.txt:495(搜「双路网络」) · text/03-p41-60.txt:498(搜「特征的生成」) · text/03-p41-60.txt:499(搜「物体定位任务的冠军」)
拼接等价分组求和1.7.1 高阶 RNNtext/03-p41-60.txt:522(搜「再求和的操作」)
参数共享与退化关系1.7.1 高阶 RNNtext/03-p41-60.txt:523(搜「权值是共享的」) · text/03-p41-60.txt:538(搜「特殊形式的 DenseNet」)
复用 vs 冗余1.7.1 高阶 RNNtext/03-p41-60.txt:569(搜「复用了前面网络提取的特征」) · text/03-p41-60.txt:572(搜「已经提取过的特征」)
DPN 工程细节1.7.2 DPN 详解text/03-p41-60.txt:581(搜「非常小的 DenseNet 分支」) · text/03-p41-60.txt:596(搜「引发显存」)
作者展望1.7.3 小结text/03-p41-60.txt:611(搜「更多种类的网络分支」)

[xingneng]: 出处:「1.5.3 SENet 的复杂性分析」(text/03-p41-60.txt:351,搜「性能瓶颈」)。原文:「而且采用这种方式得到的 s 的效果往往优于采用 SE 块的策略得到的。但是 SENet 没这么做,原因是……全连接操作往往是整个网络结构的性能瓶颈」。

Footnotes

  1. 出处:「1.5 注意力:SENet」(text/03-p41-60.txt:279,搜「为每一个通道学习一个权值」)。

  2. 出处:「1.5 注意力:SENet」(text/03-p41-60.txt:280,搜「squeeze」)。原文:「一个 SE 块包括压缩(squeeze)和激发(excitation)两个步骤」。

  3. 出处:「1.5.1 SE 块」(text/03-p41-60.txt:315,搜「要足够适配」)与(text/03-p41-60.txt:316,搜「要足够简单」)。

  4. 出处:「1.5.1 SE 块」(text/03-p41-60.txt:317,搜「非排他」)。

  5. 出处:「1.5.3 SENet 的复杂性分析」(text/03-p41-60.txt:355,搜「0.01GFLOPS」)、(text/03-p41-60.txt:356,搜「209ms」)与(text/03-p41-60.txt:359,搜「最后几层的 SE 块可以省掉」)。

  6. 出处:「1.5.1 SE 块」(text/03-p41-60.txt:331,搜「动态先验」)与(text/03-p41-60.txt:332,搜「特征图维度的自注意力」)。

  7. 出处:「1.5.4 小结」(text/03-p41-60.txt:374,搜「浅层更需要 SE 块」)。

  8. 出处:「1.6 更密:DenseNet」(text/03-p41-60.txt:384,搜「无阻碍地传播」)。

  9. 出处:「1.6.1 DenseNet 算法解析及源码实现」(text/03-p41-60.txt:407,搜「前面所有层的输出拼接」)。

  10. 出处:「1.6 更密:DenseNet」(text/03-p41-60.txt:390,搜「拼接在一起」)。原文:「DenseNet 是将不同层的输出拼接在一起,而不是残差网络中的单位加操作」。

  11. 出处:「1.6.1 DenseNet 算法解析及源码实现」(text/03-p41-60.txt:445,搜「成长率」)与(text/03-p41-60.txt:446,搜「k 维的特征向量」)。

  12. 出处:「1.6.1 DenseNet 算法解析及源码实现」(text/03-p41-60.txt:428,搜「4k」)。原文:「先使用 1 × 1 卷积将输入数据降维到 4k,再使用 3 × 3 卷积提取特征……这种结构被定义为 DenseNet-B」。

  13. 出处:「1.6.2 压缩层」(text/03-p41-60.txt:452,搜「压缩层有降维和降采样两个」)与(text/03-p41-60.txt:455,搜「DenseNet-C」)。

  14. 出处:「1.6.3 小结」(text/03-p41-60.txt:483,搜「极大的显存」)。

  15. 出处:「1.6.3 小结」(text/03-p41-60.txt:481,搜「支持特征重用」)。

  16. 出处:「1.7 模型集成:DPN」(text/03-p41-60.txt:495,搜「双路网络」)。

  17. 出处:「1.7.1 高阶 RNN、DenseNet 和残差网络」(text/03-p41-60.txt:522,搜「再求和的操作」)。

  18. 出处:「1.7.1 高阶 RNN、DenseNet 和残差网络」(text/03-p41-60.txt:523,搜「权值是共享的」)与(text/03-p41-60.txt:526,搜「产生新的特征的能力」)。

  19. 出处:「1.7.1 高阶 RNN、DenseNet 和残差网络」(text/03-p41-60.txt:538,搜「特殊形式的 DenseNet」)。

  20. 出处:「1.7.1 高阶 RNN、DenseNet 和残差网络」(text/03-p41-60.txt:569,搜「复用了前面网络提取的特征」)与(text/03-p41-60.txt:572,搜「已经提取过的特征」)。

  21. 出处:「1.7.2 DPN 详解」(text/03-p41-60.txt:581,搜「非常小的 DenseNet 分支」)。

  22. 出处:「1.7.2 DPN 详解」(text/03-p41-60.txt:595,搜「分组卷积」)与(text/03-p41-60.txt:596,搜「引发显存」)。

  23. 出处:「1.7 模型集成:DPN」(text/03-p41-60.txt:499,搜「物体定位任务的冠军」)。

  24. 出处:「1.7.3 小结」(text/03-p41-60.txt:611,搜「更多种类的网络分支」)。