CV 中几种 Attention 机制横向对比,附 Single-Path NAS 笔记
最近读了几篇关于 CV 里 attention 机制的论文,以及一篇新出的 NAS 工作,把各自的思路整理对比一下,顺便记录一些自己的想法。
SENet:对 Channel 做加权
《Squeeze-and-Excitation Networks》的核心思路是考虑 channel 之间的相关性,在特征图后面加了一个 SE 模块——先对每个 channel 做全局平均池化(squeeze),再经过 FC 层学出每个 channel 的权重(excitation),最后用这个权重对原始 feature map 做重新标定。本质上是给不同 channel 加一个 attention。

SENet 在 ImageNet 上的分数相当高,效果很明显。
| 模型 | 224×224 top-1 err. | 224×224 top-5 err. | 320×320 / 299×299 top-1 err. | 320×320 / 299×299 top-5 err. |
|---|---|---|---|---|
| ResNet-152 [13] | 23.0 | 6.7 | 21.3 | 5.5 |
| ResNet-200 [14] | 21.7 | 5.8 | 20.1 | 4.8 |
| Inception-v3 [20] | - | - | 21.2 | 5.6 |
| Inception-v4 [21] | - | - | 20.0 | 5.0 |
| Inception-ResNet-v2 [21] | - | - | 19.9 | 4.9 |
| ResNeXt-101 (64×4d) [19] | 20.4 | 5.3 | 19.1 | 4.4 |
| DenseNet-264 [17] | 22.15 | 6.12 | - | - |
| Attention-92 [60] | - | - | 19.5 | 4.8 |
| PyramidNet-200 [77] | 20.1 | 5.4 | 19.2 | 4.7 |
| DPN-131 [16] | 19.93 | 5.12 | 18.55 | 4.16 |
| SENet-154 | 18.68 | 4.47 | 17.28 | 3.79 |
Non-local NN:对空间像素做 Self-Attention
《Non-local Neural Networks》走的是另一条思路,寻找的是 feature map 像素之间的相关性,是一种 self-attention 机制,能让每个位置的特征都和其他所有位置发生交互,捕获长程依赖。这种 attention 机制确实能取得比较好的效果。读完这篇之后,我在想能不能在 NAS 里也考虑到这方面的问题——在搜索空间里把这类 attention 操作纳入候选。

CBAM:把 Channel 和空间 Attention 串联起来
《CBAM: Convolutional Block Attention Module》可以看作是对 SE 模块的扩展,分两个部分。
Channel attention 部分: 分别做全局平均池化和全局最大池化,两路各过同一个 FC,加起来再 sigmoid,得到每个 channel 的权重。
Spatial attention 部分: 沿 channel 维度做平均池化和最大池化,把两个结果 concat 到一起,经过一个卷积层加 sigmoid,得到空间维度上的 attention map。
两个部分顺序串联,先 channel attention 再 spatial attention。

Dual Attention Network:面向分割的双路 Attention
《Dual Attention Network》是把 channel 和 feature map 空间两个维度的 attention 同时用在语义分割里,两路并联,最后融合到一起。设计思路和 CBAM 类似,只是应用场景换成了分割,两路是并联而非串联。

Single-Path NAS:把多路径搜索压缩成单路径
《Single-Path NAS: Designing Hardware-Efficient Mobile Networks》的主要思路是把多路径的操作选择都放到一个卷积核里,相当于一种比较小尺度的权值共享,从而在训练时只维护一条路径。

时间上来说也不算快,花了 30 TPU hours,直接在 ImageNet 上进行搜索,performance 中规中矩。搜索空间基于 MobileNet-v2,主要搜索 depthwise conv 的 kernel 大小。

最后搜索到的结果如下,感觉是在 follow ProxylessNAS 的工作,只不过把多路径换成了单路径。

搜索方法细节: 用了一个指示函数来确定是否使用子 kernel。
其中 是编码架构(NAS)选择的指示函数,即:若 ,则 ;否则 ,则 。
指示函数里使用了一个阈值 ,这个阈值是可学习的。原本的指示函数为:
为了让梯度能够回传,将指示函数松弛为 sigmoid:
松弛后变为:
从这个设计可以看出,是否使用某个 kernel 和权重本身密切相关,主要取决于子 kernel 之外权重的重要性。总体来说,这个方法把整个 MBConv 层泛化成了一个可搜索的 block。
最终实验效果看上去也是中规中矩。
| Method | Top-1 Acc (%) | Top-5 Acc (%) | Mobile Runtime (ms) | Search Cost (epochs) |
|---|---|---|---|---|
| MobileNetV1 [11] | 70.60 | 89.50 | 113 | – |
| MobileNetV2 1.0x [17] | 72.00 | 91.00 | 75.00 | – |
| MobileNetV2 1.0x (our impl.) | 73.59 | 91.41 | 73.57 | – |
| Random search | 73.78 ± 0.85 | 91.42 ± 0.56 | 77.31 ± 0.9 | – |
| MnasNet 1.0x [20] | 74.00 | 91.80 | 76.00 | 40,000 |
| MnasNet 1.0x (our impl.) | 74.61 | 91.95 | 74.65 | 40,000 |
| ChamNet-B [6] | 73.80 | – | – | 240‡ |
| ProxylessNAS-R [4] | 74.60 | 92.20 | 78.00 | 200* |
| ProxylessNAS-R (our impl.) | 74.65 | 92.18 | 77.48 | 200* |
| FBNet-B [21] | 74.1 | - | - | 90 |
| FBNet-B (our impl.) | 73.70 | 91.51 | 78.33 | 90 |
| Single-Path NAS (proposed) | 74.96 | 92.21 | 79.48 | 8 (3.75 hours) |