DW李宏毅机器学习笔记—Task05(六)—卷积神经网络


前言

这是我在Datawhale组队学习李宏毅机器学习的记录,既作为我学习过程中的一些记录,也供同好们一起交流研究,之后还会继续更新相关内容的博客。


为什么用CNN

在这里插入图片描述

在我们之前的讨论中,我们经常用到Neural Network,而在今天当我们要处理影像时,我们依然可以使用Neural Network,但有一个更好的选择:CNN。

为什么我们要使用CNN而不用Neural Network呢?

在network的structure里面,每一个neural就是代表了一个最基本的分类器,
在这里插入图片描述
当我们Neural Network时,我们处理的流程就像上图。

第一层的神经网络是最简单的分类器,它做的事情就是识别有没有绿色出现,有没有黄色出现,有没有斜的条纹。

第二层的神经网络是做比第一层更复杂的网络,根据第一层的output,它可以根据直线横线判断是窗框的一部分,根据棕色纹判断是木纹,根据斜条纹+灰色判断是很多的东西比如轮胎的一部分等等……

再根据第二个hidden layer的outpost,第三个hidden layer会做更加复杂的事情。

但现在的问题是,当我们一般直接用全连接前馈神经网络来做影像处理的时候,往往我们会需要太多的参数

举例来说,假设将一张100 *100的彩色图(一张很小的imgage)拉成一个vector,就会有100 *100 *3的pixel。 如果是彩色图的话,每个pixel需要三个value来描述它,就是30000维(30000 dimension)。

假如input vector是30000 dimension,hidden layer假设是1000层neural,那么这个hidden layer的参数就是有30000 *1000,就会有很多很多的参数。

那么CNN做的事就是简化neural network的架构。将一些用不上的特征值在一开始就舍弃。不用fully connect feedforward network,而是用更少的参数来做影像处理这件事。所以CNN比一般的DNN(深度神经网络)还要简单的。

CNN运作看似很复杂,但它的模型事实上是要比DNN还要更简单的。而且我们就是用power-knowledge 去把原来fully connect layer中一些参数拿掉就成了CNN。

Small region

首先说明一下,为什么可以用比较少的参数来处理影像。

这里有几个观察,第一个是在影像处理里面,第一层hidden layer的neural的作用就是侦测某一种pattern。大部分的pattern其实要比整张的image更小。对一个neural来说,假设要判别一个image里面有没有某一个pattern出现,它其实是不需要看整张image,它只要看image的一小部分。

在这里插入图片描述

举例来说,假设我们现在有一张图片,第一个hidden layer的某一种neural的工作就是要侦测有没有鸟嘴的存在,有一些neural侦测有没有爪子的存在,有一些neural侦测有没有翅膀的存在,有没有尾巴的存在,合起来就可以侦测图片中是否有一只鸟。

假设有一个neural的工作是要侦测有没有鸟嘴的存在,那并不需要看整张图,我们只需要给neural看着上图小红色方框的区域(鸟嘴),它就可以判断它是不是一个鸟嘴。对人来说也是一样,看这一小块区域判断是否是鸟嘴,不需要去看整张图才知道这件事情。所以,每一个neural连接到每一个小块的区域就好了,不需要连接到整张完整的图。

Same Patterns

第二个观察就是同样的pattern在image中,可能会出现在image不同的部分,但是代表的是同样的含义,它们有同样的形状,所以可以用同样的neural,同样的参数就可以把patten侦测出来。
在这里插入图片描述

比如说,第一幅图中有一张在左上角的鸟嘴,第二幅图中有一个在中央的鸟嘴,虽然识别的位置不同,但是不需要去训练两个不同的detector,一个专门去侦测左上角的鸟嘴,一个去侦测中央有没有鸟嘴。如果这样做的话,这样就太冗了。我们不需要太多的冗源,这个nerual侦测左上角的鸟嘴跟侦测中央有没有鸟嘴做的事情是一样的。我们并不需要两个neural去做两组参数,我们就要求这两个neural用同一组参数,就样就可以减少你需要参数的量。

Subsampling(下采样)

在这里插入图片描述

