图像的线性分类器(感知机、SVM、Softmax)

来源:互联网 发布:lua 脚本 java 编辑:程序博客网 时间:2024/05/19 13:30

  本文主要内容为 CS231n 课程的学习笔记,主要参考 学习视频 和对应的 课程笔记翻译 ,感谢各位前辈对于深度学习的辛苦付出。在这里我主要记录下自己觉得重要的内容以及一些相关的想法,希望能与大家多多交流~

1. 线性分类器简介

  这部分所介绍的线性分类器,实际上指的是感知机,并且实际上是一个单层的感知机。对于感知机的部分,在之前的《<神经网路与深度学习>读书笔记》中已经有所介绍了,在这篇文章的第一部分我简单的介绍了感知机。那里的感知机只有一个输出 z ,而这里的感知机虽然也是一层的感知机,但是输出却比之前的笔记中介绍的要多,具体有多少个输出单元,根据数据的类别数确定。感兴趣的小伙伴可以点击链接跳转至那部分进行温习,本文的余下部分将不会对已经总过的知识再次总结。

  在这里认为线性分类器(即感知机)主要有两部分组成:一个是评分函数(score function),它是原始图像数据到类别分值的映射。另一个是损失函数(loss function),它是用来量化预测分类标签的得分与真实标签之间一致性的。该方法可转化为一个最优化问题,在最优化过程中,将通过更新评分函数的参数来最小化损失函数值。

  其中需要注意的是,这里所谓的评分函数实际上就是计算的过程(落到具体细节就是权重矩阵 W)。下面我们将从评分函数与损失函数两个方面先进行介绍,在介绍两种具体的分类器,SVM 与 Softmax。

2. 评分函数

2.1 评分函数的定义

  评分函数将图像的像素值映射为各个分类类别的得分,得分高低代表图像属于该类别的可能性高低。在假设有一个包含很多图像的训练集 xiRD ,每个图像都有一个对应的分类标签 yi。这里 i=1,2...N并且 yi1...K。这就是说,我们有 N 个图像样例,每个图像的维度是 D,共有 K 种不同的分类。举例来说,在CIFAR-10中,我们有一个N=50000的训练集,每个图像有D=32x32x3=3072个像素,而K=10,这是因为图片被分为10个不同的类别(狗,猫,汽车等)。

  现定义评分函数如下

f(xi,W,b)=Wxi+b

  在上面的公式中,假设每个图像数据都被拉长为一个长度为D的列向量,大小为[D x 1]。其中大小为[K x D]的矩阵W和大小为[K x 1]列向量b为该函数的参数(parameters)。还是以CIFAR-10为例,x_i就包含了第i个图像的所有像素信息,这些信息被拉成为一个[3072 x 1]的列向量,W大小为[10x3072],b的大小为[10x1]。因此,3072个数字(原始像素数值)输入函数,函数输出10个数字(不同分类得到的分值)。参数W被称为权重(weights)。b被称为偏差向量(bias vector),这是因为它影响输出数值,但是并不和原始数据 xi 产生关联。

  对于评价函数有以下几点需要注意:

  • 1
    一个单独的矩阵乘法 Wxi 就高效地并行评估10个不同的分类器(每个分类器针对一个分类),其中每个类的分类器就是W的一个行向量。
  • 2
    输入数据 (xi,yi)是给定且不可改变的,但参数W和b是可控制改变的。我们的目标就是通过设置这些参数,使得计算出来的分类分值情况和训练集中图像数据的真实类别标签相符。
  • 3
    该方法的一个优势是训练数据是用来学习到参数W和b的,一旦训练完成,训练数据就可以丢弃,留下学习到的参数即可。这是因为一个测试图像可以简单地输入函数,并基于计算出的分类分值来进行分类。
  • 4
    最后,注意只需要做一个矩阵乘法和一个矩阵加法就能对一个测试数据分类,这比k-NN中将测试图像和所有训练数据做比较的方法快多了。

2.2 如何理解评分函数

  评分函数的工作流程实际可以具体化为如下的形式


图 1. 评价函数工作流程可视化

  为了便于可视化,假设图像只有4个像素(都是黑白像素,这里不考虑RGB通道),有3个分类(红色代表猫,绿色代表狗,蓝色代表船,注意,这里的红、绿和蓝3种颜色仅代表分类,和RGB通道没有关系)。首先将图像像素拉伸为一个列向量,与W进行矩阵乘,然后得到各个分类的分值。需要注意的是,这个W一点也不好:猫分类的分值非常低。从上图来看,算法倒是觉得这个图像是一只狗。根据我们对权重设置的值,对于图像中的某些位置的某些颜色,函数表现出喜好或者厌恶(根据每个权重的符号而定)。

