CS231N-Lecture3 Loss Functions and Optimization

一、概述

在上一讲中,Andrej总结说在没有loss function的情况下,我们在用肉眼观察哪些分数是好的,哪些分数是坏的,如下图。

图中,cat的预测分数不是很好,2.9的分数比一些分数高,但是比deerdog等的低;car的预测分数则很好,比所有其他分数都高;而frog的预测分数糟透了,比大部分的分数都要低。

这个lecture中讲的是用loss function来量化分数的好坏,并用optimizer来优化Wb,使loss最小化。

二、Loss Functions

下面介绍了两种loss functionSVM CostSoftmax Cost(Cross-entropy cost)

  1. Multiclass SVM Cost 将所有不正确类型的分数和正确类型的分数的差 + 1之后的值,和0取最大值,最后将这些最大值相加,就是SVM Cost。 1) SVM Cost如何计算 下图是三个示例,具体展示SVM Cost是如何计算的。 视频中对为什么+1作了一些解释,但是不是很明白。还需要体会一下。1可以理解为是一个安全阀值。由于W可以初始化成大一些或者小一些,这是随机的。因此最终的预测分数也可以或大或小,因为W的缘故。这个1可能也是为了增加随机性而加上去的。Andrej说,选择1而是任意的,也就是说,你可以+2,+100,都是可以的,但是不能是0,和负数,这个也还不是很明白,有待体会。但是可能就像learning rate一样,太大了模型就不能和训练数据拟合了。这个1也可以想象成可以调整的hyper parameter,虽然最后Andrej说了这个不是hyper parameter… 在真正使用中,loss的值应该是将三个类型的loss相加,然后取平均值。 在上图中,也就是说,这一组Wb,作用在input image上之后,通过SVM Cost得到了一个loss值,这个值是4.6。 问题:为什么不能让j = yi?(j,和yi是svm cost公式中的两个脚标,上面的图片中有)因为如果j = yisj - syi = 0max之后得到1,那么最终的loss都会+1,增大了的loss的数值。问题:loss的最大最小值可以是多少?最大值是无穷大,最小值是0。问题:如果W在初始化的时候都是很小的值,那么所有类型的score都约等于0,在上图的情况下,loss是多少?loss是2;通用的公式是,第一次计算出来的loss应该是预测类型的个数 - 1。我们应该用这个规律来检查W初始化了之后,神经网络第一次的运行是否正确。在只有三个类型的例子中,如果初始化了之后,第一次计算得到的loss大致上在2左右,那么说明一切基本正常,至少没有很大问题;但是如果这个数值大大偏离了2,那就要检查一下网络中会有很大的问题。 Hinge Loss and Squared Hinge Loss 上图中,上一个公式被称作Hinge Loss,相应的,下面一个就是Squared Hinge Loss。这两个计算loss的方法可以被理解成是一个hyper parameter。通常出现的是Hinge Loss,但是再某些数据集中,Squared Hinge Loss的表现会相对较好。 SVM Cost的简单Python实现 上图中,margins[y] = 0一行,就是在解决上文中提到的“问题:为什么不能让j = yi?”这个问题。要将j = yi时计算的到的1抹平为0,不让其对loss产生任何影响。 下图是最终应用的时候的SVM Cost Loss Function 2) SVM Cost的问题 下面考虑SVM Cost的一个问题。 如果找到了一个W,能让L = 0,那么这个W是唯一的吗? 答案是,W不是唯一的。 如果将W设置成很大很大,在下图中,汽车那一栏的分差就会越来越大(比较上下两个计算公式里面的数值),那么max函数中的负数会越来越小,最终的L都是0。 意思是car这个类型使用的W可以是一个很大很大的数值,同时令最终的loss L = 0。但是这个W不会是唯一的。还有很多的比这个W小的W,也就是W的子集,也能使L = 0。这个属性不是很好。这个属性不好在于,过于集中的,不够分散的W的值,不利于模型的测试表现,因为只有部分训练数据的特种被捕捉。我的理解是,比如这里,如果carW的值很大很大,远大于其他类型的W的值,那么这个模型最终只会对汽车分类成功率很高,而对其他的类型的分类成功率很低。 为了解决这个问题,要引入Weight regularization。目的是为了找到我们期望中的W,不要让W在上述的问题中过于的大,或者过于的小。 3) Weight regularization loss function的最后,加上一个lambda乘以关于W的一个regularization函数Rregularization function的作用是衡量W的友好(niceness)程度。 上图中的L2 Regularization是最常用的。原理是求出所有的W的平方和,然后加在loss function后面。 那么在最后用optimizer来最小化loss的时候,loss function中加号两边的部分是相互制约的(用A,B两部分代替)。 一方面,网络选择的W应该让AB两部分都最小,而不是单单满足让A最小。 这就达到了让W最优的结果。 用图来解释一下。 上图中,对于x有两组ww1w2。这两组w作用于x之后,loss都是相同的。但是如果加上了regularizationw2是更好的选择。 因为w2的平方和小于w1的平方和。并且,w2的分布更加均匀。那么x中更多的特征都被捕捉利用了(4个),而w1只捕捉利用了1个特征值。最后测试的时候,选用w2的结果会好于w1的结果。 要注意的是,加上regularization function之后,可能在训练的时候,模型表现的会糟糕一点。但是在测试的时候,模型的表现往往会比没有正规化的时候好。 下面是Andrej对于regularization在图片分类器中的作用的解释: Regularization会考虑W作用于input x的所有维度情况,而不会只集中考虑W作用于input x的一个或者部分维度的情况;在图片分类的例子中,regularization可以让模型更好的适应所有的input x的特征(像素),在达到同样预测分数或者loss的效果的前提下,能够考虑更多的特征,可能也更加有利于generalize这个模型,让模型在测试和实际应用中有更好的表现。
  2. Softmax Cost (Cross-entropy Cost) SoftmaxSVM计算空间距离的方式不同,计算的是每个预测分数的概率分布。如果预测越准确,Softmax的结果越小,反之越大,我们要做的同样是最小化Softmax的结果。 Softmax是更加常用的loss function。计算例子如下。 根据公式首先计算e为底每个分数的指数的结果(红色框)。 然后normalize每一个分数(每个分数除以红色框中所有数值之和),得到绿色框中的数值。 最后对每个数值做log并取反,就是最终结果。 如图,catSoftmax Cost就是0.89,我们要想办法最小化这个loss。 问题:loss function的最大最小值是多少?最大值是无穷大,最小值是0。问题:W被初始化成很小的值是,所有的分数都约等于0,这时的loss是多少?是 -log(1 / N),N是预测类型的个数。同样可以用来检查W初始化后网络是否工作正常。
  3. SVM vs. Softmax 上图总结了一下两种loss function的计算方式。 下图给出了两种loss function的不同点。 问题:如果将上图中其中一组数据(比如第三组[10, -100, -100])中的数值增加或者减小,两个loss function有什么变化?SVM不会有任何变化,因为SVM考虑的只是两个点之间的距离(sj - syi,可以这么想吧),只要这个距离是负数,那么max之后,都是0;但是Softmax会变化,因为Softmax考虑的是每个点的概率,增加或者减小数值,都会影响到最后的概率。 上图是Andrej写的一个观察W,bloss的一个demo,点这里过去看看~

