卷积神经网络学习笔记

一、引言

人大脑处理图像的第一步是对边界和形状的识别,图像分类到图像识别。

二、K-近邻算法

1 .监督学习,是一种即时分类非参数算法,对测试集中的每一张图片,遍历训练集,计算两张图片的相似度,相似度的计算方法为计算每个对应像素之间的距离(所谓的距离可能使用欧氏距离或曼哈顿距离),然后相加,最终得到相似度最小的K张图片,从而根据标签占比得到最终标签(即分类)。

2.该算法同样可用于回归,例如根据k个近似数据对相应特征进行加权从而得到预测值,再与实际值比较,然后对参数进行调整。

3.该算法缺点在于计算量随着训练样本数目的增加而增加。同时相似度的计算(只计算对应像素的距离)使其泛化程度较低(图片的transform等等),优点是不需要训练。

三、线性分类器

1.有参数学习算法,假设训练样本规格为512×512,要分类的标签为5个,那么要训练的模型就有(512×512)×5个权值w(分别对应图片的每一个像素)以及5个偏置值b。

2.训练过程为:图片所有像素值的加权和与b相比较,从而得到各个标签的分类概率。

3.如果将每种标签的所有权值还原成一张权值图片(这里有5张512×512的图片),假设图片为单通道,那么权值图片中某一处像素值的高低就代表对输入图片在此位置的激活程度。

4.这种线性分类器,对于每一种分类标签来说,只是单模型分类,举个识别马的例子,马头向左与向右都应该被识别出来,但是这需要体现在一张权值图片中,因此识别马的权值图片中可能出现一只拥有两个头的马。而神经网络则不存在这种问题。

四、线性分类器的损失函数(Multiclass SVM Loss)

1.输入一张训练样本,当计算出每个分类的score后(由我们所要训练的函数得到),使用损失函数计算损失,计算公式为:令scores中正确分类的score为rs,分别用其余非正确score减去rs得到s,再max(0,s+1),最终相加,在除以标签的个数,最终就得到了loss值。这里的max(0,s)表示如果非正确score小于rs,则置为0,表示不对loss结果产生影响,这里1是一个安全参数,若非正确score虽然比rc小,但十分接近,仍然会对loss结果产生影响,这里的1只是随便设的,需要根据score来设定。

2.在这里是直接计算非正确score与rs的差值,也可以使用差值的平方。

3.还有一个知识点就是损失函数的正则化,就是在损失函数末加上l*R(w),R(w)有多种形式,一般使用所有W平方的和,正则化的作用是将W值的分布的影响加入到loss函数中,换句话说,加入正则项的话,即使score一样,但R(w)却不一定一样,那么loss结果也就不一样。我觉得有一个描述特别形象,正则化就相当于和损失函数进行对抗,它努力使权值关注图像中的大多数像素,在视频中有人说也许只关注部分效果会更好,的确训练样本的效果也许会更好,但是关注更多点可以增强泛化能力,可以使模型适用于更多种类的测试样本。

五、线性分类器的损失函数(Softmax Classifier,即一般性的逻辑斯特回归)

1、得到各个标签的score之后,使scores分别作为e的指数,得到scoresN,再分别计算scoresN中各自的占比得到scoresNN,最后再对scoresNN中的数进行log运算(10为底)最终得到scoresNNN,取出其中的正确分类的数值就是SoftmaxClassifier的loss值。

2.进行log操作是因为scoresNN中的正确分类的比例如果很小的话,那么log的结果就会很大,即loss值很大。

六、Softmax与SVM的区别

1.SVM具有附加的稳定性,因为当错误score减去正确score的值小于安全系数的话,就会置为0,从而忽略错误概率,而Softmax中,即使错误score的评分远小于正确score,它也会将错误概率计算到loss中,因此SVM对于接近分类边界的样本更加敏感。

七、优化方法(SGD,即随机梯度下降)

1.所谓优化就是通过改变W来降低Loss的过程。 2.SGD过程就是选择一个batch-size(一般为32,64,256等等),不能太大,这样是为了gpu内存着想,然后计算梯度值,再使每个w减去(-步长*梯度值),直到收敛。 3.步长就是下降速率,是一个超参数,一般随着训练过程不断减小,如果一直很小的话,迭代次数会增加,耗时长,并且会误入局部最小值的坑中无法自拔。但在神经网络中是不会出现局部最小值的,因为神经网络的参数数量实在是太多了,因此有上亿个方向可以进行下降,所以不存在陷在局部最小值的状况。

八、线性分类器总结

1.无法直接对像素进行操作,因此需要对输入数据进行特征提取和预处理。(Weka中可以自己试试,只需要特征提取就行了) 2.神经网络不需要特征提取了,能直接输入像素。