2.2.1 将图像看做高维度的点

  既然图像被伸展成为了一个高维度的列向量,那么我们可以把图像看做这个高维度空间中的一个点(即每张图像是3072维空间中的一个点)。整个数据集就是一个点的集合,每个点都带有1个分类标签。

  既然定义每个分类类别的分值是权重和图像的矩阵乘,那么每个分类类别的分数就是这个空间中的一个线性函数的函数值。我们没办法可视化3072维空间中的线性函数,但假设把这些维度挤压到二维,那么就可以看看这些分类器在做什么了


图 2. 图像空间的示意图

  其中每个图像是一个点,有3个分类器。以红色的汽车分类器为例,红线表示空间中汽车分类分数为0的点的集合,红色的箭头表示分值上升的方向。所有红线右边的点的分数值均为正,且线性升高。红线左边的点分值为负,且线性降低。

  从上面可以看到,W的每一行都是一个分类类别的分类器。对于这些数字的几何解释是:如果改变其中一行的数字,会看见分类器在空间中对应的直线开始向着不同方向旋转。而偏差b,则允许分类器对应的直线平移。需要注意的是,如果没有偏差,无论权重如何,在 xi=0 时分类分值始终为0。这样所有分类器的线都不得不穿过原点。

2.2.2 将线性分类器看做模板匹配

  关于权重W的另一个解释是它的每一行对应着一个分类的模板(有时候也叫作原型)。一张图像对应不同分类的得分,是通过使用内积(也叫点积)来比较图像和模板,然后找到和哪个模板最相似。从这个角度来看,线性分类器就是在利用学习到的模板,针对图像做模板匹配。从另一个角度来看,可以认为还是在高效地使用k-NN,不同的是我们没有使用所有的训练集的图像来比较,而是每个类别只用了一张图片(这张图片是我们学习到的,而不是训练集中的某一张),而且我们会使用(负)内积来计算向量间的距离,而不是使用L1或者L2距离。


图 3. 线性分类器通过学习得到的模板

  将课程进度快进一点。这里展示的是以CIFAR-10为训练集,图 3 为学习结束后的权重的例子。注意,船的模板如期望的那样有很多蓝色像素。如果图像是一艘船行驶在大海上,那么这个模板利用内积计算图像将给出很高的分数。

  可以看到马的模板看起来似乎是两个头的马,这是因为训练集中的马的图像中马头朝向各有左右造成的。线性分类器将这两种情况融合到一起了。类似的,汽车的模板看起来也是将几个不同的模型融合到了一个模板中,并以此来分辨不同方向不同颜色的汽车。这个模板上的车是红色的,这是因为CIFAR-10中训练集的车大多是红色的。线性分类器对于不同颜色的车的分类能力是很弱的,但是后面可以看到神经网络是可以完成这一任务的。神经网络可以在它的隐藏层中实现中间神经元来探测不同种类的车(比如绿色车头向左,蓝色车头向前等)。而下一层的神经元通过计算不同的汽车探测器的权重和,将这些合并为一个更精确的汽车分类分值。

2.3 偏差和权重的合并技巧

  分类评分函数定义为

f(xi,W,b)=Wxi+b

分开处理这两个参数(权重参数W和偏差参数b)有点笨拙,一般常用的方法是把两个参数放到同一个矩阵中,同时 xi 向量就要增加一个维度,这个维度的数值是常量 1,这就是默认的偏差维度。这样新的公式就简化成下面这样
f(xi,W)=Wxi

还是以CIFAR-10为例,那么x_i的大小就变成[3073x1],而不是[3072x1]了,多出了包含常量1的1个维度)。W大小就是[10x3073]了。W中多出来的这一列对应的就是偏差值b,具体见下图


图 4. 偏差技巧的示意图

  左边是先做矩阵乘法然后做加法,右边是将所有输入向量的维度增加1个含常量1的维度,并且在权重矩阵中增加一个偏差列,最后做一个矩阵乘法即可。左右是等价的。通过右边这样做,我们就只需要学习一个权重矩阵,而不用去学习两个分别装着权重和偏差的矩阵了。

3. 损失函数 Loss function

  使用损失函数(Loss Function)(有时也叫代价函数Cost Function或目标函数Objective)来衡量我们对结果的不满意程度。直观地讲,当评分函数输出结果与真实结果之间差异越大,损失函数输出越大,反之越小。

3.1 多类支持向量机损失 Multiclass Support Vector Machine Loss

  SVM的损失函数想要SVM在正确分类上的得分始终比不正确分类上的得分高出一个边界值 Δ

  第 i 个数据中包含图像 xi 的像素和代表正确类别的标签 yi。评分函数输入像素数据,然后通过公式 f(xi,W)计算不同分类类别的分值。这里我们将分值简写为 s。比如,针对第 j 个类别的得分就是第 j 个元素: sj=f(xi,W)j。针对第 i 个数据的多类SVM的损失函数定义如下:

Li=jyimax(0,sjsyi+Δ)

  举例:用一个例子演示公式是如何计算的。假设有3个分类,并且得到了分值s=[13 , -7 , 11]。其中第一个类别是正确类别,即 yi=0。同时假设 Δ是 10(后面会详细介绍该超参数)。上面的公式是将所有不正确分类( jyi)加起来,所以我们得到两个部分:

Li=max(0,713+10)+max(0,1113+10)

  可以看到第一个部分结果是0,这是因为[-7-13+10]得到的是负数,经过max(0,)函数处理后得到0。这一对类别分数和标签的损失值是0,这是因为正确分类的得分13与错误分类的得分-7的差为20,高于边界值10。而SVM只关心差距至少要大于10,更大的差值还是算作损失值为0。第二个部分计算[11-13+10]得到8。虽然正确分类的得分比不正确分类的得分要高(13>11),但是比10的边界值还是小了,分差只有2,这就是为什么损失值等于8。简而言之,SVM的损失函数想要正确分类类别 yi 的分数比不正确类别分数高,而且至少要高 Δ。如果不满足这点,就开始计算损失值。

  max(0,)函数,它常被称为折叶损失(hinge loss)。有时候会听到人们使用平方折叶损失SVM(即L2-SVM),它使用的是 max(0,)2,将更强烈(平方地而不是线性地)地惩罚过界的边界值。不使用平方是更标准的版本,但是在某些数据集中,平方折叶损失会工作得更好。可以通过交叉验证来决定到底使用哪个。


图 5. 折叶损失示意图

如图 5,多类SVM“想要”正确类别的分类分数比其他不正确分类类别的分数要高,而且至少高出delta的边界值。如果其他分类分数进入了红色的区域,甚至更高,那么就开始计算损失。如果没有这些情况,损失值为0。我们的目标是找到一些权重,它们既能够让训练集中的数据样例满足这些限制,也能让总的损失值尽可能地低。

3.2 SVM中的正则化(Regularization)

  上面损失函数有一个问题: W并不唯一。可能有很多相似的W都能正确地分类所有的数据。一个简单的例子:如果W能够正确分类所有数据,即对于每个数据,损失值都是0。那么当 λ>1 时,任何数乘 λW 都能使得损失值为0,因为这个变化将所有分值的大小都均等地扩大了,所以它们之间的绝对差值也扩大了。举个例子,如果一个正确分类的分值和举例它最近的错误分类的分值的差距是15,对W乘以2将使得差距变成30。

  我们希望能向某些特定的权重W添加一些偏好,对其他权重则不添加,以此来消除模糊性。这一点是能够实现的,方法是向损失函数增加一个正则化惩罚(regularization penalty)R(W)部分。最常用的正则化惩罚是L2范式,L2范式通过对所有参数进行逐元素的平方惩罚来抑制大数值的权重:

R(W)=klW2k,l

上面的表达式中,将W中所有元素平方后求和。注意正则化函数不是数据的函数,仅基于权重。包含正则化惩罚后,就能够给出完整的多类SVM损失函数了,它由两个部分组成:数据损失(data loss),即所有样例的的平均损失 Li,以及正则化损失(regularization loss)。完整公式如下所示:

L=1NiLidata loss+λR(W)regularization loss

将其展开完整公式是:

L=1Nijyi[max(0,f(xi;W)jf(xi;W)yi+Δ)]+λklW2k,l

其中,N是训练集的数据量。现在正则化惩罚添加到了损失函数里面,并用超参数\lambda来计算其权重。该超参数无法简单确定,需要通过交叉验证来获取。

  除了上述理由外,引入正则化惩罚还带来很多良好的性质,这些性质大多会在后续章节介绍。比如引入了L2惩罚后,SVM 们就有了最大边界(max margin)这一良好性质。

  其中最好的性质就是对大数值权重进行惩罚,可以提升其泛化能力,因为这就意味着没有哪个维度能够独自对于整体分值有过大的影响。举个例子,假设输入向量x=[1,1,1,1],两个权重向量w1=[1,0,0,0]w2=[0.25,0.25,0.25,0.25]。那么wT1x=wT2=1,两个权重向量都得到同样的内积,但是w1的L2惩罚是1.0,而w2的L2惩罚是0.25。因此,根据L2惩罚来看,w2更好,因为它的正则化损失更小。从直观上来看,这是因为w2的权重值更小且更分散。既然L2惩罚倾向于更小更分散的权重向量,这就会鼓励分类器最终将所有维度上的特征都用起来,而不是强烈依赖其中少数几个维度。在后面的课程中可以看到,这一效果将会提升分类器的泛化能力,并避免过拟合。

  最后,因为正则化惩罚的存在,不可能在所有的例子中得到0的损失值,这是因为只有当W=0的特殊情况下,才能得到损失值为0。

  所以正则化所带来的有点主要在于以下三点
