Machine Learning —— Convolutional Neural Network

Machine Learning —— Convolutional Neural Network

Why CNN for Image?

CNN V.s. DNN

我们当然可以用一般的neural network来做影像处理,不一定要用CNN,比如说,你想要做图像的分类,那你就去train一个neural network,它的input是一张图片,你就用里面的pixel来表示这张图片,也就是一个很长很长的vector,而output则是由图像类别组成的vector,假设你有1000个类别,那output就有1000个dimension

但是,我们现在会遇到的问题是这样子:实际上,在train neural network的时候,我们会有一种期待说,在这个network structure里面的每一个neuron,都应该代表了一个最基本的classifier;事实上,在文献上,根据训练的结果,也有很多人得到这样的结论,举例来说,下图中:
在这里插入图片描述

  • 第一个layer的neuron,它就是最简单的classifier,它做的事情就是detect有没有绿色出现、有没有黄色出现、有没有斜的条纹出现等等
  • 那第二个layer,它做的事情是detect更复杂的东西,根据第一个layer的output,它如果看到直线横线,就是窗框的一部分;如果看到棕色的直条纹就是木纹;看到斜条纹加灰色的,这个有可能是很多东西,比如说,轮胎的一部分等等
  • 再根据第二个hidden layer的output,第三个hidden layer会做更复杂的事情,比如它可以知道说,当某一个neuron看到蜂巢,它就会被activate;当某一个neuron看到车子,它就会被activate;当某一个neuron看到人的上半身,它就会被activate等等

那现在的问题是这样子:当我们直接用一般的fully connected的feedforward network来做图像处理的时候,往往会需要太多的参数

举例来说,假设这是一张100100的彩色图片,它的分辨率才100100,那这已经是很小张的image了,然后你需要把它拉成一个vector,总共有1001003个pixel(如果是彩色的图的话,每个pixel其实需要3个value,即RGB值来描述它的),把这些加起来input vectot就已经有三万维了;如果input vector是三万维,又假设hidden layer有1000个neuron,那仅仅是第一层hidden layer的参数就已经有30000*1000个了,这样就太多了

所以,CNN做的事情其实是,来简化这个neural network的架构,我们根据自己的知识和对图像处理的理解,一开始就把某些实际上用不到的参数给过滤掉,我们一开始就想一些办法,不要用fully connected network,而是用比较少的参数,来做图像处理这件事情,所以CNN其实是比一般的DNN还要更简单的

虽然CNN看起来,它的运作比较复杂,但事实上,它的模型比DNN还要更简单,我们就是用prior knowledge,去把原来fully connected的layer里面的一些参数拿掉,就变成CNN

Three Property for CNN theory base

为什么我们有可能把一些参数拿掉?为什么我们有可能只用比较少的参数就可以来做图像处理这件事情?下面列出三个对影像处理的观察:(这也是CNN架构提出的基础所在!!!)

Some patterns are much smaller than the whole image

在影像处理里面,如果在network的第一层hidden layer里,那些neuron要做的事情是侦测有没有一种东西、一种pattern(图案样式)出现,那大部分的pattern其实是比整张image要小的,所以对一个neuron来说,想要侦测有没有某一个pattern出现,它其实并不需要看整张image,只需要看这张image的一小部分,就可以决定这件事情了
在这里插入图片描述
举例来说,假设现在我们有一张鸟的图片,那第一层hidden layer的某一个neuron的工作是,检测有没有鸟嘴的存在(你可能还有一些neuron侦测有没有鸟嘴的存在、有一些neuron侦测有没有爪子的存在、有一些neuron侦测有没有翅膀的存在、有没有尾巴的存在,之后合起来,就可以侦测,图片中有没有一只鸟),那它其实并不需要看整张图,因为,其实我们只要给neuron看这个小的红色杠杠里面的区域,它其实就可以知道说,这是不是一个鸟嘴,对人来说也是一样,只要看这个小的区域你就会知道说这是鸟嘴,所以,每一个neuron其实只要连接到一个小块的区域就好,它不需要连接到整张完整的图,因此也对应着更少的参数

The same patterns appear in different regions

