上一篇讲了最简单的线性分类器:k-Nearest Neighbor, 这里继续讲讲线性分类器。
linear classifiers作为深度学习里最基本的构造模块之一,首先是它的基本原理。
原理
假设我们想实现一个线性分类器,使每输入一张照片,系统可以从已知的10个labels中筛选,并自动输出它对应的label。现在输入一张32*32*3的彩色照片,矢量化之后对应了x=(3072*1)这样一个向量(3072=32*32*3),在被函数f(x,W)处理之后,能够得到一个(10*1)的新向量,每一行对应的就是10个labels中对其中一个label的打分,打分越高,即这张输入照片越有可能属于这个label。
这里的函数f(x,W)可写成
W称为权重矩阵,b称为偏置项,在这里是一个(10*1)的常数向量。偏置项不与训练数据交互,只会给我们一些数据独立的偏好值,比如,如果在你的数据集中猫的图片要比狗的图片多,那么猫对应的偏差元素就会比狗的高。
对于W(10*3072)来说,它的每一行对应了线性分类器在训练后对每种label总结出的一个模板。即如果我们将W的每一行分别取出来,再将他们还原成图像,就可以看出:(下面一行模糊的图片就是对应label的模板)
分类器对于“学习”每一个模板的方式是:根据训练数据集,尝试求取所有属于一个label的不同变体的均值,合成一个单独的模板(相比更复杂的分类器,线性分类器的弊端:使用单一的模板来判断新图片会导致误判,因为总有情况是无法被囊括进去的)。在后面的测试中,利用学习到的每个模板与输入的图片进行加权计算(权重是W中每一行单个元素的值,意思是输入图片中对应位置上的像素对于分类到这个label有多少的影响),得到打分。
如果将输入图片投射到一个高维的空间中,线性分类器尝试在线性决策边界上画一个线性分类面来划分一个类别和其他类别。这也是它的一个弊端所在,因为并不是所有的决策边界都是线性的。
损失函数
损失函数的出现是用于评估W和b对于分类结果是好是坏(tells how good our current classifier is)。
对于一组数据集,我们写成这样的形式:
xi---image
yi---label corresponding to the image
loss function即:N个样本的loss的总和的均值
因此,想要得到一个效果满意的分类器,重点是找到使loss function极小的W的值。
多分类SVM损失函数
令,
SVM loss可写为:
在SVM loss中,如果某张输入图片中,正确分类的分数syi比错误分类的分数sj高出某个安全边距(这里我们设为1),那么我们可以认为,对于这张图片,正确分类的分数比其他任何错误分类的分数都要高很多,在这种情况下loss=0,否则,计算每一个错误分类的分数以及正确分类的分数差:sj-syi+1,并求和可得这张输入图片的loss。接下来,我们把所有图片对每个错误分类的损失加起来除以总图片数,就可以得到整个dataset的final loss。
SVM 单个样本的loss function是一个合页损失函数(hinge loss),
随着正确分类的分数提升,损失会线性下降,直到样本图片中正确分类的分数相比错误分类的分数都超过了某一个阈值(这里设为1),损失会最终变成0。
在训练的初期,如果得到的sj和syi都十分地接近,且趋近于0,那么对于单个样本,此时的loss=labels的总数N-1(safety margin)。
如果在一个样本结果下对于所有的syi和sj进行求和,即
得到的样本的loss相比原loss增加了1(增加了正确分类分数-正确分类分数+1这一项)。
def L_i_vectorized(x,y,W):
scores=W.dot(x)
margins=np.maximum(0,scores-scores[y]+1)
margins[y]=0
loss_i=np.sum(margins)
return loss_i