资讯专栏INFORMATION COLUMN

【机器学习基础】卷积神经网络(CNN)基础

番茄西红柿 / 3296人阅读

摘要:而在卷积神经网络中,这两个神经元可以共用一套参数,用来做同一件事情。卷积神经网络的基本结构卷积神经网络的基本结构如图所示从右到左,输入一张图片卷积层池化层卷积层池化层展开全连接神经网络输出。

最近几天陆续补充了一些“线性回归”部分内容,这节继续机器学习基础部分,这节主要对CNN的基础进行整理,仅限于基础原理的了解,更复杂的内容和实践放在以后再进行总结。


卷积神经网络的基本原理 

  前面对全连接神经网络和深度学习进行了简要的介绍,这一节主要对卷积神经网络的基本原理进行学习和总结。

  所谓卷积,就是通过一种数学变换的方式来对特征进行提取,通常用于图片识别中。

  既然全连接的神经网络可以用于图片识别,那么为什么还要用卷积神经网络呢?

0.使用卷积神经网络的理由

(1)首先来看下面一张图片:

  在这个图片当中,鸟嘴是一个很明显的特征,当我们做图像识别时,当识别到有“鸟嘴”这样的特征时,可以具有很高的确定性认为图片是一个鸟类。

  那么,在提取特征的过程中,有时就没有必要去看完整张图片,只需要一小部分就能识别出一定具有代表的特征。

  因此,使用卷积就可以使某一个特定的神经元(在这里,这个神经元可能就是用来识别“鸟嘴”的)仅仅处理带有该特征的部分图片就可以了,而不必去看整张图片

   那么这样就会使得这个神经元具有更少的参数(因为不用再跟图片的每一维输入都连接起来)。

(2)再来看下面一组图片:

 上面两张图片都是鸟类,而不同的是,两只鸟的“鸟嘴”的位置不同,但在普通的神经网络中,需要有两个神经元,一个去识别左上角的“鸟嘴”,另一个去识别中间的“鸟嘴”:

  但其实这两个“鸟嘴”的形状是一样的,这样相当于上面两个神经元是在做同一件事情

  而在卷积神经网络中,这两个神经元可以共用一套参数,用来做同一件事情

(3)对样本进行子采样,往往不会影响图片的识别。

  如下面一张图:

  假设把一张图片当做一个矩阵的话,取矩阵的奇数行和奇数列,可看做是对图片的一种缩放,而这种缩放往往不会影响识别效果。

  卷积神经网络中就可以对图片进行缩放,是图片变小,从而减少模型的参数。

1.卷积神经网络的基本结构

  卷积神经网络的基本结构如图所示:

  从右到左,输入一张图片→卷积层→max pooling(池化层)→卷积层→max pooling(池化层)→......→展开→全连接神经网络→输出。

  中间的卷积层和池化层可以重复多次。后面会一一介绍每一层是如何工作的。

  对于第0部分的三个功能:

  (1)某个神经元只需侦测某一部分的图片,来识别某种特征这个工作是在卷积层内完成的。

  (2)具有相同功能的神经元共用一套参数,这个工作也是在卷积层内完成的。

  (3)通过缩小图片,来减少模型的参数,这个工作是在池化层中完成的。

  稍后会解释上面三个部分是如何进行的。

1.1.卷积层的工作原理

  假设有一张6*6的黑白图片,如图所示:

  首先图片经过卷积层,卷积层有一组filter每个filter用来抓取图片中的某一种特征,如图所示:

  假设filter是3*3的矩阵,每个filter有9个参数,而这些参数就是通过训练学习得到的,这里假设我们已经学习得到了上面一组参数的值。

  因此也就说明了问题(1)中,每一个filter只侦测图片中的很小一部分数据。

  那么每个filter是如何去抓取特征的呢?也就是(1)中使某一个神经元只侦测一部分图片就能提取某一种特征的问题。

  首先看filter1,filter大小为3*3,那么相当于这个filter1依次从左到右去覆盖整张图片,然后与覆盖区域做内积,如图所示:

  首先从左上角开始,覆盖图片左上角3*3的区域,计算结果得到3,然后向右移动,这里移动的步长称之为stride当stride为1时,即一次移动一格,为2时,一次移动两格,如图所示:

  移动之后再次用图片被覆盖的区域与filter做内积,得到第二个值:

  依次进行移动和计算,当移到最右边尽头时,则从下一行开始继续移动,最终得到如图所示矩阵:

  通过观察这个filter1可以看出,filter1的对角矩阵全为1其他为-1那么对于图片中对角为1的部分,与filter1做内积后的值就会很大(例子中等于3),其他的则会很小。

  因此filter1是一种用于侦测对角都为1的图片这种属性,在图片中可以看到,坐上角和右下角都具有这种特征。

  所以这也就说明了(2)中的问题,一个filter的一组参数,可以侦测到图片中两个位置的相同属性。

  接下来是第二个filter,filter2,那么filter2与图片的计算方式一模一样,如图所示:

  其他的filter也是如此,依次计算,然后把每个filter处理结果放在一起,如图所示:

  那么相当于一个红色方框现在是由2个值来描述的,最终得到的是2个4*4的图片,称之为“feature map”。

  上面是对于一张黑白的图片进行一次卷积(convolution)的过程,那么对于彩色的图片是怎样处理的呢?

  彩色图片通常是由“RGB”组成,分别表示红色、绿色和蓝色,那么就相当于有三个部分的组成,如图所示:

  这三个层称之为“通道”(channel),那么利用卷积处理这种图片时,filter也应该是三层,即3*3*3的,是带有深度的,长下面这个样子:

  相当于每个filter具有27个参数