同样的pattern,可能会出现在image的不同部分,但是它们有同样的形状、代表的是同样的含义,因此它们也可以用同样的neuron、同样的参数,被同一个detector检测出来
在这里插入图片描述
我们可以要求这些功能几乎一致的neuron共用一组参数,它们share同一组参数就可以帮助减少总参数的量

Subsampling the pixels will not change the object

在这里插入图片描述
我们可以利用subsampling这个概念把image变小,从而减少需要用到的参数量

The whole CNN structure

整个CNN的架构是这样的:

  • 首先,input一张image以后,它会先通过Convolution的layer
  • 接下来做Max Pooling这件事
  • 然后再去做Convolution,再做Maxi Pooling…
  • 这个process可以反复进行多次(重复次数需要事先决定)

这就是network的架构,就好像network有几层一样,你要做几次convolution,做几次Max Pooling,在定这个network的架构时就要事先决定好

当你做完先前决定的convolution和max pooling的次数后,你要做的事情是Flatten,做完flatten以后,你就把Flatten output丢到一般的Fully connected network里面去,最终得到影像辨识的结果
在这里插入图片描述
我们基于之前提到的三个对影像处理的观察,设计了CNN这样的架构

  • 第一个是要侦测一个pattern,你不需要看整张image,只要看image的一个小部分;
  • 第二个是同样的pattern会出现在一张图片的不同区域;
  • 第三个是我们可以对整张image做subsampling
    在这里插入图片描述

Convolution

假设现在我们network的input是一张6*6的image,图像是黑白的,因此每个pixel只需要用一个value来表示,而在convolution layer里面,有一堆Filter,这边的每一个Filter,其实就等同于是Fully connected layer里的一个neuron

Property 1

在这里插入图片描述
每一个Filter其实就是一个matrix,这个matrix里面每一个element的值,就跟那些neuron的weight和bias一样,是network的parameter,它们具体的值都是通过Training data学出来的,而不是人去设计的

所以,每个Filter里面的值是什么,要做什么事情,都是自动学习出来的,上图中每一个filter是33的size,意味着它就是在侦测一个33的pattern,当它侦测的时候,并不会去看整张image,它只看一个3*3范围内的pixel,就可以判断某一个pattern有没有出现,这就考虑了property 1

Property 2

这个filter是从image的左上角开始,做一个slide window,每次向右挪动一定的距离,这个距离就叫做stride,由你自己设定,每次filter停下的时候就跟image中对应的33的matrix做一个内积(相同位置的值相乘并累计求和),这里假设stride=1,那么我们的filter每次移动一格,当它碰到image最右边的时候,就从下一行的最左边开始重复进行上述操作,经过一整个convolution的process,最终得到下图所示的红色的44 matrix
在这里插入图片描述
观察上图中的Filter1,它斜对角的地方是1,1,1,所以它的工作就是detect有没有连续的从左上角到右下角的1,1,1出现在这个image里面,检测到的结果已在上图中用蓝线标识出来,此时filter得到的卷积结果的左上和左下得到了最大的值,这就代表说,该filter所要侦测的pattern出现在image的左上角和左下角

Feature Map

在一个convolution的layer里面,它会有一打filter,不一样的filter会有不一样的参数,但是这些filter做卷积的过程都是一模一样的,你把filter2跟image做完convolution以后,你就会得到另外一个蓝色的44 matrix,那这个蓝色的44 matrix跟之前红色的4*4matrix合起来,就叫做Feature Map(特征映射),有多少个filter,对应就有多少个映射后的image
在这里插入图片描述
CNN对不同scale的相同pattern的处理上存在一定的困难,由于现在每一个filter size都是一样的,这意味着,如果你今天有同一个pattern,它有不同的size,有大的鸟嘴,也有小的鸟嘴,CNN并不能够自动处理这个问题;DeepMind曾经发过一篇paper,上面提到了当你input一张image的时候,它在CNN前面,再接另外一个network,这个network做的事情是,它会output一些scalar,告诉你说,它要把这个image的里面的哪些位置做旋转、缩放,然后,再丢到CNN里面,这样你其实会得到比较好的performance

Colorful image

