(14)-CNN(卷积神经网络)

本文介绍了如何利用CNN进行图片分类,通过观察发现神经网络仅关注关键特征,提出receptive field和参数共享的概念。CNN通过卷积层捕获局部模式,pooling则用于特征压缩,最后通过全连接层完成分类。重点讲解了卷积层、filter、receptive field、stride和pooling的应用。
摘要由CSDN通过智能技术生成

现在开始探讨神经网络的架构-CNN专门用在影像上的

图片的分类:

现在给定一张图片,来判断这张图片里面有什么东西,怎么操作呢?

假设模型输入的图片大小是固定的,(尽管输入的图片可能大小不一样,但是现在影像处理系统中的图片都设成是一样的),模型的目标是分类,所以会把每一个模型表示成One-hot的factor ,目标叫做\widehat{y},在这个One-hot的factor 里面,假设我们现在类别是一只猫的话,猫所对应的大小的数值是1 ,其他东西所对应的大小数值是0 ,dimension对应的长度就决定了现在的模型可以辨识出多少不同种类的东西,意思就是一个向量的长度是2000,就意味着可以辨识出2000中不同的东西,如果希望影像辨识系统辨识出上万种的目标,那所需要的label就会是一个上万维的向量。

模型的输出经过softmax之后输出的是{y}',我们希望{y}'\widehat{y}之间的交叉熵越小越好。

 接下来的问题是怎么把一张影像当作是模型的输入呢?对电脑来说一张影像是什么样的东西,

对于机器来说一张图片就是一个三维的tensor(张量)——维度大于2 的矩阵,其中一张代表图片的宽,另外一维代表图片的高,还有一维代表图片的 channel的数目。channel的意思就是一张彩色的图片他的每一个像素都是由R G B三个颜色组成的,所以三个channel就代表了R G B三个颜色。长和宽就代表了这张图片的解析度,代表这张图片里面的所有像素的数目。

接下来就把这一个三维的tensor拉直,拉直以后就可以放在一个网络里面了(到现在为止讲的network的输入都是一个向量)所以只要我们把一张图片变成一个向量,我们就可以把它当作是network的输入。但是怎么样把三维的tensor变成一个向量呢?最简单得方法就是将这个tensor拉直,一个三维的tensor里面有几个数字呢?在这个例子里面有100×100×3个数字,所以一张图片是由100×100×3个数字组成的,把这些数字排成一排就组成了一个巨大的向量,这个巨大的向量就可以做network的输入,在这个向量里面,每一维里面的数值就是某一个像素,某一个颜色的强度(每一个像素都是由RGB三种颜色组成,每一个颜色都有一个数值代表说这个颜色的强度),在这个向量里面每一维的数值就代表某一个位置的某一个颜色的强度。

上面的这个拉直的向量当作是network的输入,到现在为止讲的都是全连接的网络。

 

现在的输入的长度是100×100×3,假设现在第一层神经元的数目是1000个,那计算一下第一层有多少个weight?每一个神经元跟输入的向量的每一个数值都会有一个weight,所以就有1000×100成100×3个weight。如果参数越多,我们可以增加模型的弹性。但是也增加了过拟合的风险。

 模型的弹性越大,那过拟合的风险就越大,在影像辨识的时候怎么避免使用过多的参数呢?考虑到影像辨识这个问题本身的特性,其实也并不一定需要全连通网络这件事。所以我们并不是需要每一个神经元和每一个输入都有一个weight,接下来就是对影像辨识特性的观察。

第一个观察,对影像辨识这个问题而言,假设一张图片我们要知道这张图片的内容是一只鸟这件事要怎么做呢?对神经网络的神经元来说就是辨别出这张图片当中的一些重要的pattern,这些pattern代表的是某些重要的物件。举例来说,如果现在某一个神经元看到了这只鸟的嘴这件pattern,另外的神经元说看到了鸟的眼睛这件pattern,又某个神经元说看到了鸟的爪子这个pattern,也许看到的这些pattern总和起来说就代表着看到了一只鸟。

