卷积是一种特殊的线性运算。卷积神经网络是一种专门用来处理具有类似网格结构的数据的神经网络。
互相关函数(cross-correlation)和卷积运算几乎一样,但是并没有对核进行翻转,许多机器学习的库实现的是互相关函数但是称之为卷积。
在机器学习中,学习算法会在核合适的位置学得恰当的值,所以一个基于核翻转的卷积运算的学习算法所学得的核,是对未进行翻转的算法学得的核的翻转。单独使用卷积运算在机器学习中是很少见的,卷积经常与其它的函数一起使用,无论卷积运算是否对它的核进行了翻转,这些函数的组合通常是不可交换的。
传统的神经网络使用矩阵乘法来建立输入与输出的连接关系。参数矩阵中每一个单独的参数都描述了一个输入单元与一个输出的单元间的交互。这意味着每一个输出单元与每一个输入单元都产生交互(例如全连接层)。而卷积网络限制连接数,使其具有稀疏交互或者稀疏权重的特征,使核的大小远小于输入的大小来达到。处在网络深层的单元可能与绝大部分输入是间接交互的,这允许网络可以通过只描述稀疏交互的基石来高效地描述多个变量的复杂交互。
例如原先有m个输入和n个输出,如果矩阵乘法需要 mn 个参数,时间复杂度为 O(mn)。卷积是限制每一个输出拥有的连接数为 k,那么稀疏的连接方法只需要 kn 个参数,以及运行时间为 O(kn)。实际操作中,k比m小几个数量级,而且在机器学习中能取得较好的表现。
参数共享的定义是指在一个模型的多个函数中使用相同的参数。用于一个输入的权重也会被绑定在其他的权重上。在传统的神经网络中,当计算一层的输出时,权重矩阵的每一个元素只使用一次,当它乘以输入的一个元素后就再也不会用到了。作为参数共享的同义词,我们可以说一个网络含有绑定的权重(tiedweights),因为用于一个输入的权重也会被绑定在其他的权重上。在卷积神经网络中,核的每一个元素都作用在输入的每一位置上(是否考虑边界像素取决于对边界决策的设计)。卷积运算中的参数共享保证了我们只需要学习一个参数集合,而不是对于每一位置都需要学习一个单独的参数集合。这虽然没有改变前向传播的运行时间(仍然是O(kn)),但它显著地把模型的存储需求降低至k个参数,并且k通常要比m小很多个数量级。因为m和n通常有着大致相同的大小,k在实际中相对于mn 是很小的。因此,卷积在存储需求和统计效率方面极大地优于稠密矩阵的乘法运算。
如果一个函数满足输入改变,输出也以同样的方式改变,它就是等变的。例如:如果函数f(x)与g(x)满足f(g(x)) = g(f(x)),我们就说f(x)对于变换g具有等变性。这个特征可以说是有利有弊吧。
先看有利的地方。举个例子,令 I 为图像的亮度函数,g 为图像函数的变换函数(把一个图像函数映射到另一个图像函数的函数)使得 I’ = g(I), 这里可以假设 g 是使 I 中每个像素右移一位。同样,如果先对图像进行右移,再进行卷积操作,和先进行卷积操作,再进行右移,所得到的结果是一样的。
具体证明,可以使用傅里叶变换(可以参考知乎这篇回答 https://zhuanlan.zhihu.com/p/44769370 ),这里主要讲一下直观的理解,例如某一卷积核为了检测边缘,在图像中,各种位置均会有相似边缘,而权值共享使得在各位置出现的边缘均能被激活。总体来看,该特征与位置无关,对位置不敏感。这对于分类来说,十分有效,但对于与位置相关的任务来说,就不那么合适了,比如目标检测、语义分割等任务,我们不仅需要类别特征,更需要位置信息,平移不变性这个特性是我们不想要的,因而会采取一定的措施,弥补位置信息。
卷积的尺寸计算
out= [(input - kernel + 2 * padding) / stride] + 1
感受野计算:
感受野指的是一个特定的 CNN 特征(特征图上的某个点)在输入空间所受影响的区域。一个感受野可以用中信位置和打表来表征。然而,对于一个 CNN 特征来说,感受野中的每一个像素值并不是同等重要。一个像素点越接近感受野中心,它对输出特征的计算所起作用越大。这意味着某一个特征不仅仅是受限在输入图片中某个特定的区域(感受野),并且呈指数级聚焦在区域的中心。
其中 lk−1 为第 k−1 层对应的感受野大小, fk 为第 k 层的卷积核大小,或者是池化层的池化尺寸大小,Si是步长。
池化层的输出尺寸计算
S是步长,Ps是池化层尺寸,不同于卷积层,池化层的输出通道数不改变。
卷积层参数量计算
CNN网络的参数量和特征图的尺寸无关,仅和卷积核的大小,偏置及BN有关,对于卷积张量kernel=(K, S, C, O),权重参数量为K ∗ K ∗ C ∗ O ,偏置参数量为O,是输出特征的通道数Cout. 如果使用了BN,那么还有两个可学习参数α , β。 α,β,参数量都是O,总共2*O,综上,该卷积层所有的参数量为:
无偏执项 无 BN KxKxCxO
计算量FLOPs浮点计算量(Float Point Operations):
计算量就是统计有多少个乘法和加法运算次数,根据如下公式,整个过程就是先算输出特征图上一个元素的计算量,再乘以输出特征图元素个数即为总的计算量:
基本概念:1x1的卷积核由于大小只有1x1,所以并不需要考虑像素跟周边像素的关系,它并不改变feature map的尺寸,它能够改变的只是通道数,对不同的通道上的像素点进行线性组合,然后进行非线性化操作。
作用:
基本概念:反卷积也可以称为卷积转置或转置卷积,但其并非卷积操作的反向操作,也不会得到与原始输入一样的输出,但是却保留了映射中相对位置关系的信息,我们可以将其理解为上采样。如果我们想要网络去学出一种最优的上采样方法,我们可以使用转置卷积.它与基于插值的方法不同,它有可以学习的参数.从信息论的角度看,卷积是不可逆的.所以这里说的并不是从output矩阵和kernel矩阵计算出原始的input矩阵.而是计算出一个保持了位置性关系的矩阵。
计算公式:
正常卷积 out = [(input - kernel + 2 * padding) / stride] + 1
反卷积 out = (input -1)stride + mod - 2 padding + kernel
一些问题:使用转置卷积时会出现棋盘格伪影,棋盘状伪影是由转置卷积的“不均匀重叠”引起的。这种重叠使得更多的隐喻性绘画在某些地方比其他地方更多。
文章《Deconvolution and Checkerboard Artifacts》对这种问题进行了详细的分析,这篇文章提出了一种更好的上采样方法:首先,调整图像的大小(使用最近邻插值或双线性插值),然后做一个卷积层。通过这样做,作者避免了棋盘效应。
在这篇论文和《Multi-scale context aggregation by dilated convolutions》这篇论文中介绍了扩张卷积。
基本概念:直观上,空洞卷积是通过在卷积核部分之间插入空间(这个值一般为0)让卷积核「膨胀」。这个增加的参数 l(空洞率:超参数)表明了我们想要将卷积核放宽到多大。系统能以相同的计算成本,提供更大的感受野,扩张卷积在实时分割领域特别受欢迎。 在需要更大的观察范围,且无法承受多个卷积或更大的kennels,可以用它。
(a) 普通卷积,感受野为3×3=9;
(b) 2 - 膨胀卷积,2-dilated convolution,感受野为7×7=49;
© 4 - 膨胀卷积,4-dilated convolution,感受野为15×15=225;
综上可以发现 n - dilated convolution 的卷积核感受野为 4n-1 x 4n-1 ;
深度分离卷积降低参数量计算方法
传统卷积参数量: K × K × Cin × Cout × W × H
深度可分离卷积计算参数量:
首先将 K×K×Cout 分离为 K × K × 1 + 1 × 1× Cout
假如输入图像为 W1 × H1 × Cin
1:逐通道卷积计算量 K × K × 1 × W1 × H1 × Cin
2: 逐点卷积计算量 1 × 1× Cout × W1 × H1 × Cin
群卷积最早出现于AlexNet中。是为了解决显存不够的问题,将网络部署在两张GTX 580显卡上训练,Alex认为group conv的方式能够增加 filter之间的对角相关性,而且能够减少训练参数,不容易过拟合,这类似于正则的效果.
在AlexNet的Group Convolution当中,特征的通道被平均分到不同组里面,最后再通过两个全连接层来融合特征,这样一来,就只能在最后时刻才融合不同组之间的特征,对模型的泛化性是相当不利的。为了解决这个问题,ShuffleNet在每一次层叠这种Group conv层前,都进行一次channel shuffle,shuffle过的通道被分配到不同组当中。进行完一次group conv之后,再一次channel shuffle,然后分到下一层组卷积当中,以此循环。
传统的卷积核一般都是长方形或正方形,但MSRA提出了一个相当反直觉的见解,认为卷积核的形状可以是变化的,变形的卷积核能让它只看感兴趣的图像区域 ,这样识别出来的特征更佳。
可变形卷积是在基础卷积核的上添加一些位移量,根据数据的学习情况,自动调整偏移,卷积核可以在任意方向进行伸缩,改变感受野的范围,该位移量是靠额外的一个卷积层进行自动学习的,如下图,(a)是普通的卷积,卷积核大小为3*3,采样点排列非常规则,是一个正方形。(b)是可变形的卷积,给每个采样点加一个offset(这个offset通过额外的卷积层学习得到),排列变得不规则。(c)和(d)是可变形卷积的两种特例。对于(c)加上offset,达到尺度变换的效果;对于(d)加上offset,达到旋转变换的效果。
实际上,可变形卷积的实现非常简单。每个kernel都用两个不同的矩阵表示。第一分支学习从原点预测“偏移”。此偏移量表示要处理原点周围的哪些输入。由于每个偏移量都是独立预测的,它们之间无需形成任何刚性形状,因此具有可变形的特性。第二个分支只是卷积分支,其输入是这些偏移量处的值。
在deformable convolution中,会进行两次卷积,第一次卷积计算得到offset的卷积核,第二次是利用第一步得到的offset卷积核进行常规的卷积得到最终输出。重点是第一步中获得offset卷积核。先从input feature map中通过卷积(conv)计算得到offset field,在基于offset field得到最终的offset。注意,offset得到的输出通道数是input feature map的两倍,因为offset包含了在x和y两个方向上的偏置项。
写在最后:读了几年人工智能,发现自己对基础知识忘的差不多了,本篇是复习前面的知识,参考了很多博客,发现大佬们写的很好,有的就直接复制过来了,参考了很多博客,有的忘了贴了。
参考博客
【面试基础–深度学习】卷积及其代码实现
深度学习中的卷积网络简介