我们知道彩色的image就是由RGB组成的,所以一个彩色的image,它就是好几个matrix叠在一起,是一个立方体
在这里插入图片描述
RGB这三个颜色来表示一个pixel的话,那你的input就是366,你的filter就是333,你的filter的高就是3,你在做convolution的时候,就是把这个filter的9个值跟这个image里面的9个值做内积,可以想象成filter的每一层都分别跟image的三层做内积,得到的也是一个三层的output,每一个filter同时就考虑了不同颜色所代表的channel

Convolution V.s. Fully connected

filter是特殊的“neuron”

convolution这件事情,其实就是fully connected的layer把一些weight拿掉而已,下图中绿色方框标识出的feature map的output,其实就是hidden layer的neuron的output
在这里插入图片描述
如下图所示,我们在做convolution的时候,把filter放在image的左上角,然后再去做inner product,得到一个值3;这件事情等同于,我们现在把这个image的6*6的matrix拉直变成右边这个用于input的vector,然后,你有一个红色的neuron,这些input经过这个neuron之后,得到的output是3
在这里插入图片描述

每个“neuron”只检测image的部分区域

作为对比,Fully connected的neuron是必须连接到所有36个input上的,但是,我们现在只用连接9个input,因为我们知道要detect一个pattern,不需要看整张image,看9个input pixel就够了,所以当我们这么做的时候,就用了比较少的参数

“neuron”之间共享参数

当我们把filter做stride = 1的移动的时候,会发生什么事呢?此时我们通过filter和image matrix的内积得到另外一个output值-1,我们假设这个-1是另外一个neuron的output,那这个neuron会连接到哪些input呢?下图中这个框起来的地方正好就对应到pixel 2,3,4,pixel 8,9,10跟pixel 14,15,16
在这里插入图片描述
当我们做这个convolution的时候,首先我们把每一个neuron前面连接的weight减少了,然后我们强迫某些neuron(比如上图中output为3和-1的两个neuron),它们一定要共享一组weight,虽然这两个neuron连接到的pixel对象各不相同,但它们用的weight都必须是一样的,等于filter里面的元素值,这件事情就叫做weight share

总结

  • 当filter在image matrix上移动做convolution的时候,每次移动做的事情实际上是去检测这个地方有没有某一种pattern
  • 对于Fully connected layer来说,它是对整张image做detection的,因此每次去检测image上不同地方有没有pattern其实是不同的事情,所以这些neuron都必须连接到整张image的所有pixel上,并且不同neuron的连线上的weight都是相互独立的
  • 那对于convolution layer来说,首先它是对image的一部分做detection的,因此它的neuron只需要连接到image的部分pixel上,对应连线所需要的weight参数就会减少;
  • 其次由于是用同一个filter去检测不同位置的pattern,所以这对convolution layer来说,其实是同一件事情
  • 因此不同的neuron,虽然连接到的pixel对象各不相同,但是在“做同一件事情”的前提下,也就是用同一个filter的前提下,这些neuron所使用的weight参数都是相同的,通过这样一张weight share的方式,再次减少network所需要用到的weight参数

Max Pooling

Operation of max pooling

相较于convolution,max pooling是比较简单的,它就是做subsampling,根据filter 1,我们得到一个44的matrix,根据filter 2,你得到另外一个44的matrix

我们把output四个分为一组,每一组里面通过选取平均值或最大值的方式,把原来4个value合成一个 value,这件事情相当于在image每相邻的四块区域内都挑出一块来检测,这种subsampling的方式就可以让你的image缩小!
在这里插入图片描述

Convolution + Max Pooling

做完一次convolution加一次max pooling,我们就把原来66的image,变成了一个22的image;至于这个2*2的image,它每一个pixel的深度,也就是每一个pixel用几个value来表示,就取决于你有几个filter,如果你有50个filter,就是50维,像下图中是两个filter,对应的深度就是两维