机器做的事情就是注意些比较关键的特征来判断图片中的内容,但是假设我们现在的神经元做的事情是来判断有没有某种特征的出现,也许我们并不需要每一个神经元都去看一张完整的图片。只要是在校的范围当中判断某个特征就可以,并不需要看整张图片。所以神经元并不需要把整张图片当作输入,只需要把图片的一小部分当作输入,就足以让他们侦测某些特别关键的特征有没有出现。以上就是第一个观察。

根据上面的第一个观察就可以做第一个简化,怎么简化呢?

本来每一个神经元要看完整的图片,把图片当中的 所有信息都要给每一个神经元,这个是全连通网络所做的事情。补充什么是全连接的网络:(所谓连接神经网络,就是由连接层组成的网络。 简单的连接层网络一般分为三层,分别输入层,隐含层,输出层。 当然在输出层后面还可以添加分类层,或者损失函数等特殊处理层。 对于连接神经网络来说,网络中每一层的每一个结点都与相邻网络层的每一个结点相连,用来把前边提取到的特征综合起来)。但是我们现在观察到说也许不一定让每一个神经元看完整的图片,只要看图片的一小部分就行,怎么通过我们现在观察到的来设计神经网络呢?在CNN里面有一个这样的做法,就是设定一个区域叫做 卷积野(receptive field),每一个神经元都只关心自己的receptive field里面发生的事情就好了。举例来说:先定义这个蓝色的神经元他的范围就是这一个receptive field,在这个receptive field里面有3×3×3个数值,那对这个蓝色的神经元来说只需要关系这一小范围就好,不需要在意整张图片当中有什么东西,只在意自己的receptive field里面发生什么样的事情,那这个蓝色的神经元怎么样知道里面发生的事情呢?

要做的事情就是把3×3×3的也就是27维向量拉直,再把这个27维的向量作为这个蓝色神经元的输入

 

那这个receptive field怎么决定出来呢?  自己定义的,并且receptive field彼此之间也是可以相互重叠的。相同的范围也是可以有不同的神经元。

现在的想法是 receptive field是不是也可以有大有小呢?或是receptive field只考虑某些channel呢?有的特征只在红色的channel就会出现,有的神经元只考虑一个channel呢?上面的这些考虑都是可以出现的。在CNN当中一般不是这样考虑的,但是有这样的做法。receptive field的形状也是可以进行变换的,receptive field是自己定义的,根据问题的连接来自定义receptive field的形状。

虽然 receptive field可以自己设计,但是最经典的是会看所有的channel,既然会看全部的channel,所以在描述一个receptive field的时候只要将他的高跟宽就好,不用讲他的深度,高和宽合起来叫做kernel size(内核大小)在上面的这个例子当中的内核大小就是3×3,一般这个内核大小不会设定很大的数值,在影像辨识里面设定一个3×3的内核大小就足够了。那3×3的范围当中,在做影像辨识的时候重要的pattern就都会在这个区域当中辨识出来了吗?综上所示:常见的receptive field的设定方式就是内核大小为3×3的

 一般同一个receptive field会有一组神经元去守备这个范围,所以在划了一个receptive field的时不会只有一个神经元去守备,会有64个或者是128个神经元去守备这个receptive field。

  

 到目前为止讲的都是一个receptive field,各个不同的receptive field之间的关系是怎么样的呢?会把左上角的这个receptive field往右移动一点得到一个新的守备范围,那这个移动的范围叫做stride,在这个例子里stride=2,这个参数的值是自己设定的,但是这个数值不会设很大,因为我们希望receptive field之间是有重叠的。为什么希望receptive field是由重叠的呢?那假设两个receptive field没有重叠,如果一个pattern出现在两个receptive field的交界上,就会变成没有一个神经元去侦测他,有可能就会错过这个pattern。

在移动的过程当中会出现超出影像的范围怎么办呢?

超出范围的就做padding(填充),就是补0的意思(当作里面的值都是0),填充的方法有很多,不一定都是补0,也可以补其他的数值。

 除了横着移动的方法,还会有垂直方向上的移动,方法类似。所以在整张图片上都是会被某一个receptive field所覆盖的。也就是图片中的每一个位置都是有一群神经元在侦测那个地方有没有出现某些pattern。

上面的方式是第一个简化全连通网络的方式。

