卷积神经网络的传播过程:
step1.二维的像素图片作为输入
step2.然后进入卷积层操作:
卷积层需要一个卷积核,通过卷积核对原图进行卷积操作,然后得到一张新的图,这张新的图中的每一个点代表了输入图片中每一块区域(该区域和卷积核区域一样大)的特征。
一个的图像经过
的卷积核进行卷积得到
大小的新图片。一个卷积核作用在一张图片上形成的图片叫作feature map,不同的卷积核作用在这同一张图片上形成了不同的feature map,卷积的主要作用就是,对于图像不同区域内的像素进行特征的提取,每个像素的特征通过不能的权重进行配比,当然这些权重是需要通过Back Propagation进行调节的,每一个卷积核配备一个
的权重,和一个
。
step3.一张图片通过卷积层的卷积操作得到了很多个feature map,然后就要对这些feature map分别进行池化(pooling)操作。池化操作的主要目的是,提取图片不同区域的主要特征,并且保持了这些特征之间的的相对位置。有Max Pooling和Average Pooling,第一个是提取pool中的最大灰度,另一个是提取pool中的平均灰度。
可以看出池化操作可以非常迅速的减少feature map的维度,提取主要的特征。
step4.一定数量的feature map通过池化操作得到了很多的不同的特征图片(降维),然后需要将每一个特征图片转化为一维的向量,然后将众多的特征图片形成的一维向量按照一定的顺序连接为一个大的一维向量,此时就进入了全连接层,然后就和传统神经网络一样的,可以构建不同层数的全连接层,最后一层是输出层,起到分类的作用。
上面的四个步骤,形成了最简单的CNN一个二维的输入层,一个卷积层,一个池化层,然后是全连接层,最后是输出层。但是也可以是输入层卷积\池化层
卷积\池化层
全连接层
全连接层
输出层,同样可以设置任意多个feature map,然后每个feature map都要进行池化。
下面通过一个简单的例子来讲解CNN的FeedForward传播过程:
step1:输入图片
step2:随机初始化个卷积核
,记
,表示第一个卷积层的第
个卷积核,因此可以生成
个feature maps:
step3:假设pool的大小是,那么
个feature maps经过池化可以得到
个pooling maps:
,其中downsample表示下采样,就是池化的过程。
step4:这一步再一次的进行卷积操作,那么可以知道,前面已经有了个pooling maps,那么要进行第2次卷积操作,这次假设生成
个feature map,那么我们要做的就是用一个新的卷积核对
个pooling maps分别进行卷积,然后再将所得到的图片叠加起来,这样就形成了一个新的feature map:
,其中
表示第三层是卷积层,第
个新卷积核作用在第
个pooling map上。
step5:假设pool的大小是,那么
个feature maps经过池化可以得到
个pooling maps:
step6:进入全连接层,将这些二维向量分别展开为一维,然后在连接成一个整的特征向量作为全连接层,之后就和传统神经网络一样的FeedForward,具体过程可以参考BackPropagation算法理论详解及公式推导
Back Propagation过程,这也是CNN中最难的部分:
首先定义一些量
:表示第
层的神经元的输出值,这里不用下角标了,因为有的层的输出值是2维的有的是1维的
:表示第
层的神经元的被输出前未有归一化的权重
:表示ActivationFunction,及其导数
:表示第
层的
的误差
,这个些方程本别代表损失函数Cost,activation function激活函数,以及在全连接层,卷积层,池化层中对上一层输出参数的计算公式。
参数在不同的神经网络层中有着不同的维度和意义,在卷层中它是二维的,而在全连接层中它是一维的,而在下采用downsample的过程中是没有
参数的,
同样也有着不同的意义,但是对于一个多层的网络来说,他们的layer标号,也就是层的标号,是对它们包含意义最有力的标识。
有了上面的一些定义,就可以进入到反向传播阶段了。
1.当也就是最后一层的时候,要通过cost函数来求得
,这是所有更新的源头误差。
2.接下来进入全连接层,这一层和传统Neural Network的反向传播是一致的,可以参考BackPropagation算法理论详解及公式推导。
3.如果当前层是back propagation过程中的最后一层全连接层,那么其反向传播的下一层就是一个池化层。前面的FeedForward过程中,将每一个pooling map拆分成了一个特征向量,然后将它们有序地整合成了一个大的特征向量,现在逆向思维,将该全连接层的向量拆分成相应数量的pooling map,然后将表示为每一个pooling map的一维特征向量,还原为二维。故这就完成了全连接层到池化层的转化,其中不涉及任何的参数。
4.若层是池化层,那么
层就是一个卷积层,但是池化层的pooling map的维度要小于feature map,所以需要通过上采样(upsample)的方法得到
,现在已知条件是
,
,可以知道第一个和第三个乘数是已知的,但是不知道第二个,那么第二个乘数其实就是一个上采样(upsample)的过程。
那么这就解决了和一层的误差传递问题,但是没有涉及到参数。
5.若层是一个卷积层,那么
层可能是一个输入层,也可能是一个池化层,但是没有任何关系,因为我们的目的是为了求卷积过程中卷积核中的参数
的梯度,以及将误差传递给
层。此时的已知条件是
,
,其中第一个乘数和第三个乘数已知,那么求出
即可,但是卷积操作单求
没法求得,但是可以通过另一种卷积操作来求得
,其中要将
矩阵进行补0,使其卷积之后的大小与
层大小一致。进而得到了
层的误差。到这里,已经将误差再一次反向传播了一层,那么此时就要更新参数
了。
由我们可以知道,如果当前层
是卷积层,那么如果
层 有很多个pooling maps,那么更新本质上还是不变的就是有一些麻烦了。更新两个layer之间的权重,无非要知道两样东西,第一个是
层的误差
,第二个是
层的输出
,而就卷积的过程来说,卷积核与卷积核框住的
层区域(patch)通过按元素相乘的方式得到
层的一个元素。那么
,其中
表示第
向第
层卷积的时候,第
个卷积核对上一层的第
个图进行卷积操作用的卷积核中的权重参数。首先要知道,一张图在经过卷积之后得到的图像的维度和原图中patch在横向纵向上的个数是一致的,因此,可以用u,v来遍历
层的图像的误差(像素点坐标(u,v))和相对应的
层的一个patch,然后将它们两个相乘,就是一个数字乘以一个矩阵,而这个矩阵的大小就是这个卷积核的大小,然后相加这个卷积核对应的所有
层的pooling map,就可以得到卷积核中权重
的更新了。虽然过程非常的麻烦,但是在计算的过程中是有规律可循的,可以通过以下公式进行运算:
非常简洁。这样就完成了对
的偏导过程,一般会有很多个feature map,每一个feature map共享一个
一个
,但是
是一个一维标量,所以将
的更新设置为,该feature map的所有误差项进行求和,也就是
每一项的和。