九、正向传播与反向传播算法

1.正向传播就是根据输入经过一系列运算门得出结果。

2.整个神经网络可以看成由许多有序的数据层组成,层与层之前是各种门运算,反向传播就是为了计算每一个数据层的梯度,所谓的梯度就是当前数据层对最终结果产生影响的速率大小,如果梯度为3,那么表明如果当前数据层数值加一,最终结果就会加3.

3.计算梯度的方法:从网络末端往前计算梯度,假设表达式为f=(x+y)z,输入x=1,y=2,z=3,那么末层就是计算(x+y)z的梯度,就是f的梯度,就是对f求导,梯度肯定就是1了,假设前面一层是x+y与z,正传播时x+y=3,z=3,那么对x+y求导等于3,在此特别要注意的是,根据链式法则,每一层的梯度等于当前局部梯度乘以后一层的梯度,那么x+y的梯度就是31=3,同理z的梯度也是3.

4.层与层之间的运算可能不是单一的,可以把多种运算放到一起,然后输出一个层。

5.输入层的局部梯度恒为1,输出层的梯度恒为1,如果每一层是由前面若干个层相加得来的,那么前面的层的梯度都等于当前层并且加法运算前面的层的局部梯度也是恒等于1的,如此看来,加法运算具有梯度共享的功能,换句话说,加法运算使得前面两个层可以拥有相同的梯度,即对最终结果产生相同的影响。无独有偶,不同的运算拥有不同的功能,如max运算只会输出最大数值的那个层,意思就是把数值小的那个层的梯度设为0,那么这就实现了路由的效果。

6.通过第5条所说的概念,可以想到,神经网络不仅仅再局限为描述一个表达式了,它可以看做是对输入数据的一系列运算。如果一个数据层将被同时用作于两个运算,那么它将拥有两条分支,每条分支都会产生相应的梯度,那么当前梯度的梯度就是两条分支梯度之和。

7.Sigmoid激活函数的缺点是速度较慢,且当输入数据处于函数两头时,它的局部梯度将接近于0,且输出不是0就是1,这会出现所谓的梯度消失现象,因为根据链式法则,一个接近于0的局部梯度乘以前面的梯度会使结果十分小,那么修正参数的速度就会非常慢。

8.根据经验,预处理数据时,应该使数据关于原点对称,如在f=wx+b中,如果输入的x全为正或负,那么w的梯度就全为正或负,因为wx中对w求偏导的结果为x。

9.ReLu激活函数:速度十分快,约为sigmoid的6倍。>0时不会饱和,如果输入大于0,则会直接传播梯度(梯度为1),输入小于0时,正向传播输出为0,梯度也为0,相当于被屏蔽了。

10.数据预处理:在图像中,一般只需中心化,就是求出图像每个通道的均值,会得到一张纯色的均值图像,然后让原图减去均值图像。机器学习中会用到归一化,而图像像素(rgb)总是在0-255中,所以不需要。

11.权值的初始化:不能全为0,否则所有的神经元都在做同样的事情,传播的梯度也是一样的,因为w=0,wx=0,输出只为b。 当使用tanh作为激活函数时,tanh是中心对称函数,我们使用均值为0,方差为0.01来初始化权值,由于权值很小,所以每个神经元的输出都很小,那么在反向传播中,w的梯度就等于x的值,然而每个x的输入都十分小,那么w的梯度也就十分小,当求x的梯度时(将乘以前面的局部梯度),由于初始化时w的值很小,那么x的梯度也很小,这直接导致前面层的局部梯度将乘以一个很小的值,最终导致所有w的梯度都很小,这就是梯度弥散。当我们使用均值为0,方差为1来初始化权值时,由于权值过大,在tanh激活函数中将会饱和,因此每个神经元的输出不是1就是-1,并且此时梯度为0,所以也会导致梯度弥散。

12.BN(Batch Normalization)层,一般放在非线性层前面,用于将输入gaussian unit(方差为1,均值为0) ,并且还可以加权和偏移,可以先设置成1和0,然后再改变。通过BN来避免出现梯度弥散和爆炸,它减少了算法对合理的初始化的依赖性。并且产生了正则化的效果。根据我的初步理解,BN就是为了让人们不再为了这样初始化而苦恼,BN配合Sigmoid激活函数效果更好。

13.超参数的取样要在对数空间中进行,当神经网络不是很小时,局部最优解不再是一个问题。