(1)使得分类器可在满足条件的众多参数 W 中选取最适合的一个;
(2)使得 SVM 分类器获得了最大边界这一良好的性质;
(3)提升模型的泛化能力,避免过拟合。

  注意,这里所指的正则化指的是 L2 正则化,在之前的博客《七、改进神经网络的学习方法(3):过拟合及改进方法(正则化、Dropout)》中也有讲过正则化,不过在那节是站在神经网络的角度讲述的,主要讲解了 L1、 L2 、Dropout三种正则化方法抑制神经网络过拟合的方面,对应到SVM中正则化的三个优点,相当于只有最后一个。但是方法却比SVM多了一种Dropout。

3.3 超参数Δ的取值

  在实际中过交叉验证来求得 Δ 的取值,该超参数在绝大多数情况下设为 Δ=1.0 都是安全的。超参数 Δλ 看起来是两个不同的超参数,但实际上他们一起控制同一个权衡:即损失函数中的数据损失和正则化损失之间的权衡。理解这一点的关键是要知道,权重W的大小对于分类分值有直接影响(当然对他们的差异也有直接影响):当我们将W中值缩小,分类分值之间的差异也变小,反之亦然。因此,不同分类分值之间的边界的具体值(比如 Δ=1Δ=100 )从某些角度来看是没意义的,因为权重自己就可以控制差异变大和缩小。也就是说,真正的权衡是我们允许权重能够变大到何种程度(通过正则化强度 λ 来控制)。

4. SVM 与 Softmax

4.1 Softmax 分类器

  关于 Softmax 分类器可以参考之前的博文《六、改进神经网络的学习方法(2):Softmax输出层》。

  关于交叉熵函数可以参考之前的博文《 五、改进神经网络的学习方法(1):交叉熵代价函数》。

4.1 Softmax 与 SVM 分类器的比较


图 6. Softmax 与 SVM 分类器的比较示意图

  针对一个数据点,SVM和Softmax分类器的不同处理方式的例子。两个分类器都计算了同样的分值向量f(本节中是通过矩阵乘来实现)。不同之处在于对f中分值的解释:SVM分类器将它们看做是分类评分,它的损失函数鼓励正确的分类(本例中是蓝色的类别2)的分值比其他分类的分值高出至少一个边界值。Softmax分类器将这些数值看做是每个分类没有归一化的对数概率,鼓励正确分类的归一化的对数概率变高,其余的变低。SVM的最终的损失值是1.58,Softmax的最终的损失值是0.452,但要注意这两个数值没有可比性。只在给定同样数据,在同样的分类器的损失值计算中,它们才有意义。

  概括来讲,这两个分类器的主要区别在于以下两点:

(1)分类结果是否可直接解释

  SVM的计算是无标定的(可以理解为没有进行归一化,不知道之间的相对大小),而且难以针对所有分类的评分值给出直观解释。Softmax分类器则不同,它允许我们计算出对于所有分类标签的“可能性”。给可能性打上双引号是因为可能性分布的集中或离散程度是由正则化参数λ直接决定的,λ是你能直接控制的一个输入参数。如果正则化参数λ更大,那么权重W就会被惩罚的更多,然后他的权重数值就会更小,这样算出来的分数也会更小。所以只是与可能性的含义相近,但并不是真正的可能性。

(2)对于分数是否会满足

  相对于Softmax分类器,SVM更加“局部目标化(local objective)”,这既可以看做是一个特性,也可以看做是一个劣势。考虑一个评分是[10, -2, 3]的数据,其中第一个分类是正确的。那么一个SVM(Δ=1)会看到正确分类相较于不正确分类,已经得到了比边界值还要高的分数,它就会认为损失值是0。SVM对于数字个体的细节是不关心的:如果分数是[10, -100, -100]或者[10, 9, 9],对于SVM来说没设么不同,只要满足超过边界值等于1,那么损失值就等于0。

对于softmax分类器,情况则不同。对于[10, 9, 9]来说,计算出的损失值就远远高于[10, -100, -100]的。换句话来说,softmax分类器对于分数是永远不会满意的:正确分类总能得到更高的可能性,错误分类总能得到更低的可能性,损失值总是能够更小。但是,SVM只要边界值被满足了就满意了,不会超过限制去细微地操作具体分数。这可以被看做是SVM的一种特性。举例说来,一个汽车的分类器应该把他的大量精力放在如何分辨小轿车和大卡车上,而不应该纠结于如何与青蛙进行区分,因为区分青蛙得到的评分已经足够低了。

原创粉丝点击