第三个是:我们知道一个image你可以做subsampling,你把一个image的奇数行,偶数列的pixel拿掉,变成原来十分之一的大小,它其实不会影响人对这张image的理解。对你来说:这张image跟这张image看起来可能没有太大的差别。是没有太大的影响的,所以我们就可以用这样的概念把image变小,这样就可以减少你需要的参数。

这方面的详细介绍可以去百度了解一下,不过需要点基础。

CNN架构

在这里插入图片描述

整个CNN的架构是这样的:首先input一张image以后,这张image会通过convolution layer(卷积层),然后做max pooling,然后再做convolution,再做max pooling这件事。这个process可以反复无数次,直到反复的次数够多之后,(但是反复多少次你是要事先决定的,它就是network的架构(就像你的neural有几层一样),你要做几层的convolution,做几层的Max Pooling,在设计neural架构的时候,要事先决定好)。你做完决定要做的convolution和Max Pooling以后,你要做另外一件事,这件事情叫做flatten(扁平化),再把flatten的output输入进一般的fully connected feedforward network,然后得到影像辨识的结果。

在这里插入图片描述
基于三个对影像处理的观察,所以设计了CNN这样的架构。

第一个观察是,要生成一个pattern,不要看整张的image,你只需要看image的一小部分。

第二是,通用的pattern会出现在一张图片的不同的区域。

第三个是,我们可以做subsampling

前面的两个任务可以用convolution来处理,最后的property可以用Max Pooling来处理。

判断是否可以使用CNN,也要基于上述的三个观察。

接下来会介绍每一个layer在做的事情,先从convolution开始。

Convolution

Propetry1

在这里插入图片描述
假设现在network的input是一张6*6的Image,如果是黑白的,一个pixel(像素点)就只需要用一个value去描述它,1就代表有涂墨水,0就代表没有涂墨水。

在convolution layer里面,存在一组filter,其中每一个filter就等同于fully connect layer里面的一个neuron,每一个filter其实就是一个matrix(3 *3),每个filter里面的参数也就是matrix里面每一个element值就是network的parameter。

注意:这些parameter是要学习出来的,并不是人去设定的。

每个filter如果是3* 3的detects意味着它是侦测一个3 *3的pattern ,即只看3 *3范围内的像素点。filter在侦测pattern的时候不会看整张image,而只看一个3 *3的范围,然后就可以决定有没有某一个pattern的出现。

这个就是我们考虑的第一个Property

Propetry2

在这里插入图片描述

filter怎样在image运作呢?

首先第一个filter是一个3* 3的matrix,先把这个filter放在image的左上角,把filter的9个值和image的9个值作内积,两边都是1,1,1(斜对角),内积的结果就得到3。然后进行移动,移动的距离叫做stride,stride的值需要提前设定,我们先设stride等于1。

你把filter往右移动一格得到-1,再往右移一格得到-3,再往右移动一格得到-1。接下里往下移动一格,得到-3。以此类推,直到你把filter移到右下角的时候,得到-1,得到的值如下图所示。
在这里插入图片描述

6 *6的 m a t r i x matrix matrix经过 c o n v o l u t i o n convolution convolution(卷积)就得到4 *4的 m a t r i x matrix matrix。如果你看 f i l t e r filter filter的值,斜对角的值是1,1,1。所以它的工作就是识别斜对角的值也就是1,1,1有没有连续左上到右下的出现在这个image里面。

比如说:斜对角的值是1,1,1的Matrix出现在上图所示蓝色的直线,那 f i l t e r 1 filter1 filter1就会告诉你:左上跟左下出现最大的值,就代表说这个filter要侦测的pattern,出现在这张image的左上角和左下角。

这个过程就体现了propetry2。同一个pattern出现在了左上角的位置跟左下角的位置,我们就可以用filter 1侦测出来,并不需要不同的filter来做这件事。

在这里插入图片描述

在一个convolution layer 里面会有很多的filter(刚才只是一个filter的结果),那另外的filter会有不同的参数(比如图中显示的filter2),它也做跟filter1一模一样的事情,在filter放到左上角再内积得到结果-1,依次类推。你把filter2跟 input image做完convolution之后,你就得到了另一个4*4的matrix,红色4 *4的matrix跟蓝色的matrix合起来就叫做feature map,有几个filter,就得到多少个image,比如你有100个filter,你就得到100个4 *4的image。

