卷积神经网络是一个多层的神经网络,每层由多个二维平面组成,而每个平面由多个独立神经元组成。
图:卷积神经网络的概念示范:输入图像通过和三个可训练的滤波器和可加偏置进行卷积,滤波过程如图一,卷积后在C1层产生三个特征映射图,然后特征映射图中每组的四个像素再进行求和,加权值,加偏置,通过一个Sigmoid函数得到三个S2层的特征映射图。这些映射图再进过滤波得到C3层。这个层级结构再和S2一样产生S4。最终,这些像素值被光栅化,并连接成一个向量输入到传统的神经网络,得到输出。
每个层有多个Feature Map,每个Feature Map通过一种卷积滤波器提取输入的一种特征,然后每个Feature Map有多个神经元。
CNN一个牛逼的地方就在于通过感受野和权值共享减少了神经网络需要训练的参数的个数,所谓权值共享就是同一个Feature Map中神经元权值共享,该Feature Map中的所有神经元使用同一个权值。因此参数个数与神经元的个数无关,只与卷积核的大小及Feature Map的个数相关。但是共有多少个连接个数就与神经元的个数相关了,神经元的个数也就是特征图的大小。卷积层的参数计算:
卷积后feature map边长: outputSize =(originalSize + paddingX2 - kernelSize)/ stride + 1 (其中outputSize是卷积之后得到的feature map的边长,originalSize是输入图的边长,padding是填充的大小,kernelSize是卷积核的边长,stride是步长)
卷积层的可训练的参数个数: trainNum = (outputSize X outputSize + 1) X kernelNum (其中kernelNum是卷积核的个数,加1是因为每一个卷积核有一个bias参数)
卷积层的连接数: connectNum = (kernelSize X kernelSize) X (outputSize X outputSize) X kernelNum
卷积层的神经元个数: neuralNum = (outputSzie X outputSize) X kernelNum下采样层的参数计算:
下采样后map的边长: outputSize =(originalSize + paddingX2 - kernelSize)/ stride + 1 (其中outputSize是卷积之后得到的feature map的边长,originalSize是输入图的边长,padding是填充的大小,kernelSize是卷积核的边长,stride是步长)
下采样层可训练的参数个数: trainNum = (1+ 1) X kernelNum (其中kernelNum是卷积核的个数)
下采样层的连接数: connectNum = (kernelSize X kernelSize) X (outputSize X outputSize) X kernelNum
下采样层的神经元个数: neuralNum = (outputSzie X outputSize) X kernelNum
下面以最经典的LeNet-5例子来逐层分析各层的参数及连接个数。
- C1层是一个卷积层,由6个特征图Feature Map构成。特征图中每个单元与输入为5x5的邻域相连。特征图的大小为28x28,这样能防止输入的连接掉到边界之外(32-5+1=28)。C1有156个可训练参数(每个滤波器5x5=25个unit参数和一个bias参数,一共6个滤波器,共(5x5+1)x6=156个参数),共(5x5) x (28x28) x 6=117600个连接。
- S2层是一个下采样层,有6个14x14的特征图。特征图中的每个单元与C1中相对应特征图的2x2邻域相连接。C1层每4个输入相加,乘以一个可训练参数,再加上一个可训练偏置得到S2中的一个单元。每个单元的2*2感受野并不重叠,因此S2中每个特征图的大小是C1中特征图大小的1/4(行和列各1/2)。S2层有12(6x(1+1)=12)个可训练参数和4704(14x14x2x2x6=4704)个连接。
- C3层也是一个卷积层,它同样通过5x5的卷积核去卷积S2层,然后得到的特征map就只有10x10个神经元,但是它有16种不同的卷积核,所以就存在16个特征map了。
C3中每个特征图由S2中所有6个或者几个特征map组合而成。为什么不把S2中的每个特征图连接到每个C3的特征图呢?原因有2点。第一,不完全的连接机制将连接的数量保持在合理的范围内。第二,也是最重要的,其破坏了网络的对称性。由于不同的特征图有不同的输入,所以迫使他们抽取不同的特征(希望是互补的)。
例如,存在的一个方式是:C3的前6个特征图以S2中3个相邻的特征图子集为输入。接下来6个特征图以S2中4个相邻特征图子集为输入。然后的3个以不相邻的4个特征图子集为输入。最后一个将S2中所有特征图为输入。这样C3层有1516(6x(3x25+1) + 6x(4x25+1) + 3x(4x25+1) + (25x6+1)=1516)个可训练参数。- S4层是一个下采样层,由16个5x5大小的特征图构成。特征图中的每个单元与C3中相应特征图的2x2邻域相连接,跟C1和S2之间的连接一样。S4层有32个可训练参数(每个特征图1个因子和一个偏置16x(1+1) =32)和2000(16x2x2x5x5=1600)个连接。
- C5层是一个卷积层,有120个特征图。每个单元与S4层的全部16个单元的5x5邻域相连。由于S4层特征图的大小也为5x5(同滤波器一样),故C5特征图的大小为1x1(5-5+1=1):这构成了S4和C5之间的全连接。之所以仍将C5标示为卷积层而非全相联层,是因为如果LeNet-5的输入变大,而其他的保持不变,那么此时特征图的维数就会比1x1大。C5层有48120(120x(16x5x5+1)=48120由于与全部16个单元相连,故只加一个偏置)个可训练连接。
- F6层有84个单元(之所以选这个数字的原因来自于输出层的设计),与C5层全相连。有10164(84x(120x(1x1)+1)=10164)个可训练参数。如同经典神经网络,F6层计算输入向量和权重向量之间的点积,再加上一个偏置。然后将其传递给sigmoid函数产生单元i的一个状态。
- 最后,输出层由欧式径向基函数(Euclidean Radial Basis Function)单元组成,每类一个单元,每个有84个输入。
图:卷积和子采样过程:卷积过程包括:用一个可训练的滤波器fx去卷积一个输入的图像(第一阶段是输入的图像,后面的阶段就是卷积特征map了),然后加一个偏置bx,得到卷积层Cx。子采样过程包括:每邻域四个像素求和变为一个像素,然后通过标量Wx+1加权,再增加偏置bx+1,然后通过一个sigmoid激活函数,产生一个大概缩小四倍的特征映射图Sx+1。
- feature map的每个点都是一个神经元的输出。所以 神经元个数 = feature map的维数
- 可训练参数个数, 与神经元的个数无关,只与卷积核的大小及卷积核的个数相关,还有通道数
神经元个数, 除了卷积核大小和个数,还与步幅相关。步幅越大,神经元个数越小- 卷积后得到的feature maps边长的计算公式是:
outputSize =(originalSize_h + padding*2 - kernelSize)/ stride + 1