一、CNN的基本结构

首先我们来看CNN的解百纳结构,一个常见的图像识别CNN模型如下图:
CNN模型
从图中可以看出最左边的图像就是模型的输入层,在计算机中就是若干个矩阵,这点与DNN类似。

接着是卷积层(Convolution Layer),这个层是CNN特有的,卷积层的激活函数是ReLU,该函数其实很简单,公式为: R e L U ( x ) = m a x ( 0 , x ) ReLU(x) = max(0, x) ReLU(x)=max(0,x)。在卷积层后面是池化层(Pooling Layer),这也是CNN特有的网络结构,池化层是没有激活函数的。

卷积层+池化层的组合可以在隐藏层中出现多次,在上图的结构中出现了两次。实际上他们出现的次数可以根据模型的需要调整。当然我们也可以灵活搭配各种结构,如卷积层+卷积层、卷积层+卷积层+池化层,这些在构建模型时没有限制。但是最常见的CNN结构是若干卷积层+池化层的组合。

在若干卷积层+池化层后面是全连接层(Fully Connected Layer,简称FC),全连接层实际上就是DNN的结构,输出层采用的是Softmax层做图像的分类。

从CNN的结构可以看出,CNN相对于DNN,比较特殊的就是卷积层和池化层,只要把卷积层和池化层的原理搞清楚,那么搞清楚CNN就很容易了。

二、CNN的卷积层

举个例子如下,图中的输入是一个二维的34的矩阵,卷积核是一个22的矩阵。这里我们假设卷积核每次移动一格,具体的卷积过程如下:

  1. 计算输入层左上角2*2局部和卷积核的卷积,也就是各个位置的元素相乘再相加,得到输出矩阵S的 S 00 S_{00} S00的值,即 a ω + b x + e y + f z a\omega + bx +ey + fz +bx+ey+fz
  2. 将输入的局部向右平移一格,现在是 ( b , c , f , g ) (b, c, f, g) (b,c,f,g)四个元素与卷积核的卷积,这样得到了输出矩阵S的 S 01 S_{01} S01的值。
  3. 将这个22的矩阵在输入矩阵上遍历后,就能得到输出矩阵S的结果,S是一个二维的23矩阵。
    在这里插入图片描述

上面的例子是二维的输入,卷积的过程比较简单,那么如果输入是多维的呢?比如输入是一个335(3代表彩色图像的RGB三个色道)的矩阵,那么我们该如何取卷积呢?

在斯坦福大学的csn231n的课程上,有一个动态的例子,三维向量的卷积动态图,可以参照动态来理解。

对于三维输入,卷积核也相应的变成三维矩阵,其它的卷积过程与二维输入类似。如果我们最终只想或一个二维的输出矩阵,用一个三维卷积核即可。上图中的卷积核是两个,最终产生两个二维的输出矩阵。

三、CNN中的池化层

相比卷积层的复杂,池化层要简单的多,所谓的池化,就是对输入张量的各个子矩阵进行压缩。假如是22的池化,就是将子矩阵的每22个元素变成一个元素;如果是33的池化,那么将子矩阵的每33个元素变成一个元素,这样输入矩阵的维度就变小了。

要想将输入子矩阵的每n*n个元素变成一个元素,那么需要有一个池化标准。常见的池化标准有2个,MAX和Average,即取限定区域内的最大值或均值作为池化后的元素值。

下面的例子采用取最大值的池化方法,采用的池化大小是2*2,步幅是2

首先对红色22区域进行池化,由于此22区域的最大值是6,那么对应的池化位置输出值也就是6,由于步幅是2,此时移动到绿色的位置进行池化,输出的最大值是8,最终,我们的输入44的矩阵在池化后变成了22的矩阵。
在这里插入图片描述

四、CNN的前向传播

根据上面对CNN的模型结构的总结,在此基础上,我们看看CNN的前向传播是怎样的。

4.1 输入层前向传播到卷积层

