文章中的词语解释:
分类器:完整的神经网络
类别分类器:分类器中的某一个输出对应的所有权值(单层全连接神经网络)
损失函数:不包括正则式的损失函数
正则化损失函数:包括正则式的损失函数
多类SVM损失(Multiclass SVM loss)
这里偷个懒,SVM损失对应的公式如下图(图片来自李飞飞计算机视觉课件):
公式中的下标
j
j
j表示不正确类别,
y
i
y_{i}
yi表示正确类别,
s
s
s对应是得分向量,而
s
j
s_{j}
sj和
s
y
i
s_{y_i}
syi分别表达不正确类别的得分和正确类别的得分。
L
i
L_i
Li的含义是对于第
i
i
i张图片来说预测的损失值,他等于不正确类别的得分减去正确类别的得分加
1
1
1,然后与0比较取最大值,对所有
j
j
j重复此运算,最后相加。其中加1,这个1是安全系数,是随意的一个数(为什么需要在差值后面加一个数呢?(我的理解)试想理想情况下,不正确类别的得分应该为0,正确类别的得分应该是正数,如果正确类别的得分和不正确类别的得分很接近,即使此时正确类别的得分高于不正确类别的得分,也说明模型不能非常好的对图片进行分类。举个极端的例子就是如果所有类别的评分一样,如果不加一个数那么最后得到的损失值就为0,这显然不是我们所希望的。这里存在一个问题,因为分数的度量是不确定的,比如将权重翻倍那么分数差值也会翻倍,从这个角度讲,这个值设为1是随意的)。为什么取0和差值的最大值呢,因为损失值的最小值不能为负数(为0),当所有不正确类别的评分都小于正确类别的评分时,用SVM得到的损失值就为0。
正则化(权值衰减)
试想在W集合中,可能存在一组W,使得损失函数最小,例如成倍的增加W值,最后得到的损失值是一样的,那么哪一个W值是最好的呢?或者可能存在不是成倍的关系的W权值都使得损失值最小,又或者有些W值虽然在训练集上表现很差但是在测试集上表现就很好,这些都是需要对W进行选择的。
正则式(这里的正则式含义与平时使用的匹配式不一样)只关心权值W,而不关心训练集,训练集的拟合度是由损失函数来完成的。正则化损失函数如下图所示
从图中可以看见正则化损失函数就是在损失函数的基础上加上了一个正则式。正则化损失函数的实质作用是权衡模型的训练损失和泛化损失,为了解释为什么有衡量泛化损失的能力,我们先来看看常使用的正则式有哪些,如下图所示
在神经网络中其实全连接神经网络能够非常好的拟合训练数据,但是训练得到的模型的泛化性能不高,因为参数越多层数越高能够拟合的数据就越复杂,也许数据并没有很复杂,所以出现过拟合现象即泛化性能不高,过拟合现象是指模型将训练数据中的“噪声”学习到了,从上图中可见,例如L1正则式,将其加入到损失函数中进行优化后,模型的很多权重
W
i
W_i
Wi会变为0(因为这样正则式才会比较小,进而正则化损失函数才会比较小),这样就达到减少参数个数的目的,进而提高模型的泛化性能,这也就解释了为什么正则化的损失函数能够权衡训练损失和泛化损失,这两种损失相互竞争,正则化损失会对他们进行权衡。(其实L1正则式实质就是稀疏化W,很多
W
i
W_i
Wi变为了0,这类似于特征的选择)
加入正则式后,模型的训练误差可能会增大,但是泛化误差一般会降低。其中L2正则式是最常用的正则式。
通过一个简单的例子来理解L2正则式对W的选取是有非常大的作用的,选取出的W更加优异,如下图所示(图片来自于李飞飞教授课件)
这个只是简单例子与现实中的实例不一样,上述
x
x
x是输入,
w
1
w_1
w1和
w
2
w_2
w2分别是候选权值,假设这两个候选权值是两个分类器中相同类别分类器的权值,其他类别分类器相同,这样输入值通过两个分类器得到的损失值是一样的,然而我们通过L2正则化损失,得到
w
2
w_2
w2对应的分类器更优异,那么从直观的角度看待,
w
2
w_2
w2的权值更加分散,每个维度都考虑到了,而
w
1
w_1
w1只考虑了第一维,所以从这个例子中可见,当损失值一样时,L2正则式发挥的作用会选择“雨露均沾”的权值,而这个权值也是我们所喜欢的,L2正则式对W的选择是有意义的,L2正则式就是展开权值W,“雨露均沾”考虑所有的特征,然后利用这些特征,这样的话考虑信息更加全面,效果更好。
softmax分类器(Multinomial Logistic Regression)
我们得到的分数是未标准化的,softmax函数是基于分数得到一张图片对应于不同类别的概率,这个概率是标准化概率。softmax函数的形式如下图所示
公式就是一张图片对应于一个类别的概率是
e
这
个
类
别
分
数
/
s
u
m
(
e
所
有
类
别
的
得
分
)
e^{这个类别分数}/sum(e^{所有类别的得分})
e这个类别分数/sum(e所有类别的得分)。上图的表达式就是一张图片对应于一个类别的概率表达式(通过使用e次方的形式可以将这个概率转为0~1之间,且所有类别概率加起来为1)。损失函数如下图所示
其实很简单,一句话这个损失函数希望正确类别的概率为1其他错误类别的概率为0。对于
L
i
L_i
Li为什么取对数来求最值,而不是直接求概率值的最大值(最大为1),因对数函数是单调函数,所以这两种方法是等价的,都可以用来计算损失,因为从数学角度来说概率对数更好,更加“优美”(我的理解是lg函数的斜率是随x的增大在减小,所以x越远离1那么函数值减小得越来越快(这里的x是概率值,位于0~1之间),这看起来比较合理,因为越远离1,说明模型分类效果越差,损失不应该呈线性增加)。其实取e的次方还有一个好处是,e的任何次方永远不等于0,这个就避免了除0错误。
这里有一个例子说明怎么计算softmax分类器的损失函数,如下图所示
这里助教提到了一个技巧就是,我们一般初始的w值都是接近于0的,所以最后的得分也都是接近于0的,最后得到的损失就应该是
−
l
o
g
(
1
/
类
别
数
)
-log(1/类别数)
−log(1/类别数),可以依照这个检查第一次优化时的损失值是否是它,如果差距很远那么可能某个地方就出错了。
softmax VS. SVM
SVM损失函数具有更强的稳定性,如下面的例子(图片来自于李飞飞课件):
比如第3个样例,当我们稍微修改各个类别的评分时,SVM损失函数不会有太大的变化,因为它的边界值-100-10+1远小于0,这个样例就不会对损失值有任何贡献,SVM也不会对这个样例有所关注,对于所有样例只要边界值小于0那么就不会对损失值有所贡献。而softmax损失函数就不一样了,不管正确分类的分数和错误分类的分数差距有多大,所有的样例都会贡献损失值,softmax对所有的样本都有所关注。所以综上所述,这两种损失函数的最显著区别是,SVM只关注边界值大于等于1的样例(即正确分类评分小于错误类别评分),而softmax关注所有的样例。
使用不同的损失函数最终的W值可能不一样,最后的损失值一般也是不一样的,所以哪一个损失函数更好需要根据具体问题出发来判断。
优化
前向传播是神经网络从输入得到输出的过程,相反,反向传播算法是从后到前逐层进行求梯度,然后通过优化算法使得W朝着损失值减小的方向进行。在优化算法中步长的概念是W每一步变化的幅度,一般会将起始值设为最大值,慢慢减小,这样可以避免最后收敛时出现大幅度震荡现象,也可以在一定程度上加速模型收敛。
关于梯度的由来和原理以及梯度和斜率的关系,本文不做详细说明,可以Google一下,网上的说明非常详细。
如下图是一维空间下某点斜率(slope)的公式,也是导数(derivative),其实也是梯度的公式
其中的
h
h
h我们称为步长,这里的
f
f
f函数一般是损失函数,我们可以把损失函数看做是所有待训练变量(权值W和偏移量bias)为自变量的函数,通过梯度的公式,我们可以验证当我们向某个方向前进
h
h
h步长(修改W值或bias值)时,然后计算出当前损失,根据梯度公式,我们就可以得到梯度值,最后根据梯度值的正负,判断是向“坡底”走还是向“坡顶”走,向“坡底”走那么根据导数知识很明显是使得损失值减小,“坡顶”则相反,如下图中的例子
其中
h
h
h等于0.0001。上面的公式实质就是梯度的数值计算方法(即将微分变为差分进行求解),如果每次尝试走一步都去计算损失值然后得到梯度正负(向上走了还是向下走了)是太慢了,而且因为是数值方法所以精度低(步长的限制),结果不准确,符合我们认知的是使用微积分解决该问题。
所以在实际使用中,我们主要使用解析梯度方法即微积分,数值梯度主要用于检验最后的结果是否正确,确保解析梯度方法是正确的。
上图是一个优化代码,这里的step_size是步长,它是一个超参数,是训练时的学习速率也叫作步长,这个值的设定需要认真考虑,就像前面提到的,如果步长设得过大,那么最后收敛时震荡很厉害或者根本就不能收敛(因为大幅度改变W值),如果设得过小,那么模型训练耗费的时间就越长(每次更新W值时,W值几乎不变)。weights_grad是损失函数对于每一个
W
i
W_i
Wi的梯度组成的向量,权值需要沿梯度的负方向前进才能使得损失值朝着减小的方向前进。另一个需要注意的超参数是正则化时的参数。
我们在实际中并不会去计算所有的样本的损失然后求平均,我们一般会在一次迭代中计算一个mini-batch(训练集中的一个很小的子集)的损失函数的梯度,然后进行这一次迭代的优化(修改W值),这样做法叫做随机梯度下降法(每次更新权值是在一个mini-batch上进行的),因为更新权值是基于mini-batch的(mini-batch中可能存在“噪音”),所以随机梯度下降法的缺点就是可能得到的梯度是不正确的,但是他可以提高计算速度,在有限的时间里面可以让我们计算更多的次数,使得W值不断改变,损失值不断变小,况且噪声是很小概率的,一般我们使用的都是这种方法。从实际角度出发,使用全数据的梯度也是不切实际的,因为GPU的显存也是很困难达到要求的。实际使用中使用mini-batch训练效率更高。对于mini-batch的大小需要根据电脑的GPU显存进行确定。如下图展示一个训练过程图,图中的纵坐标是损失值横坐标是迭代次数
上图是使用mini-batch,看起来像是噪音,出现波动正如前面所述是正常的,使用full-batch上面的曲线就是一条比较光滑的曲线,没有如此的噪声,但是从结果看,损失值整体上还是呈现下降趋势。
这里再说明一下学习速率(步长)的重要性,如下图所示
可以将损失函数理解为一个盆地,我们的目的是找到盆地最低点,非常高的学习率会使得W变化很大,可能就使得损失函数不能够收敛,或者是卡在某个山腰上,在对称的位置来回震荡,又或者是蹦出了当前的小山谷到另一个小山谷里面找“局部最小值”,较低的学习速率可以得到收敛的结果,但是收敛速度太慢了,所以在实际中一般是取一个较大的学习速率,然后不断变小,直到找到合适的学习速率。
上面提到的方法就是SGD(Stochastic Gradient Descent)随机梯度下降,这个方法就是用于更新W权值,这是一种最简单的优化方法,后面还有很多更加高级的优化方法。比如momentum方法(一旦找到正确的梯度方向我就会加速在这个方向的速度)、Adagrad方法等等。这些方法的效率不一样,不同的问题会给你某个方法更好的感觉,其实也可以作为一种超参数进行选择。
这里特别注意,SGD与反向传播算法(英语:Backpropagation,缩写为BP)不一样,反向传播算法是一种求梯度的方法,而SGD是一种优化损失函数的方法,不要混淆
计算机视觉
我们通过线性分类器不能够直接分类彩色图片,因为有像素问题(3通道)。所以一般的做法是先提取出特征,将这些特征进行数字化,然后传递给线性分类器进行分类。比如颜色特征(一个图片中各个颜色的数量)、HOG/SIFT特征(不同物体之间边缘的方向,有些方向是水平的有些是垂直的,如下图所示,通过统计不同方向边缘的数量来分类)
最开始的计算机视觉是通过人工提取特征来完成的,但是如今我们全部交给计算机,并不用我们去决定哪一个特征需要被提取,我们建立了一个可以仿真出许多不同特征的结构(卷积神经网络),机器直接从像素开始训练,这样整个模型的训练不再需要人的参与,减少了人的工作量。(2012年以后不再需要)