在这里插入图片描述
刚才举的例子是一张黑白的image,所以input是一个matrix。若换成彩色的image, 彩色的image是由RGB组成的,所以,一个彩色的image就是好几个matrix叠在一起,就是一个立方体。如果要处理彩色image,这时候filter不是一个matrix,filter也是一个立方体(也有宽度了)。如果用RGB表示一个pixel的话,那input就是3*6 *6,那filter就是3 *3 *3。

在做convolution的话,就是将filter的9个值和image的9个值做内积(不是把每一个channel分开来算,而是合在一起来算,一个filter就考虑了不同颜色所代表的channel)。

convolution和fully connected之间的关系

在这里插入图片描述
Convolution就是fully connected layer把一些weight拿掉了。经过convolution的output就是那张Feature Map。其实也是一个hidden layer的neural的output。如果把这两个放在一起比较的话,convolution就是fully connected拿掉一些weight的简化版。

在这里插入图片描述

我们在做convolution的时候,我们filter1放到左上角(先考虑filter1),然后做inner product,得到内积为3,这件事情就等同于把6* 6的image拉直(变成如图所示的数组)。然后第一个neural的output是3,这个neural的output考虑了9个pixel,这9个pixel分别就是编号(1,2,3,7,8,9,13,14,15)的pixel。这个filter做inner product以后的output 3就是某个neuron output 3时,就代表这个neuron的weight只连接到(1,2,3,7,8,9,13,14,15)。这9个weight就是filter matrix里面的9个weight(同样的颜色)

在fully connected中,一个neural应该是连接在所有的input(有36个pixel当做input,这个neuron应连接在36个input上),但是现在只连接了9个input(detain一个pattern,不需要看整张image,看9个input就好),这样做就是用了比较少的参数了。

在这里插入图片描述

将stride=1(移动一格)做内积得到另外一个值-1,假设这个-1是另外一个neural的output,这个neural连接到input的(2,3,48,9,10,1415,16)。

这也意味着:这两个neuron本来在fully connect中两个neural是有自己的weight,而在做convolution时,首先把每一个neural连接的wight减少,强迫这两个neural共用一个weight。这件事就叫做shared weight,当我们做这件事情的时候,我们用的这个参数就比原来的更少。

Max pooling

在这里插入图片描述
在这里插入图片描述

相对于convolution来说,Max Pooling是比较简单的。根据filter 1得到4*4的maxtrix,根据filter2得到另一个4 *4的matrix,接下来output时每4个value编成一组。每一组里面可以取它们的平均值或者选最大值,然后将四个value合成一个value。这样可以让你的image缩小。

在这里插入图片描述

假设我们选择四个里面的max vlaue保留下来,这样可能会有个问题,把这个放到neuron里面,这样好像不能够微分,但是实际上还是能用微分的办法来处理的。

在这里插入图片描述

做完一个convolution和一次max pooling,就将原来6 * 6的image变成了一个2 *2的image。这个2 *2的pixel的深度取决于convolution有几个filter(有50个filter,就有50维),得到结果是一个new image but smaller,一个filter就代表了一个channel。

在这里插入图片描述

一次convolution和一次max pooling组成的进程可以重复很多次,通过一个convolution + max pooling就得到新的 image。它是一个比较小的image,可以把这个小的image,做同样的事情,再次通过convolution + max pooling,将得到一个更小的image。

这边有一个问题:第一次有25个filter,得到25个feature map,第二个也是由25个filter,那做完是不是会得到 2 5 2 25^2 252的feature map了?其实不是这样的!

假设第一层filter有2个,第二层的filter在考虑这个imput时是会考虑深度的,并不是每个channel分开考虑,而是一次考虑所有的channel。所以convolution有多少个filter,output就有多少个filter(convolution有25个filter,output就有25个filter。而且这25个filter都是一个立方体)

Flatten

在这里插入图片描述

flatten就是feature map拉直转化成一个一维数组,然后就可以输入进fully connected feedforward netwwork,就结束了。

CNN in Keras

在这里插入图片描述