卷积与全连接网络的关系

  其实卷积就是一种特殊形式的全连接网络,还是假设是上面那张6*6的图片,如下是全连接的网络结构:

  把图片进行拉直展开,但在卷积中,这个网络有些连接的地方被切断了,只有一部分输入与神经元相连接。下面进行解释:

  正如上面的卷积过程,如下是其中的一步,如图所示:

  那么这个步骤我们可以想象成是这样子的:

  左边把图片的36个数值拉直,然后,对于filter1所覆盖的区域为左上角,那么元素对应的位置为1、2、3、7、8、9、13、14、15

  然后这9个数值,依次经过各自的weight相乘再相加,得到第一个值3,这里的weight就是对应的filter中各个位置的值,图中weight线的颜色与filter中圆圈颜色一一对应

  到这里就很清楚的看出卷积与全连接之间的关系,相当于简化了全连接神经网络,从而使得参数量更少

  然后filter开始向右移动一格(stride=1,上面计算过程的第二个方框,元素依次为2、3、4、8、9、10、14、15、16),与filter做inner product,得到结果-1,对应到全连接网络中如图所示:

  依旧是每个元素的weight与输入输出连接,颜色对应的filter圆圈与weight的颜色一致。

  从上面的图可以看出,两个神经元(3和-1)都是通过filter1作为weight与输入进行连接的,也就是说,这两个神经元是共用同一组参数,这样,在上面减少参数的基础上,使得模型的参数更少了

  上述过程就是卷积层的工作过程,主要用于图片中特征的抓取,完成第0节内容的前两个。

1.2池化层的工作原理

  池化层的作用上面说了,就是为了图片的缩放,那么池化层是如何进行缩放的呢?

  其实池化层的原理很简单,这里以max-pooling为例,经过卷积层之后的图片变为4*4大小的图片,有2个filter,也就是两张4*4的图片:

  池化就是将上面得到的数据进行分组,如图所示:

  如图示中的分组方法,这种分组方法可以是任意的,也可以三个一组等等,然后取每个组中的最大值:

  那么原来4*4的图片经过maxpooling之后就缩小为2*2的图片了,当然这里也不一定非要取最大值,也可以取平均,或者又取平均又取最大值等。

  那么上面的过程总结一下就可以用如下图进行概括:

 

  这就是池化层的工作原理,比较简单。

1.3Flatten和全连接层

  接下来就来到了flatten和全连接层了,flatten的作用就是把上面得到的两个2*2的image拉直展开,然后再丢进全连接网络中计算就可以了,这个跟前面全连接神经网络的方法一样,如图所示:

  这里就不再详细赘述了。那么整个网络就是利用梯度下降的方法进行训练的,所有的参数被一起学习得到。

2.使用Keras对CNN的简单实现

  这里还是使用keras对CNN的建模过程进行一个简单的实现,首先先来看一下keras分别添加卷积层和池化层的过程:

  如图中所示,首先要导入Convolution2D(后来这个接口会改成Conv2D)和Maxpooling2D。

  然后与之前神经网络中一样,不过是把“Dense”换成了上面两个方法,其中Convolution2D中,25表示filter的数量,3,3表示filter的尺寸,input_shape为输入图片的大小,28*28为图片大小,1表示黑白图片,3则表示彩图“RGB”

  Maxpooling2D中只有分组的形状,即2*2大小的。

  接下来就是根据设计的网络的形状,重复上面两个步骤,完成卷积和池化。如图所示:

  图中黑色的方框为代码的实现内容,在keras1.0和2.0中可能有些差异;

  黄色的框中是输入和输出的尺寸大小,可以看到,输入为28*28的图片,经过25个3*3的filter组成的第一个卷积层之后,变成了25*26*26的尺寸

  然后经过第一个2*2的池化层,缩小后的输出尺寸大小为25*13*13

  然后经过第二个由50个3*3的filter之后,输出变为50*11*11

  之后经过第二个2*2的池化层后,缩小后的输出尺寸变为50*5*5(这里由于输入为基数,最后一格就忽略掉了)。

  而在卷积层中,filter的参数数量是在变化的,在第一个卷积层的参数为3*3=9个,这个比较好理解;

  而在第二个卷积层中,参数就变成了225个,这是因为上一层的输出为25*13*13大小的图片,这时是带有channel的(就相当于一开始输入为RGB时,通道数为3)当使用3*3的filter进行处理时,需要带有深度25,因此每个filter的参数数量为25*3*3=225。

  然后就是经过Faltten和fully-connection了,这个与之前的神经网络一致:

  然后就可以对模型进行训练了。这里要注意的是,这里的输入跟全连接有所不同,要把输入图片数据转化为(28,28,1)的格式。完整代码如下:

