原理

当在神经网络的上下文中讨论卷积时,我们通常不是指数学文献中使用的那种标准的离散卷积运算。实际应用中的函数略有不同。这里我们详细讨论一下这些差异,并且对神经网络中用到的函数的一些重要性质进行重点说明。

首先,当提到神经网络中的卷积时,我们通常是指由多个并行卷积组成的运算。这是因为具有单个核的卷积只能提取一种类型的特征,尽管它作用在多个空间位置上。我们通常希望网络的每一层能够在多个位置提取多种类型的特征。

另外,输入通常也不仅仅是实值的网络,而是由一系列观测数据的向量构成的网络。例如,一幅彩色图像在每一个像素点都会有红、绿、蓝三种颜色的亮度。在多层的卷积网络中,第二层的输入是第一层的输出,通常在每个位置包含多个不同卷积的输出。当处理图像时,我们通常把卷积的输入输出都看作3维的张量,其中一个索引用于标明不同的通道(例如红、绿、蓝),另外两个索引标明在每个通道上的空间坐标。软件实现通常使用批处理模式,所以实际上会使用4维的张量,第4维索引用于标明批处理中不同的实例,但我们为简明起见这里忽略批处理索引。

因为卷积网络通常使用多通道的卷积,所以即使使用了核翻转,也不一定保证网络的线性运算是可交换的。只有当其中每个运算的输入和输出具有相同的通道数时,这些多通道运算才是可交换的。

假定我们有一个4维的核张量K,它的每一个元素是\(K_{i,j,k,l}\),表示输出中处于通道i的一个单元和输入中处于通道j中的一个单元的连接强度,并且在输出单元和输入单元之间有k行l列的偏置。假定我们的输入又观测数据V组成,它的每一个元素是\(V_{i,j,k}\),表示处在通道i中第j行第k列的值。假定我们的输出Z和输入V具有相同的形式,如果输出Z是通过对K和V进行卷积而不涉及翻转K得到的,那么

\[Z_{i,j,k} = \sum_{l,m,n} V_{l, j+m-1, k+n-1}K_{i,l,m,n}\]

这里对所有的l、m和n进行求和是对所有(在求和式中)有效的张量索引的值进行求和。在线性代数中,向量的索引通常从1开始,这就是上式中-1的由来。但是像C或Python这类编程语言索引通常从0开始,这使得上述公式可以更加简洁。

我们有时会希望跳过核中的一些位置来降低计算的开销(相应的代价是提取特征没有先前那么好了)。我们可以把这一过程看作对全卷积函数输出的下采样(downsampling)。如果只想在输出的每个方向上每间隔s个像素进行采样,那么我们可以定义一个下采样卷积函数c使得

\[Z_{i,j,k} =c(K, V, s)_{i,j,k} = \sum_{l,m,n} [V_{l, (j-1)\times s+m, (k-1)\times s+n}, K_{i,l,m,n}]\]

我们把s称为下采样卷积的步幅(stride)。当然也可也对每个移动方向定义不同的步幅。

在任何卷积网络的实现中都有一个重要性质,那就是能够隐含地对输出V用零进行填充(pad)使得它加宽。如果没有这个性质,表示的宽度在每一层就会缩减,缩减的幅度是比核少一个像素这么多。对输入进行零填充允许我们队核的宽度和输出的大小进行独立的控制。如果没有零填充,我们就被迫面临二选一的局面,要么选择网络空间宽度的快速缩减,要么选择一个小型的核——这两种情境都会极大得限制网络的表示能力。

有三种零填充设定的情况值得注意。第一种是无论怎样都不使用零填充的极端情况,并且卷积核只允许访问那些图像中能够完全包含整个核的位置。在MATLAB的术语中,这称为有效(valid)卷积。在这种情况下,输出的所有像素都是输入中相同数量像素的函数,这使得输出像素的表示更加规范。然而,输出的大小在每一层都会缩减。如果输入的图像宽度是m,核的宽度是k,那么输出的宽度就会变成m-k+1。如果卷积核非常大,缩减率会非常显著。因为缩减数大于0,这限制了网络中能够包含的卷积层的层数。当层数增加时,网络的空间维度最终会缩减到\(1 \times 1\),这种情况下增加的层就不可能进行有意义的卷积了。第二种特殊情况是只进行足够的零填充来保持输出和输入具有相同的大小。在MATLAB的术语中,这称为相同(same)卷积。在这种情况下,只要硬件支持,网络就能包含任意多的卷积层,这是因为卷积运算不改变下一层的结构。然而,输入像素中靠近边界的部分相比于中间部分对于输出像素的影响更小。这可能会导致边界像素存在一定程度的欠表示。这使得第三种极端情况产生了,在MATLAB中称为全(full)卷积。它进行了足够多的零填充,使得每个像素在每个方向上恰好被访问了k次,最终输出图像的宽度为m+k-1。在这种情况下,输出像素中靠近边界的部分相比于中间部分是更少像素的函数。这将导致学得一个在卷积特征映射的所有位置都表现不错的单核更为困难。通常零填充的最优数量(对于测试集的分类正确率)处于”有效卷积“和”相同卷积“之间的某个位置。

在一些情况下,我们并不是真的想使用卷积,而是想用一些局部连接的网络层(LeCun, 1986,1989)。在这种情况下,我们的多层感知机对应的邻接矩阵是相同的,但每一个连接都有它自己的权重,用一个6维的张量W来表示。W的索引分别是:输出的通道i,输出的行j和列k,输入的通道l,出入的行偏置m和列偏置n。局部连接层的线性部分可以表示为

\[Z_{i,j,k} = \sum_{l,m,n} [V_{l,j+m-1,k+n-1} w_{i,j,k,l,m,n}]\]

这有时也被称为非共享卷积(unshared convolution),因为它和具有一个小核的离散卷积运算很像,但并不横跨位置来共享参数。

当我们知道每一个特征都是一小块空间的函数并且相同的特征不会出现在所有的空间上时,局部连接层是很有用的。例如,如果想要辨别一张图片是否是人脸图像,我们只需要去寻找嘴是否在图片的下半部分即可。

使用那些连接被更进一步限制的卷积或者局部连接层也是有用的,例如,限制每一个输出的通道i仅仅是输入通道l的一部分的函数时。实现这种情况的一种通用方法是使输出的前m个通道仅仅连接到输入的前n个通道,输出的接下来的m个通道仅仅连接到输入的接下来n个通道,以此类推。对于少量通道间的连接进行建模允许网络使用更少的参数,这降低了存储的消耗以及提高了统计效率,并且减少了前向和反向传播所需要的计算量。这些目标的实现并没有减少隐藏单元的数目。

平铺卷积(tiled convolution)(Gregor and LeCun, 2010a; Le et al., 2010)对卷积层和局部连接层进行了折中。这里并不是对每一个空间位置的权重集合进行学习,我们学习一组核使得当我们在空间移动时它们可以循环利用。这意味着在近邻的位置上拥有不同的过滤器,就像局部连接层一样,但是对于这些参数的存储需求仅仅会增长常数倍,这个常数就是核的集合的大小,而不是整个输出的特征映射的大小。