唯一要改的是:network structure和input format:本来在DNN中input是一个vector,现在是CNN的话,需要考虑 input image的几何空间,所以不能输入vector,应该input一个tensor(高维的vector)。

为什么要给三维的vector?因为image的长宽高各是一维,若是彩色的话就是第三维。所以要给三维的tensor。

代码解释:

model.add(Convolution2D(25, 3, 3,

25代表有25个filter,3 *3代表filter是一个3 *3的matrix

input_shape=(28,28,1)))

假设要做手写数字辨识,input是28 *28的image,每个pixel都是单一颜色。所以input_shape是(28,28,1)。如果是黑白图用1&0来表示black&white,如果是彩色的图时用3(每个pixel用三个值来表述)。

model.add(MaxPooling2D(( 2, 2 ))

2,2表示把2*2的feature map里面的pixel拿出来,选择max value。

在这里插入图片描述

假设我们input一个1 *28 * 28的image,你就可以写model.add(Convolution2D( 25, 3, 3, Input_shape=(28,28,1)))。通过convolution以后得到output是25 *26 *26(25个filter,通过3 *3得到26 * 26)。然后做max pooling,2 *2一组选择 max value得到 25 *13 * 13

然后再做一次convolution,假设选50个filter,每一个filter是3 *3时,那么现在的channel就是50。13 *13的image通过3 *3的filter,就成11 *11,然后通过2 *2的Max Pooling,变成了50 *5 *5

在第一个convolution layer里面,每一个filter有9个参数,在第二个convolution layer里面,虽然每一个filter都是3 *3,但不是3 *3个参数,因为它input channel 是25个,所以它的参数是3 *3 *25=225。

在这里插入图片描述

通过两次convolution,两次Max Pooling,原来是1 *28 *28变为50 *5 *5。flatten的目的就是把50 *5 *5拉直,拉直之后就成了1250维的vector,然后把1250维的vector输入fully connected netwwork。

CNN学到了什么?

很多人常会说:deep learning就是一个黑盒子,learn以后你不知道它得到了什么,所以有很多人不喜欢用这种方法。但还有很多的方法分析的,我们今天来示范一下咋样分析CNN,它到底学到了什么。
在这里插入图片描述

分析input第一个filter是比较容易的,因为一个layer每一个filter就是一个3*3的mmatrix,对应到3 *3的范围内的9个pixel。所以你只要看到这个filter的值就可以知道说:它在detain什么东西,所以第一层的filter是很容易理解的,但是你不知道它在做什么事情的是第二层的filter。在第二层3 *3的filter有50个,但是这些filter的input并不是pixel(3 *3的9个input不是pixel)。而是做完convolution再做Max Pooling的结果。所以这个3 *3的filter就算你把它的weight拿出来,你也不知道它在做什么。另外这个3 *3的filter它考虑的范围并不是3 *3的pixel(9个pixel),而是比9个pxiel更大的范围。不要忘了这3 *3的element的 input是做完convolution再Max Pooling后的结果。所以它实际上在image上看到的范围,是比3 *3还要更大的。

那我们咋样来分析一个filter做的事情是什么呢,以下是一个方法。
在这里插入图片描述

我们知道现在做第二个convolution layer里面的50个filter,每一个filter的output就是一个matrix(11*11的matrix)。假设我们现在把第k个filter拿出来,它就是上图中的矩阵,每一个element我们就叫做 a i j k a_{i j}^k aijk(上标表示这是第k个filter,i,j代表在这个matrix里面的第i row和第j column)。

接下来定义一个东西叫做:“Degree of the activation of the k-th filter",这个值表示:第k个filter有多被active,也就是input和第k个filter有多match。

第k个filter被启动的Degree定义成:这个11*11的 matrix里面全部的 element的summation。(input一张image,然后看这个filter output的这个11 *11的值全部加起来,当做是这个filter被active的程度)

如果我们想知道第k个filter的作用是什么,所以我们就要找一张image,这张image它可以让第k个filter被active的程度最大。
在这里插入图片描述

假设input一张image,我们称之为X,那我们现在的问题就是:找一个x,它可以让我们现在定义的activation Degree: a k a^k ak最大。

这件事情要咋样做到呢?其实是用gradient ascent(梯度上升)你就可以做到这件事(minimize使用gradient descent,maximize使用gradient ascent)

这部分还是蛮神妙的,我们现在是把X当做我们要找的参数用gradient ascent做update,原来在train CNN network neural的时候,input是固定的,model的参数是你需要用gradient descent找出来的,用gradient descent找参数可以让loss被 minimize。但是现在立场是反过来的,现在在这个task里面,model的参数是固定的,我们要让gradient descent 去update这个X,让这个activation function的Degree of the activation是最大的。

在这里插入图片描述
这个是得到的结果,如果我们随便取12个filter出来,每一个filter都去找一张image,这个image可以让那个filter的activation最大。现在有50个filter,你就要去找50张image,它可以让这些filter的activation最大。取前12个filter,可以让它最active的image展示(如下图)。
在这里插入图片描述
这些image有一个共同的特征就是:某种纹路在图上不断的反复。比如说第三张image,上面是有小小的斜条纹,代表着第三个filter的工作就是detain图上有没有斜的条纹。不要忘了每一个filter考虑的范围都只是图上一个小小的范围。所以今天一个图上如果出现小小的斜的条纹的话,这个filter就会被active,这个output的值就会比较大。那今天如果让图上所有的范围通通都出现这个小小的斜条纹的话,那这个时候它的Degree activation会是最大的。(因为第三个filter的工作就是侦测有没有斜的条纹,所以你给它一个完整的数字的时候,它不会最兴奋。你给它都是斜的条纹的时候,它是最兴奋的)

所以你就会发现:每一个filter的工作就是detain某一张pattern。比如说:第三图detain斜的线条,第四图是detain短的直线条,等等。每一个filter所做的事情就是detain不同角度的线条,如果今天input有不同角度的线条,你就会让某一个activation function,某一个filter的output值最大

分析全连接层

在这里插入图片描述
在做完convolution和Max Pooling以后,就要做flatten了,把flatten的结果输入到neural network,最后输出结果。那我们想要知道:在这个neural network里面,每一个neural的工作是什么。

我们要做的事情是这样的:定义第j个neural,它的output叫做 a j a_j aj。接下来我们要做事情就是:找一张image(用gradient ascent的方法找一张X),这个image X你把它丢到neural network里面去,它可以让 a j a_j aj的值被maximize。找到的结果就是这样的(如图)
在这里插入图片描述

随便取前9个neural出来,上图中的9张图丢到CNN里面可以让这9个neural最被active output的值最大

这些图跟刚才所观察到图不太一样,刚才的filter观察到的是类似纹路的图案,在整张图上反复这样的纹路,那是因为每个filter考虑是图上一个小小的range。现在每一个neural,在你做flatten以后,每个neural的工作就是去看整张图,而不是是去看图的一小部分。

在这里插入图片描述
如果考虑的是output呢?(output就是10维,每一维对应一个digit)我们把某一维拿出来,找一张image让那个维度output最大。那我们这个image会是什么样子的呢?

现在我们找一张image,它可以让对应在数字1的output 最大,那么那张image显然就像看起来是数字1。你可以期待说:我们可以用这个方法让machine自动画出数字。
在这里插入图片描述

但是实际上我们得到的结果是这样子的,每一张图分别代表数字0-9。也就是说:我们到output layer对应到0那个neuron,其实是这样的(如下图所示)(如图)
以此类推,可能会有疑惑,为什么是这样子的,是不是程序有bug。为了确定程序没有bug,再做了一个实验是:把上图中每张image都输入CNN里面,然后看它classifier的结果是什么。CNN确定就说:这个是1,这个是,…,这个是8。因为CNN用这张image train,正确率有98,就会判断这个就是8。

这种现象在很多的地方已经被观察到了,实际上neuron network学到东西跟我们人类是不太一样的,也就是说它所学到的东西跟我们人类想象和认知不一样的)。你可以查看这个链接的paper(如图)