这是一个新的比较小的image,它表示的是不同区域上提取到的特征,实际上不同的filter检测的是该image同一区域上的不同特征属性,所以每一层channel(通道)代表的是一种属性,一块区域有几种不同的属性,就有几层不同的channel,对应的就会有几个不同的filter对其进行convolution操作
在这里插入图片描述
这件事情可以repeat很多次,你可以把得到的这个比较小的image,再次进行convolution和max pooling的操作,得到一个更小的image,依次类推

你这边做完一次convolution,得到25个feature map之后再做一次convolution,还是会得到25个feature map,因为convolution在考虑input的时候,是会考虑深度的,它并不是每一个channel分开考虑,而是一次考虑所有的channel,所以,你convolution这边有多少个filter,再次output的时候就会有多少个channel

因此你这边有25个channel,经过含有25个filter的convolution之后output还会是25个channel,只是这边的每一个channel,它都是一个cubic(立方体),它的高有25个value那么高

Flatten

做完convolution和max pooling之后,就是FLatten和Fully connected Feedforward network的部分

Flatten的意思是,把左边的feature map拉直,然后把它丢进一个Fully connected Feedforward network,然后就结束了,也就是说,我们之前通过CNN提取出了image的feature,它相较于原先一整个image的vetor,少了很大一部分内容,因此需要的参数也大幅度地减少了,但最终,也还是要丢到一个Fully connected的network中去做最后的分类工作
在这里插入图片描述

What does CNN learn?

在这里插入图片描述
要分析第一个convolution的filter是比较容易的,因为第一个convolution layer里面,每一个filter就是一个33的matrix,它对应到33范围内的9个pixel,所以你只要看这个filter的值,就可以知道它在detect什么东西,因此第一层的filter是很容易理解的

第二层的filter,它们是50个同样为33的filter,但是这些filter的input并不是pixel,而是做完convolution再做Max pooling的结果,因此filter考虑的范围并不是33=9个pixel,而是一个长宽为3*3,高为25的cubic,filter实际在image上看到的范围是远大于9个pixel的

what does filter do

我们知道在第二个convolution layer里面的50个filter,每一个filter的output就是一个11*11的matrix,假设我们现在把第k个filter的output拿出来,如下图所示,这个matrix里的每一个element,我们叫它 a i j k a^k_{ij} aijk,上标k表示这是第k个filter,下标ij表示它在这个matrix里的第i个row,第j个column
在这里插入图片描述
接下来我们define一个 a k a^k ak叫做Degree of the activation of the k-th filter,直观来讲就是描述现在input的东西跟第k个filter有多接近,它对filter的激活程度有多少

第k个filter被启动的degree a k a^k ak-----它与input进行卷积所输出的output里所有element的summation,以上图为例,就是这11*11的output matrix里所有元素之和,用公式描述如下: a k = ∑ i = 1 11 ∑ j = 1 11 a^k=\sum\limits_{i=1}^{11}\sum\limits_{j=1}^{11} ak=i=111j=111

我们想要知道第k个filter的作用是什么,那我们就要找一张image,这张image可以让第k个filter被activate的程度最大;于是我们现在要解的问题是,找一个image x,它可以让我们定义的activation的degree a k a^k ak最大,即: x ∗ = a r g m a x x a k x^*=arg \mathop{max}\limits_{x} a^k x=argxmaxak

之前我们求minimize用的是gradient descent,那现在我们求Maximum用gradient ascent(梯度上升法)就可以做到这件事

我们现在是把input x作为要找的参数,对它去用gradient descent或ascent进行update,原来在train CNN的时候,input是固定的,model的参数是要用gradient descent去找出来的;但是现在这个立场是反过来的,在这个task里面model的参数是固定的,我们要用gradient ascent去update这个x,让它可以使degree of activation最大
在这里插入图片描述
50个filter理论上可以分别找50张image使对应的activation最大,这里仅挑选了其中的12张image作为展示,这些image有一个共同的特征,它们里面都是一些反复出现的某种texture(纹路)

因此每个filter的工作就是去detect某一种pattern,detect某一种线条,上图所示的filter所detect的就是不同角度的线条,所以今天input有不同线条的话,某一个filter会去找到让它兴奋度最高的匹配对象,这个时候它的output就是最大的

what does neuron do