输入层的前向传播是CNN前向传播算法的第一步,一般输入层对应的都是卷积层,这里还是以图像识别为例。

先考虑最简单的情况,样本都是二维的黑白图片。这样输入层 X X X就是一个矩阵,矩阵的值等于图片的各个像素位置的值,此时的卷积核 W W W就是矩阵。前向传播的过程可以表示为: a 2 = σ ( z 2 ) = σ ( a 1 ∗ W 2 + b 2 ) a^2=\sigma(z^2)=\sigma(a^1*W^2+b^2) a2=σ(z2)=σ(a1W2+b2)
其中,上标代表网络层数,星号代表卷积,b代表偏倚向量, σ \sigma σ是激活函数,这里一般都是ReLU。

和DNN的前向传播比较,其实形式是非常像的,只是我们这里是张量的卷积,不是矩阵的乘法。同时由于 W W W是张量,那么同样的位置, W W W参数的个数比DNN多了很多。

这个过程中需要定义的CNN模型参数是:

  1. 一般我们的卷积核不止是一个,比如有K个,那么我们输入层的输出就会有K个。
  2. 卷积核中每个子矩阵的大小,一般我们都用子矩阵为方阵的卷积核,比如F*F的子矩阵。
  3. 填充padding(以下简称P),我们卷积的时候,为了更好的识别边缘矩阵,一般都会在输入矩阵周围加上若干圈的0再进行卷积,加多少圈则P为多少。
  4. 步幅stride(以下简称S),即在卷积过程中每次移动的像素大小。

4.2 隐藏层前向传播到池化层

池化层的处理逻辑较为简单,我们的目的就是对输入的矩阵进行缩小概括。比如输入的矩阵是 N ∗ N N*N NN维的,而我们的池化大小是 k ∗ k k*k kk的区域,则输出的矩阵都是 N k ∗ N k \frac{N}{k}*\frac{N}{k} kNkN维的。

在这里需要定义的CNN模型参数是:

  1. 池化区域的大小k
  2. 池化的标准,一般是Max或者Average

4.3 CNN前向传播算法过程

有了上面的基础,我们现在总结下CNN的前向传播算法。
输入:1个图片样本,CNN模型的层数L和所以隐藏层的类型,对于卷积层,要定义卷积核的大小K,卷积核子矩阵的维度F,填充大小P,步幅S。对于池化层,要定义池化区域大小和池化标准(MAX或Average),对于全连接层,要定义全连接层的激活函数(输出层除外)和各层的神经元个数。
输出:CNN模型的输出 a L a^L aL
1)根据输入层的填充大小P,填充原始图片的边缘,得到输入张量 a 1 a^1 a1
2)初始化所有隐藏层的参数 W W W b b b
3) f o r l = 2 t o L − 1 : for l =2 to L-1: forl=2toL1:
    a)如果第 l l l层是卷积层,则输出为 a l = R e L U ( z l ) = R e L U ( a l − 1 ∗ W l + b l ) a^l = ReLU(z^l) = ReLU(a^{l-1}*W^l+b^l) al=ReLU(zl)=ReLU(al1Wl+bl)
    b)如果第 l l l层是池化层,则输出为 a l = p o o l ( a l − 1 ) a^l = pool(a^{l-1}) al=pool(al1),这里的 p o o l ( ) pool() pool()指按照池化区域大小 k k k和池化标准将输入张量缩小的过程
    c)如果第 l l l层是全连接层,则输出为 a l = σ ( z l ) = σ ( W l a l − 1 + b l ) a^l = \sigma(z^l) = \sigma(W^la^{l-1}+b^l) al=σ(zl)=σ(Wlal1+bl)
4)对于输出层第L层:
a L = s o f t m a x ( z L ) = s o f t m a x ( W L a L − 1 + b L ) a^L = softmax(z^L) = softmax(W^La^{L-1}+b^L) aL=softmax(zL)=softmax(WLaL1+bL)
以上就是CNN前向传播算法的过程总结。

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