Convolutional Neural Network

CNN是专门被用在影像上的。

Image Classification

给机器一张图片,它要去决定这张图片里面有什么样的东西。

我们假设我们的模型输入的图片大小是固定的,模型的目标是分类。

dimension(维度)的长度就决定了现在的模型可以辨识出多少不同种类的东西。

cross entropy(交叉熵)越小越好。

用于度量一个预测概率分布与真实概率分布之间的差异或不相似程度。 差异越大,交叉熵的值就越大。

怎么把一张影像当作一个模型的输入呢?

对于一个machine来说,一张图片其实是一个三维的tensor(维度大于2的矩阵),其中一维代表图片的宽,另外一维代表图片的高,还有一维代表图片的channel的数目。

一张彩色的图片它的每一个pixel(像素)都是由RGB3个颜色所组成的,3个channel就代表了RGB3个颜色

长跟宽就代表了图片的解析度,代表这张图片里面有的pixel,有的像素的数目。

接下来把三维的tensor拉直,然后丢到一个network里面(network里面的输入其实都是一个向量,所以我们只要能够把一张图片变成一个向量,我们就可以当作是network的输入)

在这个例子里面一张图片是由100×100×三个数字所组成的,把这些数字拿出来排成一排就是一个巨大的向量,那么这个向量就可以作为network的输入。而这个向量里面每一维存的数值其实就是某一个pixel,某一个颜色的强度。

把这个向量当作network的一个输入,feature vector(特征向量)他的长度就是100×100×3非常长的一个vector。假设我们现在的第一层的neuron(节点、神经元)的数目有1000个,这边一层总共有多少个weight(权重)?每一个neural它跟输入的向量的每一个数值都会有一个weight,所以我们现在第一层的weight就有3×10^{7}

随着参数的增加,我们可以增加模型的弹性、能力,但是我们也增加了over fitting(过拟合)的风险。

那我们怎么减少在做影像辨识的时候避免使用过多的参数?考虑到影像辨识这个问题本身的特性,我们并不一定需要fully connected(全连接),我们不需要每一个neural跟input的每一个dimension都有一个维度。

接下来就是对影像辨识这个问题对影响本身的特性的一些观察。

Observation 1

对影像辨识这个问题而言,假设我们想要知道这张图片里面有一只动物,这个动物是个鸟,怎么做?

侦测这张图片里面有没有一些特别重要的pattern,而这些pattern是代表了某种物件的。

这是一只猫。

就算是人,我们在判断一个物件的时候,往往也是抓主要的特征。

      假设我们现在要neuron做的事情其实就是现在有没有某种pattern出现,那也许我们并不需要每一个neural都去看一张完整的图片,因为重要的pattern,并不需要看整张图片才能够得到这些,只需要看小范围有没有鸟嘴、眼睛、爪子等,所以这些neural也许根本就不需要把整张图片当作输入,它们只需要把图片的一小部分当作输入,就足以让他们侦测某些特别关键的pattern有没有出现。

      根据这些观察,我们就可以做第一个简化,本来我们每一个neural他要看完整的图片,把图片里面的每一个pixel,每一个pixel都还有三个数字,把一张图片里面所有的都丢给neural,然后让它产生矛盾,这是fully connected and network做的事情,但是现在我们已经观察到说:也许不需要让一个neural看完整的图片,只要让它看图片的一小部分就i足够了,那怎么通过这个观察来设计我们的neural network呢?

Simplification 1

在CNN里面,我们设定一个区域叫做receptive field(感受野),每一个neural都只关心自己的receptive field里面发生的事情就好了。

  • 定义: 在CNN的某一层中,一个特征图上的一个像素(或一个神经元节点),其值是由输入图像上多大范围的像素计算出来的。这个输入图像上的区域,就是该节点的感受野。

  • 通俗理解: 就是网络中的某一层“看到”了原始输入图像的哪一块地方

对于右侧蓝色的neural来说,它只需要关心这一小范围就好了,不需要在意整张图片里面有什么东西,只在意它自己receptive field里面发生的事情就好了。

那这个neural怎么考虑这个receptive field里面发生什么样的事情呢?他要做的事情就是把这3×3乘以三个数值拉直,变成一个长度是3×3×3(也就是27维)的向量,再把这27维的向量作为这个neural的输入,这个neural会给27维的向量的每一个dimension一个位。所以这个neural有27个位,再加上bias(偏置)这个输出,这个输出再送给下一层的neural当作输入。

receptive field怎么决定出来呢

receptive field彼此之间可以重叠,同个范围可以有多个不同的neural,即多个neural可以去守备同一个receptive field。

可不可以receptive field有大有小呢?

可以不可以receptive field只考虑某些channel呢?

receptive field可不可以不是正方形?可以

receptive field的范围一定要相连吗?理论上可以

1 Typical Setting

虽然receptive field你可以任意设计,但最经典的receptive field的安排方式:

第一个就是会看到所有的channel(你可能不会说某些pattern只出现在某一个channel里面),so在描述一个receptive field的时候,只讲它的高跟宽(kernel size,不用讲深度(反正深度一定是考虑全部的channel)

kernel size 卷积核尺寸 或 卷积核大小有时也简称为 “核大小”。我们一般不会设太大。

kernel size 一般3×3,意味着我们在做影像辨识的时候,重要的pattern都只在3×3的范围内就可以被侦测出来,??有些pattern很大,在3×3的范围内没办法侦测出来

一般用同一个receptive field会有一组neural去守备这个范围。

那各个不同receptive field之间的关系是怎么同样的呢?

把左上角receptive field往右移一点,就制造一个新的守备范围,制造另外一个receptive field,移动的量叫做stride(步长)stride是你自己决定的参数(往往1或2)。你希望receptive field和receptive field之间是有重叠的。(因为假设receptive field完全没有重叠,有一个pattern就正好出现在两个receptive field的交接上,那就会变成没有任何neural去侦测它,就会miss掉这个pattern)

hyper parameter(超参数)指的是在机器学习模型开始学习之前,就由开发者人为设定的配置参数。它们是“关于模型如何学习的参数”,而不是模型通过学习得到的参数。

超出范围怎么办?padding(补值0)

除了水平移动,也有垂直方向的移动。按照这个方式,扫过整张图片。

Observation 2

同样的pattern出现在不同的区域里面。

这些侦测鸟嘴的neural它们做的事情其实是一样的,只是它们守备的范围不一样。

那我们真的需要每一个守备范围都去放一个侦测鸟嘴的neural吗?

我们能不能让不同receptive field的neural它们共享参数。

这两个neural它们的weight完全是一样的。

输入不一样,输出不一样。

2 Typical Setting

filter(滤波器 或 过滤器)

Benefit of Convolutional Layer(卷积层的优势)

Fully Connected Layer弹性最大,不需要看整张图片,也许只需要看图片的一小部分就可以侦测出重要的pattern。所以有了Receptive Field,只能看一个小范围,弹性变小,参数共享又进一步限制network的弹性,本来在learning的时候,它可以决定说这两个network的参数是什么,每一个neural可以各自有不同的参数它们可以正好学出一模一样的参数,也可以有不一样的参数,但是加入参数共享以后就意味着某一些neural无论如何参数就算一模一样的,也没得选了,参数要一模一样,所以又更增加了对neural的限制。

而receptive field+Parameter Sharing就是Convolutional Layer。

有用Convolutional Layer的network就叫Convolutional Neural Network,就是CNN。

其实CNN它的bias比较大,它的model的bias比较大。model bias大不一定是坏事,因为当model bias小,model 的 flexibility (灵活性)很高的时候,他比较容易overfitting。Fully Connected Layer它可以做各式各样的事情,它可以有各式各样的变化,但是它可能没有办法在任何特定的任务上做好,而Convolutional Layer它是专门为影像设计的。所以它在影像上仍然可以做的好,虽然它的model bias很大,但这个在影像上不是问题,但是如果它用在影像之外的任务,那就要小心,需要想想那些任务有没有我们刚才讲的影响有的特性。

以上是CNN 的一种介绍方式。下面是另外一种介绍方式:(一模一样但同个故事用不同版本来说明)

Convolutional Layer(卷积层)

Convolutional Layer就是里面有很多的filter(“滤波器”或“卷积核”),这些filter的大小是3×3×channel的size,所谓channel就是如果是彩色照片的话,那就是RGB3个channel,如果是黑白图片的话,它的channel就等于1。

那一个Convolutional Layer里面有一排的filter,每一个filter都是一个3×3×channel这么大的tensor(张量)。每一个filter的作用就是要去图片里抓取某一个pattern,但这些pattern要在3×3×channel这么小的范围内才能被这些filter抓出来。

那这些filter怎么去图片里面抓pattern呢?举例说明

       假设channel是1,也就是我们图片是黑白的图片;假设这些filter的参数是已知的,filter就是一个一个的tensor,这个tensor里面的数值我们已经都知道了。【但实际上这些tensor里面的数值,其实就是model里面的parameter(参数),这些filter里面的数值其实都是未知的,它是要透过gradient descent(梯度下降)去找出来的】

我们来看看这些filter是怎么跟一张图片进行运作,怎么去图片上面把pattern侦测出来的。

先把filter放在图片的左上角,然后把filter里面所有的(9个)值跟左上角这个范围内的9个值做相乘,算完是3,然后往右移动一点,移动的距离叫做strive(设为1)。再算是-1,再移,以此类推,再往下,直到移到右下角。那这个filter怎么说实在侦测pattern呢?这个filter里面对角线的地方都是1,所以它看到image里面出现连3个1的时候,它的数值会最大。

左上角和左下角会出现pattern

接下来,我们把每一个filter都做重复的process。

如果我们有64个filter,就会得到64群数字,这群数字叫做feature map(特征图)。

所以当我们把一张图片通过一个Convolutional Layer里面有一堆filter的时候,我们产生出来一个feature map,假设Convolutional Layer里面有64个filter,那我们产生的feature map就有64组数字,每一组在这个例子里面是4×4,每个filter产生4×4的数字。

feature map可以看成是另外一张新的图片,只是这个图片的channel不是RGB,这个图片的channel有64个,每一个channel就对应到一个filter。本来一张图片3个channel,通过一个convolution(卷积),它变成一张新的图片,有64个channel。

Multiple Convolutional Layers(多个卷积层)

Convolutional Layer是可以叠很多层的,叠第二层,第二层的convolution里面也有一堆的filter,每一个filter大小设为3×3,高度设为64(filter的高度就是要处理的影像的channel)这64前一个Convolutional Layer的filter数。

如果我们的filter大小一直设3×3,会不会让我们的network没办法看比较大范围的pattern呢?不会。

看第一个Convolutional Layer的输出的这个feature map的3×3范围的时候,在原来的影像上其实是考虑了一个5×5的范围,所以虽然我们的filter只有3×3,但他在影像上考虑的范围是比较大的,是5×5,所以你的network叠得越深,同样是3×3大小的filter,它看的范围就会越来越大

Comparison of Two Stories(两种情况比较)

两个版本的故事是一模一样的。第一个版本里面neural共用的参数就是第二个版本里面的filter。

neural有bias,filter也有,只是未提到。

第一个版本里面不同的neural可以share weight,然后去守备不同的范围,而share weight这件事其实就是把filter扫过一张图片,就是convolution。但所谓的把filter扫过图片这件事情就是不同的receptive field neural可以共用参数,而这组公用的参数就叫做一个filter。

总结

Observation 3

Convolutional Layer在做影像辨识的时候,其实还有第三个常用的东西—pulling。pulling来自另一个观察:我们把一张比较大的图片做subsampling(下采样),举例来说,把偶数的color都拿掉,奇数的  都拿掉,图片变为原来的1/4,但是不会影响里面的东西。把一张大的图片缩小。

pooling(池化)本身没有参数,所以它不是一个layer,它里面没有wake,它没有要learn的东西。ping像是一个activation function(激活函数),它就是一个operator,它的行为都是固定好的,没有要根据data学任何东西,pooling也有很多不同的版本。这里讲的是max pooling。

每一个filter都产生一把数字,要做pooling的时候,我们就把数字几个几个一组,上图2×2个一组,每一组里面选一个代表,在max pooling里面我们选的代表就是最大的那一个。(自己决定的)

做完convolution以后,往往后面还会搭配pooling,pooling做的事情就是把图片变小,做完convolution以后,会得到一张图片,这张图片里面有很多的channel,做完pooling以后,把这张图片的channel不变,但是会把图片变得比较小。

一般在实作上往往就是convolution跟pooling交替使用。pooling对于你的performance还是可能会带来一点伤害的。近年来很多影像辨识的network的设计,往往也开始把pooling丢掉,他会做这种for convolution的neural network,就是整个network里面统统都是convolution,完全都不用pooling。因为近年来运算能力越来越强,pooling组最主要的理由就是为了来减少运算量。

The whole CNN

所以一般以后你的架构就是convolution+pooling(可有可无),那你做完几次convolution接下来最终怎么得到最后的结果呢?你会把pooling的output做flatten(扁平化

把影像里面本来排成矩阵的样子的东西拉直,把所有的数值拉直成一个向量,再把这个向量丢进fully connected layers里面,最终可能还要过个softmax(归一化指数函数),然后最终得到影像辨识的结果,这就是一个经典的影像辨识的network。

Application: Playing Go

除了影像辨识以外,CNN另外一个最常见的、最耳熟能详的应用就是用来下围棋。

下围棋其实就是一个分类的问题,你的network的输入是棋盘上黑子跟白子的位置,你的输出就是下一步应该要落子的位置。把棋盘表示成一个19×19维的向量,在这个向量里面,如果某一个位置有一个黑子,那个位置我们就填1,白子-1,没子0。这样我们就可以告诉network现在棋盘上的盘是长什么样子的。所以下围棋就是一个有19×19个类别的分类问题,network会output说在这19个类别里面,哪一个类别是最好的,应该要选择下一步落子的位置应该在哪里,这个问题完全可以用一个fully connected的network来解决,但是CNN的效果更好。Why?首先你完全可以把一个棋盘看作是一张图片,一个棋盘可以看作是一个解析度19×19的图片,这个图片里面每一个像素就代表棋盘上一个可以落子的位置,一般图片的channel就是RGB,而棋盘上每一个pixel是用48个channel来描述,也就是说棋盘上的每一个位置它都用48个数字来描述(原始论文说的)。

Why CNN for Go playing?

CNN事实上并不能处理影像放大、缩小或者旋转的问题。

CNN并没有你想象的那么强,那就是为什么在做影像辨识的时候往往都要做data augmentation(数据增强)

Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