1.卷积操作实质:
输入图像(input volume),在深度方向上由很多slice组成,对于其中一个slice,可以对应很多神经元,神经元的weight表现为卷积核的形式,即一个方形的滤波器(filter)(如3X3),这些神经元各自分别对应图像中的某一个局部区域(local region),用于提取该区域的特征。如果该slice对应的神经元参数共享,那么相当于只有一个卷积核作用于所有的局部区域(类似于图像滤波了)。一个局部区域可以称为一个block,如果将所有的block拉成一个个列向量(因为神经元作用本来就定义为将输入向量和参数向量进行内积操作,y=w0x0+w1x1+...+wnxn),则我们可以得到很多这些列向量组成的局部区域数据矩阵,再将神经元的weight拉成一个个行向量,这样就得到一个参数矩阵(如果参数共享,那么该矩阵行数为slice的个数),然后将数据矩阵和参数矩阵进行点积操作,得到卷积后结果,其实就是将所有的filter和所有的局部区域分别进行点积操作,当然这个结果还需要重新reshape到期望的输出尺寸。这个过程其实也解释了为什么神经元的参数可以保存在一个个filter中,该网络层为什么称为卷积层。
下图转自https://www.zhihu.com/question/28385679
最后一页没画,但是基本上就是Filter Matrix乘以Feature Matrix的转置,得到输出矩阵Cout x (H x W),就可以解释为输出的三维Blob(Cout x H x W)。
2.经过卷积后输出图像尺寸:
假设输入图像尺寸为W,卷积核尺寸为F,步幅(stride)为S(卷积核移动的步幅),Padding使用P(用于填充输入图像的边界,一般填充0),那么经过该卷积层后输出的图像尺寸为(W-F+2P)/S+1。
3.池化
池化层通过减小中间过程产生的特征图的尺寸(下采样,图像深度不变),从而减小参数规模,降低计算复杂度,也可以防止过拟合。池化是分别独立作用于图像深度方向上的每个slice,一般使用Max操作(在一个局部区域内取最大值代表该区域),即最大池。通常池化层的空间尺寸(spatial extent)不应过大,过大会丢失太多结构信息,一般取F=3,S=2或者F=2,S=2。也有人不建议使用池化,而是在卷积层增大stride来降低图像尺寸。
4.全连接
一个神经元作用于整个slice,即filter的尺寸恰好为一个slice的尺寸,这样输出一个值,如果有n个filter,则输出长度为n的向量,一般全连接层的输出为类别/分数向量(class scores )。
5. 网络的结构
网络的一般结构为:
INPUT -> [[CONV -> RELU]*N -> POOL?]*M -> [FC -> RELU]*K -> FC
INPUT:输入
CONV:卷积层
RELU:激活函数
POOL:池化层,这里的问号表示该层是可选的
FC:全连接层
N >= 0
(通常N <= 3)
, M >= 0
, K >= 0
(通常 K < 3)
6.其他
(1)尽量使用多层fliter尺寸小的卷积层代替一层filter较大的卷积层。
因为使用多层filter较小的卷积层所能观察到的区域大小和一层filter较大的卷积层是相同的,但是前者可以看到更加抽象的特征,提取的特征表达性能更佳。
此外,前者引入的参数规模相比后者更小。比如,使用3层filter为3X3的卷积层代替1层filter为7X7的卷积层,假设输入的volume为C个通道,则前者参数
个数为3×(C×(3×3×C))=27C^2,而后者为C×(7×7×C)=49C^2,明显前者引入的参数更少。
(2)为什么使用padding?
使用padding的好处是使得卷积前后的图像尺寸保持相同,可以保持边界的信息。一般padding的大小为P=(F-1)/2,其中F为filter的尺寸。如果不使用
paddding,则要仔细跟踪图像尺寸的变化,确保每一层filter和stride正确的被使用。
(3)为什么stride一般设为1?
stride设为1实际表现效果更好,将下采样的工作全部交给池化层。
(4)输入层(input layer)尺寸一般应该能被2整除很多次,比如32(CIFAR-10),64,96(STL-10),224(common ImageNet ConvNets),384和512。
(5)尽量使用filter较小(3x3 or 至多 5x5)的卷积层,如果要使用较大的filter(比如7x7),一般也只在第一个卷积层。
(6)有时候由于参数太多,内存限制,会在第一个卷积层使用较大filter(7x7)和stride(2)(参考 ZF Net),或者filter(11x11),stride(4)
(参考 AlexNet)。