Deep Learning

Bottleneck

2018-09-30  本文已影响3654人  __main__

今天在看ResNet的时候想看看代码,碰到个Bottleneck_v1函数,看了半天不知道干啥的。不过本来就是没看完论文就来看代码,看不懂、理解不了,也算是给自己的愚蠢找了借口了。


各种查询bottleneck,也出现了各种各样的说法,也就在这里梳理一下查到的和所思考的。
原文对于Bottleneck Architecture的描述如下:

The three layers are 1X1, 3X3, and 1X1 convolutions, where the 1X1 layers are responsible for reducing and then increasing(restoring) dimensions, leaving the 3X3 layer a bottleneck with smaller input/output dimensions.

大致翻译过来:

三层瓶颈结构为1X1,3X3和1X1卷积层。其中两个1X1卷积用来减少并增加(复原)维度。3X3卷积层可以看作一个更小的输入输出维度的瓶颈。

1.png

上图右侧为瓶颈——Bottleneck架构设计,实际上描述的很形象,但是为什么要这么设计呢?然后找到一篇论文:https://pdfs.semanticscholar.org/de8d/30f9c59be0c235ae2de7da77993e54f9f91f.pdf?_ga=2.123500427.1832799503.1538275568-288142727.1538275568

没看完,就看了一小段对于Bottleneck设计的描述,其中有这么一句话:

Bottleneck features are most commonly used in an autoencoder which the neural network is trained to predict the input features themselves.

翻译过来就是:

Bottleneck设计主要用于自编码(AutoEncoder),其中深度网络被训练成用于预测输入特征它们自己(用输入特征,预测输入特征,什么鬼)。

姑且不论具体什么意思,我们看下面两张图片:


2.png P$C1BTOE5O(T4`PY9H~J@}0.png

最上面带猫的图片是具体的实现路线,下一张代表的是具体的神经网络架构。可以看到架构就呈现了一种Bottleneck的样子。


那么什么是unpooling和deconvolution呢?

反池化:池化的逆向操作,在实际池化过程中记录点的位置(比如maxpooling记录最大点的位置),然后还原,其余位置填充0。

反卷积:卷积的逆向操作,事实上就是增加了padding操作的卷积,卷积后恢复原来大小尺寸。

AutoEncoder自编码是一种数据压缩法。看上去也像,事实上我们也可以通过那张名字乱七八糟的图看出,通过压缩把特征缩放到低纬度之后,可以更有效、直观地进行数据的训练和特征提取。


那么根据上述的种种启发,我们可以得知到一些为什么要做Bottleneck这样的短路单元设计。推测:

  1. 可以对单元进行降维的特征学习,通过Bottleneck将输入的特征进行降维后的残差学习。
  2. 可以有效减少全连接数量,稍后给出简单推测。
  3. 短路的实,之前在想为什么要通过H(x) = F(x) + x这样的设计来实现短路,它的原理是什么。后来仔细想想,如果使用的是F(x) = H(x) - x这种方式的话,学习到的就不是残差对应的weight,而是原本的weight,这种编排方式实际上不是直观意义上的“短路”,而是巧妙地通过这种架构,让神经网络能够学习残差对应的weight。

关于减少全连接数量的推断:
假设没有Bottleneck的两层全连接,设一层的长宽构成的总长度为m,channel数量为dm;另一层总长为n,channel数量为dn。中间Bottleneck层总长数量为z,channel为dz。那么:

FC1 = m*dm*n*dn
FC2 = m*dm*z*dz + n*dn*z*dz

if let FC1>FC2
then m*n*dm*dn > z*dz*(m*dm+n*dn)
then z*dz < \frac{m*n*dm*dn}{m*dm+n*dn}

上述公式是简单推导的全连接数量大小关系,FC1代表两层全连接,FC2代表含Bottleneck中间层,假设两层在FC1和FC2中完全一致,那么我们按照普通的卷积经验带入:

let m = n = 768
let dm = dn = 256
we get z*dz < \frac{768*256*758*256}{768*256*2}
z*dz < 98304
if let z = 254 and dz = 64 (3*3,64 channel, no padding)
we get 16256 < 98304 True

通过上述简单论述我们看到使用Bottleneck设计也可以有效减少全连接数量,让神经网络更高效地前向传播计算。

以上。

上一篇 下一篇

猜你喜欢

热点阅读