让图更像数字

我们有没有办法让这个图看起来更像数字呢?
在这里插入图片描述

想法是这样的:我们有一些关于一张图是不是数字的基本假设,比如说:这些就算你不知道它是什么数字,人类手写出来的就不是这个样子。所以我们应该对x做constraint,我们告诉machine,有些x可能会使y很大但不是数字。我们根据人的power-knowledge就知道,这些x不可能是一些数字。以上图左侧图像为例,图中白色的亮点代表的是有墨水的。

对一个digit来说,白的部分其实是有限的,对于一个数字来说,一整张图的某一个小部分会有笔画,所以我们应该对这个x做一些限制,那么我们可以加上咋样的constraint呢?

假设image里面的每一个pixel用 x i j x_{ij} xij来表示,(每一个image有28 *28的pixel)我们把所有image上 i , j i,j i,j的值取绝对值后加起来。如果你熟悉machine learning的话,这一项就是L1-regularization。然后我们希望说:在找一个x可以让 y i y^i yi最大的同时让 ∣ x i j ∣ |x_{ij}| xij的summation越小越好。也就是我们希望找出的image,大部分的地方是没有涂颜色的,只有非常少的部分是有涂颜色的。

如果我们加上constraint以后我们得到的结果是这样的(如右图所示),跟左边的图比起来,隐约可以看出来它是一个数字。

