今天在看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.
大致翻译过来:
1.png三层瓶颈结构为1X1,3X3和1X1卷积层。其中两个1X1卷积用来减少并增加(复原)维度。3X3卷积层可以看作一个更小的输入输出维度的瓶颈。
上图右侧为瓶颈——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这样的短路单元设计。推测:
- 可以对单元进行降维的特征学习,通过Bottleneck将输入的特征进行降维后的残差学习。
- 可以有效减少全连接数量,稍后给出简单推测。
- 短路的实,之前在想为什么要通过H(x) = F(x) + x这样的设计来实现短路,它的原理是什么。后来仔细想想,如果使用的是F(x) = H(x) - x这种方式的话,学习到的就不是残差对应的weight,而是原本的weight,这种编排方式实际上不是直观意义上的“短路”,而是巧妙地通过这种架构,让神经网络能够学习残差对应的weight。
关于减少全连接数量的推断:
假设没有Bottleneck的两层全连接,设一层的长宽构成的总长度为m,channel数量为dm;另一层总长为n,channel数量为dn。中间Bottleneck层总长数量为z,channel为dz。那么:
if let
then
then
上述公式是简单推导的全连接数量大小关系,FC1代表两层全连接,FC2代表含Bottleneck中间层,假设两层在FC1和FC2中完全一致,那么我们按照普通的卷积经验带入:
let
let
we get
if let and (3*3,64 channel, no padding)
we get True
通过上述简单论述我们看到使用Bottleneck设计也可以有效减少全连接数量,让神经网络更高效地前向传播计算。
以上。
网友评论