做完convolution和max pooling之后,会将结果用Flatten展开,然后丢到Fully connected的neural network里面去
在这里插入图片描述
我们定义第j个neuron的output就是 a j a_j aj,接下来就用gradient ascent的方法去找一张image x,把它丢到neural network里面就可以让 a j a_j aj的值被maximize,即: x ∗ = a r g m a x x a j x^*=arg\mathop{max}\limits_{x}a_j x=argxmaxaj
在这里插入图片描述
找到的结果如上图所示,同理这里仅取出其中的9张image作为展示,你会发现这9张图跟之前filter所观察到的情形是很不一样的,刚才我们观察到的是类似纹路的东西,那是因为每个filter考虑的只是图上一部分的vision,所以它detect的是一种texture;但是在做完Flatten以后,每一个neuron不再是只看整张图的一小部分,它现在的工作是看整张图,所以对每一个neuron来说,让它最兴奋的、activation最大的image,不再是texture,而是一个完整的图形

what about output

接下来我们考虑的是CNN的output,由于是手写数字识别的demo,因此这里的output就是10维,我们把某一维拿出来,然后同样去找一张image x,使这个维度的output值最大,即: x ∗ = a r g m a x x y i x^*=arg\mathop{max}\limits_{x}y^i x=argxmaxyi

你可以想象说,既然现在每一个output的每一个dimension就对应到一个数字,那如果我们去找一张image x,它可以让对应到数字1的那个output layer的neuron的output值最大,那这张image显然应该看起来会像是数字1

但实际上,我们得到的结果是这样子,如下图所示
在这里插入图片描述
我们要对这个x做一些regularization,我们要对找出来的x做一些constraint(限制约束),我们应该告诉machine说,虽然有一些x可以让你的y很大,但是它们不是数字

最简单的想法是说,画图的时候,白色代表的是有墨水、有笔画的地方,而对于一个digit来说,整张image上涂白的区域是有限的,像上面这些整张图都是白白的,它一定不会是数字

假设image里的每一个pixel都用 x i j x_{ij} xij 表示,我们把所有pixel值取绝对值并求和,也就是 ∑ i , j ∣ x i j ∣ \sum\limits_{i,j}|x_{ij}| i,jxij,这一项就是之前提到的L1 regularization,再用 y i y^i yi 减去这一项,得到:

x ∗ = a r g m a x x ( y ∗ − ∑ i , j ∣ x i j ∣ ) x^*=arg\mathop{max}\limits_{x}(y^*-\sum\limits_{i,j}|x_{ij}|) x=argxmax(yi,jxij)

这次我们希望再找一个input x,它可以让 y i y^i yi最大的同时,也要让 ∣ x i j ∣ |x_{ij}| xij的summation越小越好,也就是说我们希望找出来的image,大部分的地方是没有涂颜色的,只有少数数字笔画在的地方才有颜色出现

加上这个constraint以后,得到的结果会像下图右侧所示一样,已经隐约有些可以看出来是数字的形状了
在这里插入图片描述

Deep Dream

Deep Dream是说,如果你给machine一张image,它会在这个image里面加上它看到的东西

找一张image丢到CNN里面去,然后你把某一个convolution layer里面的filter或是fully connected layer里的某一个hidden layer的output拿出来,它其实是一个vector;接下来把本来是positive的dimension值调大,negative的dimension值调小,也就是让正的更正,负的更负,然后把它作为新的image的目标

总体来说就是使它们的绝对值变大,然后用gradient descent的方法找一张image x,让它通过这个hidden layer后的output就是你调整后的target,这么做的目的就是,让CNN夸大化它看到的东西——make CNN exaggerates what is sees

如果某个filter有被activate,那你让它被activate的更剧烈,CNN可能本来看到了某一样东西,那现在你就让它看起来更像原来看到的东西,这就是所谓的夸大化
在这里插入图片描述

Deep Style

如果今天你input一张image,Deep Style做的事情就是让machine去修改这张图,让它有另外一张图的风格