你如果加上一些额外的constraint,比如说:你希望相邻的pixel 是同样的颜色等等,你应该可以得到更好的结果。其实有更多很好的方法可以让machine generate数字

Deep Dream

在这里插入图片描述

其实constraint的想法就是Deep Dream的精神,Deep Dream是说:如果你给machine一张image,它会在这张image里加上它看到的东西。

咋样做这件事情呢?你先找一张image,然后将这张image丢到CNN中,把它的某一个hidden layer拿出来(vector),它是一个vector(假设这里是:[3.9, -1.5, 2.3…])。接下来把postitive dimension值调大,把negative dimension值调小(正的变的更正,负的变得更负)。你把调节之后的vector当做是新的image的目标(把3.9的值变大,把-1.5的值变得更负,2.3的值变得更大。然后找一张image(modify image)用GD(梯度下降)方法,让它在hidden layer output是你设下的target)。这样做的话就是让CNN夸大化它所看到的东西,本来它已经看到某一个东西了,你让它看起来更像它原来看到的东西。本来看起来是有一点像东西,它让某一个filter有被active,但是你让它被active的更剧烈,也就是夸大化看到的东西。

在这里插入图片描述

如果你把这张image拿去做Deep Dream的话,你看到的结果是这样子的。右边有一只熊,这个熊原来是一个石头(对机器来说,这个石头有点像熊,它就会强化这件事情,所以它就真的变成了一只熊)。Deep Dream还有一个进阶的版本,叫做Deep Style

Deep style

在这里插入图片描述
今天input两张image,让machine去修改,让其中一幅图有另外一张图的风格 (类似于风格迁移)
在这里插入图片描述
得到的结果就是这样子的

在这里插入图片描述
其中做法的精神是这样的:原来的image丢给CNN,然后得到CNN的filter的output,CNN的filter的output代表这张image的content。接下来把呐喊这张图也丢到CNN里面,也得到filter的output。我们并不在意filter的output ,而是在意filter和filter之间的convolution,这个convolution代表了这张image的style。

接下来你用同一个CNN找一张image,这张image它的content像左边这张相片,但同时这张image的style像右边这张相片。你找一张image同时可以maximize左边的图,也可以maximize右边的图。那你得到的结果就是像最底下的这张图。用的就是刚才讲的gradient ascent的方法找一张image,然后maximize这两张图,得到就是底下的这张图。

CNN的应用

围棋

在这里插入图片描述

我们现在CNN已经在很多不同的应用上,而不是只有影像处理上。比如:CNN现在有一个很知名的应用,就是用在下围棋上面。为什么CNN可以用来下围棋上面呢?

我们知道如果让machine来下围棋,你不见得需要用CNN。其实一般的topic neuron network也可以帮我们做到这件事情。你只要learn一个network(也就是找一个function),它的input是棋盘,output是棋盘上的位置。也就是说:你根据这个棋盘的盘式,如果你下一步要落子的话,你落子的位置其实就可以让machine学会。