from sklearn.datasets import fetch_openmlfrom sklearn.preprocessing import OneHotEncoderfrom sklearn.model_selection import train_test_splitimport numpy as npfrom keras import Sequentialfrom keras.layers import Densefrom keras.layers import Activationfrom keras.layers import Convolution2D, MaxPooling2D, Flattendata_x, data_y = fetch_openml(mnist_784, version=1, return_X_y=True)x = []for i in range(len(data_x)):    tmp = data_x.iloc[i, :].tolist()    tmp = np.array(tmp).reshape((28, 28, 1))    x.append(tmp)x = np.array(x)one_hot = OneHotEncoder()data_y = one_hot.fit_transform(np.array(data_y).reshape(data_y.shape[0], 1)).toarray()train_x, test_x, train_y, test_y = train_test_split(x, data_y)model2 = Sequential()model2.add(Convolution2D(25, 3, 3, input_shape=(28, 28, 1)))model2.add(MaxPooling2D((2, 2)))model2.add(Convolution2D(50, 3, 3))model2.add(MaxPooling2D((2, 2)))model2.add(Flatten())model2.add(Dense(units=100))model2.add(Activation(relu))model2.add(Dense(units=10))model2.add(Activation(softmax))model2.compile(optimizer=adam, loss=categorical_crossentropy, metrics=[accuracy])model2.fit(train_x, train_y, batch_size=300, epochs=20)

最后的输出如下:

3.CNN都学到了啥?

  通过CNN的原理我们大致知道,CNN的卷积是不断提取特征的过程,池化是对图片的缩放,那么究竟CNN学习到了什么呢?如下面一张图:

  给机器一张图片,那么对人来说,这张图片是一双鞋,而对机器来说,它可能认为是是美洲狮,因为图中的鞋标有一只美洲狮。

  因此,我们想要知道CNN究竟学习到了啥,下面介绍几种方法来查看CNN都在侦测什么特征的方法。

3.1 直接查看filter

  前面我们说到,filter就是为了抓取某一种特征的,那么我们是不是可以看一下这些filter分别都是侦测什么样的特征的。

  根据CNN的原理,随着网络越来越靠近输出层,那么这一层所学习到的东西就越来越抽象,不太容易观察。因此,我们选取第一个卷积层的filters来看一下。

  对于一个训练好的模型,将第一个卷积层的filters多带带拿出来,并画出来,如图所示:

  上面一共96个filter,每个filter的大小为11*11,从filter我们可以看出,上面几排的filter主要是侦测形状特征的,下面几排的filter主要是侦测色彩特征的。

  我们也可以通过多带带看一个filter,然后把图片依次输入的CNN中,看哪些图片经过这个filter后的输出(Activate)最大,如下图所示:

  白色的框表示filter,这里白色的框看着很大,主要是因为这个filter比较靠后,也就是它所看到的是前面经过缩小后的输入,因此框就会变得很大。

  第一排的图片中的框是一个filter1,可以看到,这个filter对于脸部的侦测比较强;

  第二排的框是另一个filter2,可以看到filter2侦测的主要是洞状排列的特征;

  第三排的filter3则是侦测红色的特征;

  以此类推...

3.2 特征的可视化

  这种方法是查看特征的,也就是说使用反卷积、反池化的方法,来可视化输入图像的激活特征。

  还用原理部分那个CNN结构的例子,如下图左边的结构:

                           

  在第二个卷积层中,假设第k个filter,它与输入作用以后得到的结果如上图中右侧,每一个元素aij,然后把aij相加,即为ak,即:

  那么现在我们想要通过输入x使得ak最大,也就是找一张图片x,使得ak的输出最大,即:

这里就要利用gradient ascent的方法去找这个最大值了,即求:

  就相当于原先经过卷积、池化过程,现在要将x当做未知量,反过来求反池化、反卷积去求解出一个使得ak最大的x注意这里x并不是真正的图片了,相当于是通过反池化和反卷积所得到的的带有一些特征的图像);

  具体原因就在于反池化和反卷积的求解过程,无法还原为原先的图片,这里暂不过多介绍如何反池化和反卷积的原理,后续再补充。

  那么经过上面的步骤,还原得到的x的结果如图所示:

   一共50个filter,这里取前12个,每个图片的意思代表1个filter所还原得到的图片x,也就是说,比如第一张图片,将其作为input丢进上面那个网络后,其输出与第一个filter作用后得到的ak最大。

  仔细观察一下上面的图,还是有一定的规律可循的。

  同时我们也可以去查看fully-connection部分的神经元,原理跟上面一样,不过再求解释时又多了一层反向传播的过程,如图:

  当然也可以去拿输出层的神经元,比如识别结果为0,输出层在第0维值就很大,然后一样根据上面的原理得到的结果如图:

  会发现得到的结果什么也看不到,但是当把某张图片再次输入进网络之后,得到的确实是对应的结果。

  这也就说明了深度学习很容易被欺骗,但从侧面也反映出了,深度学习确实学习到了某些特征,并非仅仅简单“记住”数据,也说明深度学习的“玄学”性,难以解释

  当然,在上面的求解过程中,我们可以适当加一些限制,比如正则化:

  那么得到的结果如图:

  发现结果稍微清晰了一些,有些能够看到一些笔画。

  那么正则化的目的是在保证y越大越高的同时,也要使得xij(图片中的每一个pixel)越小越好,也就是说对于图片显示(白色的是笔画,黑色的是空白)时,尽可能使空白减少,能连的连起来。所以效果会好些。

3.3 微分

  对于一张图片的识别,我们可以计算类别y对图像像素pixel的微分的值:

  通过改变像素xij,来看这个像素对识别的影响是否重要,也就是说,当xij稍微做一下改变,对识别的结果影响有多大,用这样的方法可以得到如下的结果:

  白色区域表示对识别影响较为重要的pixel,可以大概看到一些形状。那这样做有什么意义呢?

  有时当我们从网上爬取图片进行建模后,发现对马的识别率很高,但对其他的识别一般,这是因为可能关于“马”的图片都包含“horse”字样的标签,机器真正识别到的是“horse”的标签,而并非知道马长什么样子。

  同样的道理,我们可以通过盖住图片的一部分,去看看盖住的部分结果的影响有多大,比如:

  图中灰色的区域是被盖住的,不断移动灰色的区域,看对结果的影响有多大,那么可以获取到下面一样的热力图:

  图中颜色越浅表示对辨识的结果影响越大,越不能辨别出是什么,可以看到,第一张当盖住狗的脸的时候,很难分辨出狗;

  第二张图片当盖住轮胎部分的时候,就很难辨别出轮胎;

  第三张图片当盖住狗的身子的部分,就很难辨别出狗了。

  更多有关CNN可视化的内容,可搜索一些有关博客进行学习:https://blog.csdn.net/xys430381_1/article/details/90413169

4.关于CNN一些有趣的应用

  根据上面的理论,我们可以通过修改某个filter的参数,去还原出一张另类的图片,比较有趣的应用有deep dream和风格迁移,如下图(图片来源于网络):

这里就暂时不具体介绍原理了,后面会找一些开源的项目去玩。

 

参考资料:台大李宏毅《机器学习-卷积神经网络》


 

上面是对CNN进行的一个初步的介绍,后面会对深度学习部分进行系统的学习和整理,这里主要是对原理有个初步的认识,因此很多都是概念性的东西,后续会进一步添加补充。

 

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/125103.html

相关文章

  • 机器学习

    摘要:用离散信一文清晰讲解机器学习中梯度下降算法包括其变式算法无论是要解决现实生活中的难题,还是要创建一款新的软件产品,我们最终的目标都是使其达到最优状态。 提高驾驶技术:用GAN去除(爱情)动作片中的马赛克和衣服 作为一名久经片场的老司机,早就想写一些探讨驾驶技术的文章。这篇就介绍利用生成式对抗网络(GAN)的两个基本驾驶技能: 1) 去除(爱情)动作片中的马赛克 2) 给(爱情)动作片中...

    wums 评论0 收藏0
  • 深度学习

    摘要:深度学习在过去的几年里取得了许多惊人的成果,均与息息相关。机器学习进阶笔记之一安装与入门是基于进行研发的第二代人工智能学习系统,被广泛用于语音识别或图像识别等多项机器深度学习领域。零基础入门深度学习长短时记忆网络。 多图|入门必看:万字长文带你轻松了解LSTM全貌 作者 | Edwin Chen编译 | AI100第一次接触长短期记忆神经网络(LSTM)时,我惊呆了。原来,LSTM是神...

    Vultr 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<