三、Optimization

首先回顾以下上面的内容。

这是Optimization进行至前的所有步骤:

* input是`(x, y)`,`score function`算出了每一个类型的预测分数;

* 然后通过任意一个`loss function`,上面是`Softmax`,下面是`SVM`计算出么一个分数的`loss`;

* 最后加总所有的`loss`,求平均值,再加上`regularization function`。 

接下来就是进行optimize的时候了。optimization有很多种方法,一种比一种好,可以看成是方法的一种演进。

  1. Random Search 由网络随机分配W,然后找到能够最小化lossW。 相当于是瞎猜。 可以看到用这种方式最终的结果是很惨烈的。 用这种方式选出的W在最终测试的时候准确率只有%15,最好的成绩是%95左右。 optimize的过程,可以想象成上图中的情形。你处于山坡上,眼睛被蒙住了。你只有一个高度仪,你可以知道任意点上的loss,你的目标是走到谷底。 Random Search就是随机往一个方向走,这是个很烂的主意。
  2. Numerical Gradient Numerical Gradient的方法是,计算每一个点上的斜率(坡度),这个斜率就是gradient。这个gradient的值,能告诉我我的这一步,是在往上走还是往下走,当然往下走是我想要的。 下图是Numerical Gradient的简单Python实现。 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qX1cpLU1-1587400503904)(http://img.blog.csdn.net/20170517164829332?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvaGVpc2VqaXVodWNoZQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)] 其实就是翻译了求导数的公式(上上张图中的),循环每一个W然后求出导数,即gradient。 下面给出了计算例子。 图上的公式的解释可以是这样。我在现有W的基础上,往任意方向上走很小的一步(0.0001),然后计算这一步的loss,是1.25322;原有W上的loss1.25347loss减少了,根据公式算出来,第一个W在往任意方向走了0.0001这一小步之后的gradient-2.5,因为是负的,所以这一步是往下走的(借用上面的例子,就是我在往山下走,这正是我想要的);以此类推。 直到计算出每一个Wgradient。 这种方法的缺陷是: 如果用在真正实践中,Convnet会有上千万的参数(W),一个一个计算gradient效率低下。 并且这挺蠢的,因为loss function整体是和W相关的,我们要minimize loss,就是要找到loss function相对于W的导数(gradient)即可,如下图。 want的部分,就是我们想要的。没有必要对整个W vector依次做导数的数学计算,所有W对于最终loss的贡献都已经包含在loss function中了,因此只需要计算loss function相对于Wgradient即可,也就是下面的Analytic Gradient方式。
  3. Analytic Gradient 使用微积分的方式来计算,如图: 使用这种方式的效率大大高于Numerical gradient。但同时这种方式很容易出错。因为在写公式的过程中很容易犯错误。因此,再实践中,一般用Analytic Gradient来操作,但是用Numerical Gradient来检查计算是否正确,这过程叫做Gradient Check。 话说是这样,但是真正实践中,用到Numerical太浪费时间了吧…以后再体会,现在还没有看到过有用这个方式去检查正确与否的…
  4. Gradient Descent Gradient Descent就是调整W的过程了。计算出gradient之后,要用这个gradient,乘以step_size或者learning_rate,然后取负数。 取负数是因为,最初计算导数的时候,相对于loss都是增量的,要取反才能让loss减小。 图中,step_size或者learning_rate,以及regularization function中的lambda,是很重要的hyper parameter,需要好好选择才能取得很好的训练效果。 下图是高维空间在二维空间的展示,阐述了gradient如果让loss降到最低。 图中的蓝色部分是loss最低的区域,W就是要沿着negative gradient direction这个方向走,才能让loss降到最低。
  5. Mini-batch Gradient Descent Mini-batch Gradient Descent是一种训练方式。相比于一下子用所有的数据去训练一个神经网络,采用Mini-batch分批训练的方式得到了更好的训练效果。 每个Mini-batch都选用了有利于GPU内存大小的数值,32/64/128/256等。 ImgNet冠军Krizhevsky训练他的Convnet时用了256 sizeMini-batch。 下图是选择Mini-batch训练时产生的loss的图示。 这里的loss看起来不是一条直线,而上下都有很多噪音是因为没有使用整个数据集去训练的缘故。因为每个Mini-batch的训练质量不同,这是造成噪音的原因。 并且这条loss下降曲线的形状和W的初始化相关,如果W初始化得好,这条曲线下降得会比较平缓,不会看到太多急速下降的部分。
  6. Learning Rate Learning Rate的选择是很重要的,下图显示了不同的Learning Rate对训练产生的不同效果。 这里写图片描述 十分高的Learning Rateloss直接爆掉了,会一直上升。 太高的Learning Rateloss一开始会下降,但是很快会到达一个平原区域,不再下降,这个时候网络已经停止学习了。 过低的Learning Rateloss下降的过于缓慢,网络的效率不高,要花很久很久的时间才能把loss降下来,并且效果也不一定很理想。 正确的Learning Rateloss下降很快,但是又不会迅速进入平原区域,同时训练效率也很高,不需要训练很长的时间。

四、总结

这一集讲了如何使用loss function来量化loss,并且使用optimizer来更新W的值,使loss最小化。