第二个观察是什么呢?同样的pattern可能会出现在图片当中的不同区域(位置)里面。

虽然在图片的不同位置,但是他一定落在某一个receptive field里面,因为receptive field是盖满整张图片的,所以图片当中的任何地方不是在某个神经元的守备范围内的。鸟嘴一定是在某一个神经元的receptive field里面的。

 同组神经元是负责关泽同一接受域中方可能出现的不同特征,现在的问题是侦测鸟嘴的神经元中所做的事情都是一样的,只是他们守备的范围不是一样的,既他们做的事情是一样的,守备的范围不一样,我们真的需要每一个守备范围都去放一个检测鸟嘴的神经元吗?他们做的事情都是重复的啊,我们所需要的参数两会很多。

 如果放在影像处理上会是什么样的呢?

让不同的receptive field的神经元共享参数,共享参数就是这两个神经元的weight是一样的 

既然两个神经元的weight是一样的,那会不会输出也是一样的呢?不会,因为两个神经元的输入是不一样的。

 输出一不一样取决于两个神经元的receptive field不一样,如果输出是一样的,那就是receptive field是一样的。

 上面所述就是第二个简化,让一些神经元共享参数,至于怎么共享完全是自己决定的。

接下来讲的是常见的在影像辨识是上共享的方法,每一个receptive field都有一组参数,两个

receptive field的参数是共享的,那这个参数叫做Filter。

目前我们讲了两个简化的方法,现在来梳理一下:

全连通网络的弹性是最大的,我们现在也许不用通过看整张图片,只要看图片的一小部分就可以侦测出重要的pattern,所以有了receptive field的方法,当我们强制一个神经元只能看一张图片里面的一个范围的时候,network的弹性就是变小的。接下来就是参数共享的方法,就更进一步的限制了network弹性,加入参数共享之后,某一些神经元无论如何让,参数就算是一模一样,这就更加的增加了network的限制。而receptive field加上参数共享之后就是从 convolutional layer(卷积层)

CNN模型的偏差是比较大的,模型偏差比较大的时候也不是一件坏事。

CNN专门是为影像辨识设计的,但是在其他的任务上面不一定会做的很好。

 卷积层:卷积里面有很多的filter,这些filter的大小是3×3×channel的size,那channel就是加入图片是彩色的话就是R  G B三个channel,如果是黑白图片的话channel等于1,哪一个卷积层里面就是有一排的filter,每一个filter的作用就是去图片当中抓取某一个pattern。

filter怎么去图片当中抓取pattern的呢?举例来说:假设这些filter的参数是已知的,filter就是一个个的tensor,这个tensor里面的数值都是一致的,实际上tensor里面的数值就是模型当中的参数,这些filter当中的数值是未知的,是通过梯度下降法得到的,现在我们的假设是这些filter当中的数值已经找到了,现在就是看看这些filter是怎么跟一张图片进行运作的,怎么去图片上面把pattern侦测出来的。

 filter是怎么在图片上面侦测出pattern的呢?做法是:先把filter放在图片的左上角的位置,讲filter1当中的九个数值和图片工商filter左上角的九个值相乘得到3,再将图片上的filter往右移动一点,移动的距离是1 (stride=1),再将filter1的数值与这个新的filter的九个数值相乘得到-1,再往右移动一点得到的数值是-3,以此类推最后将图片上的filter移动到右下角的地方。

 那这个filter怎么说是在侦测pattern的呢?因为filter1的对角线的数值都是1 ,所以在看到图片当中的数值有连续的1的时候得到的数值是最大的。

 从输出的这些数值来看,左上角和左下角的都出现了三个1连在一起的pattern。

接下来对filter2:做与filter 相同的操作得到的输出的数值如下图所示

得到的这群数字有一个名字叫做feature map(特征图)

我们将一张图片经过convolutional layer里面有一堆filter的时候,我们产生出来了一个feature map特征图,假设这个convolutional layer里面有64个filter的时候,产生的这个feature map就有64群数字。这个feature map可以看做是另外一张新的图片,但是这张图片的channel不是R G B的,每一个channel对应的是一个filter。