14.Momentum Update,与SGD相比,这种方式更加快。 SGD中权值的更新方式为x+=-learning_ratedx, Momentum Update中更新方式为x+=mu *v-learning_ratedx 在这里,mu是一个超参数,其功能类似于阻尼系数,-learning_ratedx就相当于加速度,v一般会初始化为0,实际上,我觉得它与SGD最大的不同就是它是于迭代次数息息相关的,迭代次数多了,速度必然会大幅度减小,最终会变得极为缓慢(指数级衰减),而SGD由于只会朝着最优解前进,不仅在前期可能会发生震荡,而且接近谷底时也不会缓慢下来。

15.NAG(Nesterov Accelerated Gradient) 与Momentum不同的是,它不计算当前位置的梯度,而是计算预测位置的梯度,然后在计算Momentum梯度与预测梯度的矢量和来作为最终的梯度。它的收敛速度要比Momentum更快。

16 . AdaGrad update 这里写图片描述 如图所示,这种更新方式最大的特点是每个参数都拥有自己的自适应学习速率,cache的值是每次迭代的梯度的平方和,所以当累积的梯度较少时,分母就会比较小,那么学习速度就很快,反之同理。这里的1e-7是平滑因子,为了防止分母为0。 RMSProp update 这里写图片描述 由于AdaGrad update随着迭代次数变多,梯度的不断累积会让分母变得很大,最终参数的更新将会停止,为了防止这种情况的发生,RMSProp update增加了衰减参数decay_rate,使得参数的更新一直进行。

17.AdamUpdate 就是将RMSProp和Momentum结合起来,这部分我完全没听懂,不过这是最常使用的方法。Eve是Adam的升级版,他包含了学习率退火算法。

18.除了一阶优化(只使用梯度),还有二阶优化(梯度和损失函数曲面弯曲度),这部分没详细讲,我也没听懂。

19.Dropout(随机失活) 通过随机数使某一个隐含层随机失活,前向和反向传播均需要随机失活。随机失活使用的原因,防止过拟合,由于神经元的失活是随机的,所以这可以使特征的识别更加多样,避免依赖于某一个或几个神经元。另一个解释是,每一次随机失活,就会产生一个网络子集,每一次训练,都是一个网络子集使用一个数据进行训练,这些子集是交叉(局部数据共享)的,因此整个神经网络就可以看作是许多个子集的结合。 在训练阶段我们使用随机失活,可是在测试阶段中我们不使用,这就导致了测试阶段中的数据整体要比训练阶段大一倍(这里的dropout是使一半的神经元失活),因为测试阶段用到了所有的神经元,解决方法有两种:1.测试阶段的每个神经元的激活函数除以相应的倍数,这里是2。2.训练阶段每个神经元的激活函数乘以相应倍数。

十、卷积神经网络

过滤器的规格应与上一层的数据规格相同,点积运算时要把所有的通道的点乘过后的数据加起来作为结果,这一点很关键,意思是每一个过滤器都把前一层的所有的通道结合成一张图,如32×32×3通过5×5×3得到28×28,三个通道合并成了一个通道。当使用1×1作为过滤器时,相当于对纵深进行点积。池化层只会减小长宽,不会减小维度。网络的最后是全连接层,把所有维度的图像展开成列向量,然后分别计算每个分类的评分。 在全连接层中,有几个分类,就用几个神经元,且随机失活只在全连接层中使用。

十一、迁移学习之物体定位与检测

1.通过滑动窗的方法来强化效果(就是通过计算在原图上不同位置的输入来得到多个类分数和定位,在结合起来得到更精确的输出),例如神经网络的输入规格为100100,而原图片为400 400,那么不断滑动输入图像,从而得到不同的类分数和定位(方框),最终通过一些方法合并,从而得到最终的类分数和定位。 通过将全连接层看成卷积层,这样我们可以在不同大小的图片上使用相同的计算过程,大大提高了效率,因为如果是全连接层的话,前一层的只能是一组输入,而由于卷积层有滑动的功能,因此可以对多组输入进行相同的计算。 第一段中所说的通过计算在原图的不同位置的输入来得到更精确的结果的方法,如果原图为400400,而输入规格为300300,那么将会有4组输出,但是由于4组输入的图片有大量重叠的部分,那么一个个算的话肯定也有大量重复的计算,为了避免这种情况,我们将用到第二段所说的思想。举一个例子,原图为1616,输入规格为1414,当我们输入左上角的1414,假设全连接层前一层的输入为55,经过55的卷积层后输出为11(事实上神经网络全连接层的前一层的输出为特征向量),那么现在我们把全连接层看成卷积层,我们就可以处理多组输入了,我们现在可以直接向网络中输入1616的原图,那么全连接层的前一层输入可能为66,经过55的卷积层后输出为22,这里的输出为之前的4倍,那么经过全连接层后的输出也就会有4组,而这4组输出就是在16*16的原图的不同位置网络所得到的输出,这种方法比之前一个个算节省了大量的时间。 2.具体训练分类及定位网络的方法,获取分类网络(就是一些nb的分类网络去掉尾部),获取训练集,对训练集使用选择性搜索算法(就是事先筛选出原图可能为所要分类的实例的区域,这样神经网络就不用在原图上一个个试了),然后用回归的方法不断调整实例框(事实上前面使用的选择性搜索算法(除了这个,还有很多种)已经为我们确定了实例框的大概的位置和大小),用分类来识别分类种类。我们要训练二分类svm来确定图像区域中是否包含对象。

