李宏毅机器学习笔记-10 卷积神经网络(Convolutional Neural Network-RNN)
Convolutional Neural Network(CNN)
1 为什么用 CNN 识别图像
1.1 使用 DNN 的缺陷
-
当我们用一般的全连接神经网络处理图像时,可能是这样子:
第一层识别一些最基础的线条、特定方向的边界等等之类的最基本的模式。
第二层就开始基于第一层的基础识别一些复杂一些的模式。
往后的层以此类推,直至识别出一个预期中的目标。
是我们这样直接处理的话,往往参数会太多,处理一张100*100像素的图 像就需要几千万个参数。
基于上述原因,所以我们要尽可能的去简化 Neural Network 的参数。根据我们的一些知识,去掉网络中的一些没用的 weight。这就是 CNN 要做的事情。
1.2 为什么可以使用 CNN
所以其实 CNN 是简化了全连接的神经网络。那为什么我们可以进行这种简化呢?
-
原因1: 在做图像识别的时候,就像我们在前面讲过的,神经网络的每一层完成的是不同的任务,识别的模式由简单到复杂。也就是说,我们并不是每识别一个模式都要查看整张图,大多数特征只要看图片的一小部分就行了。
-
原因2: 同样的一个模式可能会在图片的不同区域出现,而我们并不需要对不同区域中的模式都训练出一组参数 去检测。反之,我们只需要同一组参数重复使用就可以了。
-
原因3: 我们可以对一张图片做 重采样(subsample)。比如说把一张图片的奇数行和偶数列拿掉,使图片变为原来的 ,但是并不会影响人对这样图片的理解,除了尺寸变小以外,我们不会觉得跟原来的图片有什么区别。根据这点我们可以使神经网络的参数大大减少。
2 CNN 的步骤
- 对图像做 Convolution(卷积);
- (可选)对图像做 Max Pooling(池化);
- 以上两个步骤重复 N 次。(N 要提前决定好)。
- 将处理完的图像 一维展开(Flatten);
- 丢进一个全连接神经网络进行学习。
如下图,
其中,Convolution 处理的就是我们在前面 1.2 中讲的 原因1 和 原因2。Max Pooling 处理的就是 原因3 。
以上是 CNN 的操作步骤,但是具体怎么做?我们继续往下。
3 CNN – Convolution(卷积)
3.1 卷积是什么
-
首先让我们先来看一下卷积操作是怎么进行的,假设我们有一张 6*6 的图片,然后定义一些 Filter(滤波器,也叫作卷积核),如下图。
在真正的应用中,Filter 的值是要我们去学习出来的,但是在这里我们假设已经知道了。
-
卷积过程: 对于上图的 Filter 1 来说,我们将其对准图像左上角的 3*3 的区域,计算其与 Filter 1 的 内积(就是逐元素相乘再相加),然后将 Filter 向右移动 stride(这个例子中 stride=1,但是也可以是其他值) 距离,再做内积,一行结束就换到下一行的左边,如此循环直至遍历整张图片。每个 Filter 都做上述的操作。
每个 Filter 得出来的内积组合成一个 4*4 的矩阵,这些矩阵我们叫做 Feature Map(特征图)。这些 Filter 实质上识别的是图片上一些特定方向的纹理或者是边界等等之类的东西。具体为什么能够识别,这里就不详细说明了(我也不太懂)。
-
彩色图片的卷积操作: 因为彩色图片的每一个像素是由 3 个值表示的,所以每一次进行卷积的 Filter 也得 3 个,从一个矩阵变成了一个立方体。如下图:
3.2 卷积跟神经网络有什么关系
-
上面说了那么多,那到底卷积跟我们的神经网络之间有什么关系呢?
- 卷积中的图片对应的就是神经网络中输入的图片,当然在神经网络中输入的是经过 Flatten 过的一维向量。
- 卷积中的 Filter 对应的是神经网络中的 weight,与 Filter 做卷积的区域对应的就是输入连接的 weight 就是 Filter 中对应的值。
- 卷积中计算出来的每一个 内积 对应着 一个神经元的输出,一个 Feature Map 就是一个 hidden layer 的输出。
如果用一句话概括的话,那么卷积对应的神经网络就是一个全连接网路拿掉了其中的某些 weight。也就是 CNN。
3.3 CNN 参数为什么比较少
- 为什么说这样子参数会比较少呢?这个东西有点难解释,我们先把输入的图片变成一个一维的向量,然后当卷积进行第一次内积计算时,相当于把对应的 9 个输入连到一个神经元上,其 weight 就等于 filter 中的值。如下图。观察下图你会发现,相较于全连接的网络,其参数数量减少了非常多。
- 我们接着做第二次卷积运算,还是跟上面一样的操作,把对应的输入连接到一个新的神经元。乍一看我们增加了 9 个weight,但是其实这 9 个 weight 和上一个神经元的 weight 是一样的!也就是说 我们并没有增加更多的参数。
-
所以,我们通过:
- 让连接到一个神经元的输入变少(或者说让全连接网络中一些 weight 为0);
- 强制让不同的输入(或者不同的神经元)共享一些相同的 weight;
来使得神经网络中的参数数量大大的减少。
那如果要去自己训练CNN,该怎么做呢?就是将一些 weight 设为 0,永远都不改变,这就做到了上面的第一个要求。那第二个要求,就是当我们算出 gradient 时,把那些要分享同一个 weight 的输入的 gradient 加起来,然后求平均就可以了。(不过我们一般不会自己亲手去做这个)。
4 Max Pooling(池化)
-
首先,将 convolution 做出来的 Feature Map 进行分组,如下图,每 4 个分成一组。
-
然后只保留每一组里最大的值(或者平均值,或者其他你自己的处理方法)。于是我们成功的把图片缩小到了 2*2 的大小。图片的个数(深度)是 Filter 的个数。
-
需要说明的一点是,因为 (Convolution - Max Pooling)这个过程可以重复进行。比如说上面输出了一个 2 * 2 * 2 的立方体图像,下一次要做卷积时,需要的 filter 的尺寸也得是一个立方体,以此类推。
5 Flatten(展开)
-
这个过程没什么好说的,就是把上面处理后的图像转换成一个向量,然后丢进一个神经网络中就好了。