线性瓶颈是在 MobileNetV2: Inverted Residuals 中引入的。
线性瓶颈块是不包含最后一个激活的瓶颈块。
在论文的第 3.2 节中,他们详细介绍了为什么在输出之前存在非线性会损害性能。
简而言之:非线性函数 Line ReLU 将所有 < 0 设置为 0会破坏信息。根据经验表明,当输入的通道小于输出的通道时删除最后的激活函数是正确的。所以只要删除 BottleNeck 中的 nn.ReLU 即可。
首先说明一下ReLU6,卷积之后通常会接一个ReLU非线性激活,在Mobile v1里面使用ReLU6,ReLU6就是普通的ReLU但是限制最大输出值为6(对输出值做clip),这是为了在移动端设备float16的低精度的时候,也能有很好的数值分辨率,如果对ReLU的激活范围不加限制,输出范围为0到正无穷,如果激活值非常大,分布在一个很大的范围内,则低精度的float16无法很好地精确描述如此大范围的数值,带来精度损失。
本文提出,最后输出的ReLU6去掉,直接线性输出,理由是:ReLU变换后保留非0区域对应于一个线性变换,仅当输入低维时ReLU能保留所有完整信息。
在看MobileNet v1的时候,我就疑问为什么没有把后面的ReLU去掉,因为Xception已经实验证明了Depthwise卷积后再加ReLU效果会变差,作者猜想可能是Depthwise输出太浅了应用ReLU会带来信息丢失,而MobileNet还引用了Xception的论文,但是在Depthwise卷积后面还是加了ReLU。在MobileNet v2这个ReLU终于去掉了(非紧邻,最后的ReLU),并用了大量的篇幅来说明为什么要去掉(各种很复杂的证明,你不会想自己推一遍的= =,从理论上说明了去掉ReLU的合理性)。
总之,结论就是最后那个ReLU要去掉,效果更好。
参考:
https://blog.csdn.net/deephub/article/details/124684557#t3