Original url:
https://zhuanlan.zhihu.com/p/28839889
本文收录在无痛的机器学习第二季目录。
很早以前我曾写过一篇关于CNN网络结构的文章——CNN--结构上的思考,后来在书中也提到基于ResNet思想的网络结构演变,今天就来看一看在此之后的又一股有关网络结构的思潮。如果说前面的几次网络结构的演变都是在外部进行探索,那么这一次的微创新则是聚焦于模型内部了。今天两个主角就是曾经的两大经典模型——ResNet和Inception(GoogLeNet)的后代——ResNext和Xception。
前面介绍的模型主要站在更为宏观的角度,然后不断地进入围观的世界。我们面对的数据是一个三维的张量(Tensor),它有三个维度:通道(Channel),长(Height),宽(Width)。这三个维度统一起来形成了我们要分析处理的数据。
在卷积操作爆发之前,神经网络的主要运算方式是全连接,也就是说,每一次运算过程中,输出的每一个元素都要受三个维度共同的影响(当然,一般来说全连接是没有三个维度的,这个只是做一个比方)。后来前辈们发现了卷积操作的妙用,于是大家开始广泛采用卷积操作。在卷积操作中,每一个输出的元素中,三个维度的影响力如下:
1 所有的通道
2 局部的高度
3 局部的宽度
这就是我们最初见到的卷积操作。如果用图来表示两种操作的差异,我们可以下面这张图来表示:
卷积一战成名。此后,前辈开始发明各种各样的网络,这些网络都以卷积操作作为基本操作体。于是一系列的模型结构诞生了。模型在自身规模方面有了很大的发展,终于追上了处理器(GPU)的处理速度。经过这些年的发展,架构和招式修炼到了一定境界,那么是不是该回过头来看看这个基本操作体了?
前面看到,我们发现了数据的局部相关性,所以卷积操作出现,代替了全连接的大部分工作,使得模型在能够抽取大量有用特征的同时,还能保证模型参数的精简。于是在高和宽两个维度,局部性得到了有效的验证。那么一个自然而然的问题就来了——通道信息是否也具有局部性?换句话说,在处理通道时,我们是不是也可以像处理长宽一样,不把所有的信息考虑在内,像下面这张图这样?
今天要介绍的这两个新生代模型告诉我们,这个想法是有道理的。
在ResNext模型中,作者提出了Cardinality这个概念,它表示了通道分成的组。假如说我们本来有这样一段模型结构:
此时中间的计算是经典的卷积操作,所有的通道信息合并处理,也相当于把通道分成了1组,如果想要将通道分成两组,那么运算过程中,在中间的层次,我们会得到两个结果,这两个结果分别计算,最后合并起来(concatenate)或者加和起来(sum):
对于Xception模型中,作者提出了“depth-wise separable convolution”的结构,也就是说,在做卷积计算的时候,每一个通道内的数据做单独计算,也就是说,如果有N维通道输出,那么Cardinality就等于N。
两个模型的其他方面各有异同,但思路上却十分一致,都是要对通道下手,把convolution进化成为group convolution。
前面提到了卷积之于全连接的优点,那么成组的卷积之于卷积的优点是不是类似呢?看上去是的。和全连接把所有的信息考虑在内类似,卷积操作把所有的通道信息考虑在内,也可能是一种信息浪费。我们曾经了解过,不同的卷积参数会产生不同的卷积效果,因而在不同的通道中,最终的输出结果也有所不同。但是卷积参数比较有限,产生的输出结构难免会有一定的相关性,因此将这些相关的特征放在一起考虑,有时并不一定会产生更好的效果,反而可能会造成一定程度的过拟合。因此,在通道维度做局部化的考量也是一个不错的思路。
但是随之而来的一个问题是——通道毕竟不同于长和宽,后两者有明确物理意义上的局部性,而通道的局部性却是人为想象出来的,因此这种做法难免会有些缺乏说服力,到底怎么处理通道这一维呢?
有关group conv的解决方案也在不断探索中,其中ShuffleNet做出了一定的尝试。下图是直接从它的论文中截取的,可以从图(b)中看出,在完成一次group conv之后,通道的顺序会发生一定的变化。作者并不是让相近的几个通道一直做信息的汇集,而是不断地交换相邻的通道,从某种意义上,这样得到的通道融合会更加地均匀。
看了这些论文的展示,下面我们就要认真地思考一个问题,如何更好地处理通道这个维度?显然,完全孤立各个通道和把所有通道考虑在内是走了两个极端,那么中间的状态是什么?ImageNet 2017的冠军模型SENet也对通道做了处理,它们的做法比较有趣,采用了“Squeeze-Excitation”的方法:
Squeeze操作将通道信息压缩成一个数(average pooling,相当于1阶矩),然后对这个通道汇总信息做全连接操作,得到各个通道的权重;
Excitation操作把这些权重赋给每一个通道,这种给通道加权的方式也是一种操纵通道的方式。
相信这种方法为他们最终的成功提供了帮助,但也可以看出,这种方法通过轻量级的通道与通道之间的交互来定义通道的重要程度。它所使用的信息只有一个一阶矩,如果想要做的更好是不是可以再增加一些信息呢?是不是还有别的方法呢?这些都是值得我们思考的。
我的书《深度学习轻松学:核心算法与视觉实践》,感谢支持!
我爱机器学习13群:550972653,欢迎加入~