十二、可视化

可视化工具: t-SNE
DeCov方法,如果想要知道某一个神经元对图片的梯度,可以将网络中所有梯度设为0,然后将指定的那个神经元的梯度设为1,这样反向传播就会从这里开始。但这样得出的梯度图难以理解,因为梯度的正影响和负影响相互干扰,因此若要使梯度图十分清晰,就要使relu层也对反向传播有效,即拦截负向传播。
可视化有个很重要的应用是:通过对输入的图片(为空白图)进行优化,所谓优化就正向-反向-优化,然后就可以得到使某个分类的分数最大化的图片,这里要注意的是,在这里的网络是有损失函数的,即是有目标的,而且这个网络的所有权值都是经过大量训练且稳定可靠的。通过这样的操作,就可以看出怎样的图片输入可以最大化激活网络中某一个分类。不仅仅针对于某个分类,也可以针对网络中的任意一个神经元,不需要损失函数也可以。
把一个图片进行正向传递,便能得到分类前的特征图,那我们可以尝试着只依据特征图还原出原图,具体方法也是保持网络不变,只对图片进行优化,只不过要设损失函数,损失函数为当前特征图减去原图的特征图。从实验结果来看,如果直接对分类前的特征图进行还原,只能看见一些基本的信息,而越向前取特征图,则还原度越高,由此可见,随着网络的深入,图像的解析越来越抽象。
Deep dream:在原始图片中放大网络中的某一个神经元(或某一层)的激活信息。举个例子,我们想在神经元x上“做梦”,即我们想在图像中放大神经元x的激活信息,假设”狗头“能够最大化激活神经元x,那么通过对输入图片进行优化,网络就得努力使图片上充满”狗头“,那么怎么才能做到呢?具体做法为:当正向传播到我们选择的神经元时,我们直接将这个神经元的梯度置为这个神经元的激活图,注意在此网络中需要使relu对正反向传播都进行拦截,以免正负相互干扰,这样一来激活程度大的地方梯度越高,当这些梯度反向传播时会达到怎样的效果呢?网络会对这些梯度一步步进行解析,最终作用在图像上,换句话说,反向传播的过程中网络在思考图像该怎样变化才能符合那个神经元的梯度。
在图像风格转换中,之所以要将内容的loss加上是为了保证图像像素的位置对应,若没有内容图的内容表达,得出的结果会是乱序的。
在课程的最后,讲师说了一个尚未解决的问题,就是对抗样本的问题,这个问题出现的原因是(我的理解):图像的维度太高,有太多的空间没有被训练过,因此神经网络不知道该如何正确的训练,举个例子:用鸵鸟的梯度来优化狗的照片,按理说狗应该越来越像鸵鸟,但实际上狗的照片只是产生了细微的变化却达到了很低的loss,那么这张图就称为对抗样本,因为神经网络在优化的过程中对图片的每个维度都向最优解前进一小步,导致loss发生了很大的变化。对抗样本会有很多不好的影响,例如在得到某张图的对抗样本之后,就可以用对抗样本骗过神经网络。

重点

1用于分类的网络,最终得出的结果必然是通过损失函数计算出的误差值。
2.像VGG,GoogleNet这样的网络,我们可以去掉最后的全连接层来为己所用,像这种分类网络,最后的全连接层基本都是损失函数。而我们可以利用的是网络提取图片特征的能力,它既然能够分类出1000种事物,那么它肯定能很好的提取图片中的特征并抽象复杂化。
3、每个神经元都有自己的一组权值和一个偏移值,还有相应的激活函数。
4、大致上卷积神经网络可看成是由卷积层和全连接层组成的,而全连接层也可以看做一种特殊的卷积层,即每个神经元都可以看做是长宽步长均为1的过滤器。
5、神经网络的特征提取能力取决于当初训练时所提供的样本,比如训练样本全部为各种各样的狗时,这个网络就特别擅长于提取狗的特征。