所以你用Fully-connected feedforward network也可以帮我们做到让machine下围棋这件事情。也就是你只要告诉input是一个19 *19的vector,每一个vector的dimension对应到棋盘上面的每一个位置。machine就可以学会下围棋了。 如果那个位置有一个黑子的话就是1,如果有一个白子的话就是-1,反之就是0。

但是我们这边采用CNN的话,我们会得到更好的performance。我们之前举的例子是把CNN用在影像上面,也就是input是matrix(也就是把19*19的vector表示成19 *19的matrix),然后当做一个image来看,然后让它output 下一步落子的位置就结束了。

在这里插入图片描述

告诉machine说:看到落子在“5之五”,CNN的output就是在“天元”的地方是1,其他地方是0。看到“5之五”和“天元”都有子,CNN的output就是在“五之5”的地方是1,其他地方是0。这个是supervised部分

在这里插入图片描述

现在大家都说“AlphaGo”,都是懂懂的样子。但是自从“AlphaGo”用了CNN以后,大家都觉得说:CNN应该很厉害。所以如果你没有用CNN来处理你的问题,别人就会问你为什么不用CNN来处理问题(比如说:面试的时候),CNN不是比较强吗

什么时候应该用CNN呢image必须有该有的那些特性,在CNN开头就有说:根据那三个观察,所以设计出了CNN这样的架构。在处理image时是特别有效的。为什么这样的架构也同样可以用在围棋上面,是因为围棋有一些特性跟影像处理是非常相似的。

第一个是:在image上面,有一些pattern是要比整张image还要小的多的(比如:鸟喙是要比整张的image要小的多),只需要看那一小的部分就知道那是不是鸟喙。在围棋上也有同样的现象,如图所示,一个白子被三个黑子围住(这就是一个pattern),你现在只需要看这一小小的范围,就可以知道白子是不是没“气”了,不需要看整个棋盘才能够知道这件事情,这跟image是有同样的性质。

在“AlphaGo”里面它的第一个layer filter其实就是用5*5的filter,显然做这个设计的人觉得说:围棋最基本的pattern可能都是在5 *5的范围内就可以被侦测出来,不需要看整个棋牌才能知道这件事情。

接下来我们说image还有一个特性:同样的pattern会出现在不同的regions,而他们代表的是同样的意义,在围棋上可能也会有同样的现象。像如图这个pattern可以出现在左上角,也可以出现在右下角,它们都代表了同样的意义。所以你可以用同一个pattern来处理在不同位置的同样的pattern。所以对围棋来说,是有这两个特性的。

AlphaGo

在这里插入图片描述

但是没有办法让我想通的地方就是第三点,我们可以对一个image做subsampling,把image变为原来的1/4的大小,但是也不会影响你看这张图的样子。因为基于第三点,所以有Max Pooling这个layer。但是对围棋来说,你可以做这件事情吗?你可以舍弃奇数行偶数列吗?这样它还是同一个盘式吗,显然不是的,这个让我相当的困扰。

“AlphaGo”里面如果有用了Max Pooling这个架构,或许这是一个弱点。可以针对这个弱点去攻击它,击败它。但是“AlphaGo”比李世石还强,没有这个显而易见的弱点

有一天我突然领悟到“AlphaGo”的CNN架构里面有什么特别的地方,但在“AlphaGo”Paper里面只说了一句:用CNN架构,但它没有在正文里仔细描述CNN的架构,会不会实际上CNN架构里有什么特别的玄机呢?

在“AlphaGo”Paper的附录里面,描述了neuron network structure,它的input是一个19 *19 *48的image。19 *19是可以理解,因为棋盘就是19 *19。48是咋样来的呢?对于“AlphaGo”来说,它把每一个位置都用48个value来描述。这里面的value包括:我们只要在一个位置来描述有没有白子,有没有黑子;还加上了domain-knowledge,因为不只是说:有没有黑子或者白子,还会看这个位置是不是出于没“气”的状态,等等

如果读完这段你会发现:第一个layer有做 zero pads(零填充)。也就是说:把原来19*19的image外围补上更多的0,让它变成23 *23的image。

第一个hidden layer用的是5*5 filter(总共有k个filter),k的值在Paper中用的是192;stride设为1;使用RLU activation function等等。