这里仅讲述Deep Style的大致思路,你把原来的image丢给CNN,得到CNN filter的output,代表这样image里面有什么样的content,然后你把呐喊这张图也丢到CNN里面得到filter的output,注意,我们并不在于一个filter output的value到底是什么,一个单独的数字并不能代表任何的问题,我们真正在意的是,filter和filter的output之间的correlation,这个correlation代表了一张image的style
在这里插入图片描述
接下来你就再用一个CNN去找一张image,这张image的content像左边的图片,比如这张image的filter output的value像左边的图片;同时让这张image的style像右边的图片,所谓的style像右边的图片是说,这张image output的filter之间的correlation像右边这张图片

最终你用gradient descent找到一张image,同时可以maximize左边的content和右边的style,它的样子就像上图左下角所示

More Application——Speech、Text

Speech

CNN也可以用在很多其他的task里面,比如语音处理上,我们可以把一段声音表示成spectrogram,spectrogram的横轴是时间,纵轴则是这一段时间里声音的频率

下图中是一段“你好”的音频,偏红色代表这段时间里该频率的energy是比较大的,也就对应着“你”和“好”这两个字,也就是说spectrogram用颜色来描述某一个时刻不同频率的能量

我们也可以让机器把这个spectrogram就当作一张image,然后用CNN来判断说,input的这张image对应着什么样的声音信号,那通常用来判断结果的单位,比如phoneme,就是类似音标这样的单位
在这里插入图片描述
当我们把一段spectrogram当作image丢到CNN里面的时候,在语音上,我们通常只考虑在frequency(频率)方向上移动的filter,我们的filter就像上图这样,是长方形的,它的宽就跟image的宽是一样的,并且filter只在Frequency即纵坐标的方向上移动,而不在时间的序列上移动

CNN的output后面都还会再接别的东西,比如接LSTM之类,它们都已经有考虑typical的information,所以你在CNN里面再考虑一次时间的information其实没有什么特别的帮助,但是为什么在频率上 的filter有帮助呢?

我们用CNN的目的是为了用同一个filter把相同的pattern给detect出来,在声音讯号上,虽然男生和女生说同样的话看起来这个spectrogram是非常不一样的,但实际上他们的不同只是表现在一个频率的shift而已(整体在频率上的位移),男生说的“你好”跟女生说的“你好”,它们的pattern其实是一样的,比如pattern是spectrogram变化的情形,男生女生的声音的变化情况可能是一样的,它们的差别可能只是所在的频率范围不同而已,所以filter在frequency的direction上移动是有效的

Text

假设你的input是一个word sequence,你要做的事情是让machine侦测这个word sequence代表的意思是positive的还是negative的

首先你把这个word sequence里面的每一个word都用一个vector来表示,vector代表的这个word本身的semantic (语义),那如果两个word本身含义越接近的话,它们的vector在高维的空间上就越接近,这个东西就叫做word embedding(词嵌入向量)
在这里插入图片描述

  • 把一个sentence里面所有word的vector排在一起,它就变成了一张image,你把CNN套用到这个image上
  • 那filter的样子就是上图蓝色的matrix,它的高和image的高是一样的
  • 把filter沿着句子里词汇的顺序来移动,每个filter移动完成之后都会得到一个由内积结果组成的vector
  • 不同的filter就会得到不同的vector,接下来做Max pooling
  • 然后把Max pooling的结果丢到fully connected layer里面,你就会得到最后的output

与语音处理不同的是,在文字处理上,filter只在时间的序列(按照word的顺序)上移动,而不在这个embedding的dimension上移动;因为在word embedding里面,不同dimension是independent的,它们是相互独立的,不会出现有两个相同的pattern的情况,所以在这个方向上面移动filter,是没有意义的

conclusion

本文的重点在于CNN的theory base,也就是What is CNN?What does CNN do?Why CNN?总结起来就是三个property、两个架构和一个理念,这也是使用CNN的条件基础:

三个property

  • Some patterns are much smaller than the whole image ——property 1
  • The same patterns appear in different regions ——property 2
  • Subsampling the pixels will not change the object ——property 3

两个架构

  • convolution架构:针对property 1和property 2
  • max pooling架构:针对property 3

参考

https://sakura-gh.github.io/ML-notes/ML-notes-html/12_Convolutional-Neural-Network-part2.html

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值