convolutional layer是可以叠加很多层,在叠加第二层的时候,第二层的convolution里面也是有一堆的filter,每一个filter的大小在这个例子当中设置的是3×3×64的,filter的高度设的是64 的,因为要处理的影像的channel(根据输入的图片的channel的数值决定的)

如果filter的大小一直设定的是3×3 的,会不会让我们的网络没办法看到范围比较大的pattern呢?不会的,我们在第二层convolutional layer的filter的大小设置成3×3的话,当我们看最左上角的熟知的时候,在图片对应的范围是5×5 的范围,所以只要network叠加的越深,就能侦测到比较大的pattern。

 总上面讲的两种方法:说到的有一些神经元共用参数就是第二个方法当中的filter。在实际的操作上面CNN还是有bias的。

 刚才讲的第一个方法当中不同的神经元可以共享参数守备不同的范围 ,而共享参数就是讲filter扫过一张图片,而filter扫过一张图片实际上就是convolution,这就是为什么叫convolutional layer。

综上所述是从两个方面来讲CNN:

一种方法是:不需要看整张图片,神尽管只看其中的一小部分就好。

另一种就是:对filter来说,有一组filter,每一个就只看filter的一小范围

 convolutional layer在做影像辨识的时候还可以用pooling

pooling是怎么来的呢?把一张比较大的图片做二次抽样,把偶数的column都拿掉,奇数的row都拿,图片变为原来的四分之一,但是不会影响影片里面的什么东西,就是把一张大的图片缩小了。

所以有了pooling的设计,pooling是怎么运作的:本身并不是一个参数,行为都是固定好的,没有要根据data学任何东西,想到与一个操作者。

pooling有很多的版本,现在讲的是Max Pooling 

Max Pooling 是怎么运作的呢?刚才说每一个filter都产生一群数字,要做pooling的时候,把这群数字进行分组,每一组里面选一个代表,在Max Pooling 里面选的代表就是最大的一个数字(选择的这个数字是可以自己决定的)

 所以我们在昨晚convolution的时候后面跟的是pooling,pooling做的事情就是将图片变小,但是channel的大小还是不变的。咋实际的操作上就是convolutions和pooling交叉使用。

但是pooling对呈现结果还是有伤害的,因为假设侦测的是非常小的东西,随便做二次抽样的话,最后展现的结果不是那么的好。

输入的图片经过几次的convolution之后会的到什么样的结果呢?会把pooling的输出结果当作是flatten,这个flatten的作用是把影像里面本来排成矩阵的东西拉直,把所有的数值拉直拉成一个向量,在把这个向量放进全联通的网络里面,经过一个softmax最终得到影像辨识的结果。

 上面的这个过程就是影像辨识。

除了影像辨识之外,CNN还有一个常见的应用就是Playing Go(下围棋)

下围棋就是一个分类的问题,network的输入是棋盘上黑白子的位置,输出就是下一步应该落子的位置。现在我们已经知道network的输入就是一个下向量,但是怎把棋盘表示成向量呢?

棋盘上有19×19个位置,那就表示成19×19维的向量,在这个向量里面某一个位置有一个黑子,那这个位置就填1,如果是白子的话就填-1,没有子的话就填0.network就知道棋盘上的盘式是怎么样的。将这个表示好的向量当作输入放入到network当中,最后在这个19×19的向量当中找到最好的哪一个分类。这个问题可以用fully-connected network来解决,但是CNN的效果更好,为什么呢?可以被一张棋盘当作是解析度是19×19 的图片,这个图片上的每一个像素都是可以当作可以落子的位置,棋盘上每一个像素的使用48(规定的)个channel来描述的.

为什么CNN可以用在下围棋上面?

棋盘上重要的范围就是在5×5的范围里面。

在影像上的第二个观察就是同样的pattern可能出现在不同的位置

 

 但是在做影像的时候都会做pooling这一步,但是在棋盘上同样使用的吗?把棋盘上奇数列和偶数列拿掉?下围棋的时候不会用pooling。

 近年来CNN还用在了其他的地方-语音和文字处理上

 CNN没办法处理影像的放大和缩小或者是旋转的问题。在做影像辨识的时候还要做data augmentation.

原创不易,请勿转载,随手笔记,有误请告知。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值