然后你就会发现“AlphaGo”是没有用Max Pooling,所以这个neuron network的架构设计就是“运用之妙,存乎一心”。虽然在image里面我们都会用Max Pooling这个架构,但是针对围棋的特性来设计neuron network的时候,我们是不需要Max Pooling这个架构的,所以在“AlphaGo”里面没有这个架构.

语音

在这里插入图片描述

CNN也可以用在其它的task里面,比如说:CNN也用在影像处理上。如图是一段声音,你可以把一段声音表示成Spectrogram(横轴是时间,纵轴是那段时间里面声音的频率),红色代表:在那段时间里那一频率的energy比较大。

这张image其实是我说“你好”,然后看到的Spectrogram。有通过训练的人,看这张image,就知道这句话的内容是什么。

人既然可以看这个image就可以知道是什么样的声音讯号,那我们也可以让机器把这个Spectrogram当做一张image。然后用CNN来判断:input一张image,它是对应什么样的声音讯号。但是神奇的地方是:将Spectrogram输入进CNN里面的时候,在语音上,我们通常只考虑在frequency方向上移动的filter。也就是说:我们的filter是长方形的,其中宽是跟image的宽是一样的,我们在移动filter的时候,我们移这个方向(如图所示)

如果把filter向时间的方向移动的话,结果是没有太大的帮助。这样的原因是:在语音里面,CNN的output还会接其他的东西(比如:LSTM),所以在向时间方向移动是没有太多的帮助。

为什么在频率上的filter会有帮助呢?我们用filter的目的是:为了detain同样的pattern出现在不同的range,我们都可以用同一个的filter detain出来。那在声音讯号上面,男生跟女生发同样的声音(同样说“你好”),Spectrogram看起来是非常不一样的,它们的不同可能只是频率的区别而已(男生的“你好”跟女生的“你好”,它们的pattern其实是一样的)

所以今天我们把filter在frequency direction移动是有效的。当我们把CNN用在application时,你永远要想一想,这个application的特性是什么,根据那个application的特性来design network的structure

文本

在这里插入图片描述

CNN可以用在文字处理上面,这个是从paper截下来的图。在文字处理上面,假设你要做的是:让machine侦测这个词序代表的是积极还是消极。首先input一个word sequence(词序),你把word sequence里面的每一个word都用一个vector来表示。这边的每一个vector代表word本身的sementic(语义),如果两个word含义越接近的话,那它们的vector在高维的空间上就越接近,这个就叫做“wordembedding(词嵌入)”。

当你把每一个word用vector来表示的时候,你把sentence所有的word排在一起,它就变成一张image。你可以把CNN套用在这个image上面。

当我们把CNN用在文字处理上的时候,你的filter其实是这个样子的(如图所示)。它的高跟image是一样的,你把filter沿着句子里面词汇的顺序来移动,然后你就会得到一个vector。不同的filter就会得到不同的vector,然后Max Pooling,然后把Max Pooling的结果丢到fully connect里面,就会得到最后的结果。在文字处理上,filter只在时间的序列上移动,不会在“embedding dimension”这个方向上移动。如果你有做过类似的task(文字处理),知道“embedding dimension”指的是什么,你就会知道在“embedding dimension”反向上移动是没有帮助的,因为在word embedding里面每一个dimension的含义其实是独立的。所以当我们如果使用CNN的时候,你会假设说:第二个dimension跟第一个dimension有某种特别的关系;第四个dimension跟第五个dimension有某种特别的关系。而这个关系是重复的,即这个pattern出现在不同的位置是同样的意思。但是在word embedding里面,不同dimension是独立的(independent)。所以在embedding dimension移动是没有意义的,所以你在做文字处理的时候,你只能在sentence顺序上移动filter。

这个文本处理就是另外的例子。

Reference

在这里插入图片描述

如果你想知道更多visualization事情的话,以上是一些reference。

在这里插入图片描述

如果你想要用Degree的方法来让machine自动产生一个digit,这件事是不太成功的,但是有很多其它的方法,可以让machine画出非常清晰的图。这里列了几个方法,比如说:PixelRNN,VAE,GAN来給参考.


总结

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值