标签:
该方法的第一部分就是定义一个评分函数,这个函数将图像的像素值映射为各个分类类别的得分,得分高低代表图像属于该类别的可能性高低。下面会利用一个具体例子来展示该方法。现在假设有一个包含很多图像的训练集 $x_i \in \mathbb{R}^D$,每个图像都有一个对应的分类标签 $y_i$ 。这里 $i= 1,2,…,N$ 并且 $y_i \in 1…K$ 。这就是说,有 N 个图像样本,每个图像的维度是 D,共有 K种不同的分类。
举例来说,在 CIFAR-10 中,我们有一个 N=50000 的训练集,每个图像有 D = 32x32x3=3072 个像素,而 K=10 ,这是因为图片被分为 10 个不同的类别(狗,猫,汽车等)。现在定义映射函数为:$f:\mathbb{R}^D \rightarrow \mathbb{R}^K$ ,该函数是原始图像像素到分类分值的映射。
线性分类器:在本模型中,我们从最简单的概率函数开始,一个线性映射:
\[f(x_i,W,b) = Wx_i +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),这是因为它影响输出数值,但是并不和原始数据 $x_i$ 产生关联。在实际情况中,人们常常混用权重和参数这两个术语。
需要注意的几点:
线性分类器计算图像中 3 个颜色通道中所有像素的值与 $W$ 相乘,从而得到预测值。根据训练得到的权重,对于图像中的某些位置的某些颜色,函数表现出喜好或者厌恶(根据每个权重的符号而定)。举个例子,可以想象“船”分类就是被大量的蓝色所包围(对应的就是水)。那么“船”分类器在蓝色通道上的权重就有很多的正权重(它们的出现提高了“船”分类的分值),而在绿色和红色通道上的权重为负的就比较多(它们的出现降低了“船”分类的分值)。
这里举个例子,假设单通道图像只有 4 个像素,有 3 个分类,分别为猫,狗,船。首先将图像像素拉伸为一个列向量,与W进行矩阵乘,然后得到各个分类的分值。需要注意的是,这个 W 一点也不好:猫分类的分值非常低。从上图来看,分类结果为狗。
将图像看做高维度的点:既然图像被伸展成为了一个高维度的列向量,那么我们可以把图像看做这个高维度空间中的一个点(即每张图像是 3072 维空间中的一个点)。整个数据集就是一个点的集合,每个点都带有 1 个分类标签。
既然定义每个分类类别的分值是权重和图像的矩阵乘,那么每个分类类别的分数就是这个空间中的一个线性函数的函数值。我们没办法可视化 3072 维空间中的线性函数,但假设把这些维度挤压到二维,那么就可以看看这些分类器在做什么了:
图像空间的示意图。其中每个图像是一个点,有 3 个分类器。以红色的汽车分类器为例,红线表示空间中汽车分类分数为0的点的集合,红色的箭头表示分值上升的方向。所有红线右边的点的分数值均为正,且线性升高。红线左边的点分值为负,且线性降低。
线性分为器的权重参数
从上面可以看到,W 的每一行都是一个分类类别的分类器。对于这些数字的几何解释是:如果改变其中一行的数字,会看见分类器在空间中对应的直线开始向着不同方向旋转。而偏差 b,则允许分类器对应的直线平移。需要注意的是,如果没有偏差,无论权重如何,在 $x_i = 0$ 时分类分值始终为 0 。这样所有分类器的线都不得不穿过原点。
将线性分类器看做模板匹配:关于权重 W 的另一个解释是它的每一行对应着一个分类的模板。一张图像对应不同分类的得分,是通过使用内积来比较图像和模板,然后找到和哪个模板最相似。从这个角度来看,线性分类器就是在利用学习到的模板,针对图像做模板匹配。从另一个角度来看,可以认为还是在高效地使用 KNN ,不同的是我们没有使用所有的训练集的图像来比较,而是每个类别只用了一张图片(这张图片是我们学习到的,而不是训练集中的某一张),而且我们会使用(负)内积来计算向量间的距离,而不是使用 L1 或者 L2 距离。
这里展示的是以CIFAR-10为训练集,学习结束后的权重的例子。注意,船的模板如期望的那样有很多蓝色像素。如果图像是一艘船行驶在大海上,那么这个模板利用内积计算图像将给出很高的分数。
可以看到马的模板看起来似乎是两个头的马,这是因为训练集中的马的图像中马头朝向各有左右造成的。线性分类器将这两种情况融合到一起了。类似的,汽车的模板看起来也是将几个不同的模型融合到了一个模板中,并以此来分辨不同方向不同颜色的汽车。这个模板上的车是红色的,这是因为 CIFAR-10 中训练集的车大多是红色的。线性分类器对于不同颜色的车的分类能力是很弱的,但是后面可以看到神经网络是可以完成这一任务的。神经网络可以在它的隐藏层中实现中间神经元来探测不同种类的车(比如绿色车头向左,蓝色车头向前等)。而下一层的神经元通过计算不同的汽车探测器的权重和,将这些合并为一个更精确的汽车分类得分。
偏差和权重的合并技巧:在进一步学习前,要提一下这个经常使用的技巧。它能够将我们常用的参数 W 和 b 合二为一。回忆一下,分类评分函数定义为:
\[f(x_i,W,b) = Wx_i + b\]
分开处理这两个参数(权重参数 $W$ 和偏差参数 $b$)有点笨拙,一般常用的方法是把两个参数放到同一个矩阵中,同时 $x_i$ 向量就要增加一个维度,这个维度的数值是常量 1 ,这就是默认的偏差维度。这样新的公式就简化成下面这样:
\[f(x_i,W) = W x_i\]
还是以 CIFAR-10 为例,那么 $x_i$ 的大小就变成 [3073x1] ,而不是 [3072x1] 了,多出了包含常量 1 的 1 个维度)。W 大小就是 [10x3073] 了。W 中多出来的这一列对应的就是偏差值 b,具体见下图:
偏差技巧的示意图。左边是先做矩阵乘法然后做加法,右边是将所有输入向量的维度增加 1 个含常量 1 的维度,并且在权重矩阵中增加一个偏差列,最后做一个矩阵乘法即可。左右是等价的。通过右边这样做,我们就只需要学习一个权重矩阵,而不用去学习两个分别装着权重和偏差矩阵了。
图像数据预处理
在上面的例子中,所有图像都是使用的原始像素值(从 0 到 255 )。在机器学习中,对于输入的特征做归一化(normalization)处理是很常见的。而在图像分类的例子中,图像上的每个像素可以看做一个特征。在实践中,对每个特征减去平均值来中心化数据是非常重要的。在这些图片的例子中,该步骤意味着根据训练集中所有的图像计算出一个平均图像值,然后每个图像都减去这个平均值,这样图像的像素值就大约分布在 [-127, 127] 之间了。下一个常见步骤是,让所有数值分布的区间变为 [-1, 1] 。零均值的中心化是很重要的,这样损失函数在梯度下降时得到的是一个很规则的形状。
在假设函数中,训练数据 $(x_i,y_i)$ 是给定的,不能修改。但是可以调整权重矩阵的参数,使得评分函数的结果与训练数据集中图像的真实类别一致,即评分函数在正确的分类的位置应当得到最高的评分(score)。
回到之前那张猫的图像分类例子,它有针对猫,狗,船三个类别的分数。例子中权重值非常差,因为猫分类的得分非常低(-96.8),而狗(437.9)和船(61.95)比较高。所以这里使用损失函数(Loss Function,Cost Function)来衡量对结果的不满意程度。直观地讲,当评分函数输出结果与真实结果之间差异越大,损失函数输出越大,反之越小。
损失函数的具体形式多种多样,这里从 Hinge Loss 的角度来考虑 SVM 。SVM 的损失函数想要 SVM 在正确分类上的得分始终比不正确分类上的得分高出一个边界值 $\Delta$ 。可以把损失函数想象成一个人,这位 SVM 先生对于结果有自己的品位,如果某个结果能使得损失值更低,那么 SVM 就更加喜欢它。
现在回忆一下,第 i 个数据中包含图像 $x_i$ 的像素和代表正确类别的标签 $y_i$。评分函数输入像素数据,然后通过公式 $f(x_i,W)$ 来计算不同类别的得分。这里我们将得分简写为向量 $s$ 。比如,针对第 j 个类别的得分就是第 j 个元素:$s_j = f(x_i,W)_j$ 。针对第 i 个数据的多类 SVM 的损失函数定义如下:
\[L_i = sum_{j \ne y_i} max(0,s_j – s_{y_i} + \Delta)\]
举例:用一个例子演示公式是如何计算的。假设有3个分类,并且得到了分值 s = [13,-7,11] 。其中第一个类别是正确类别,即 $y_i = 0$ 。同时假设 $\Delta$ 是 10 。上面的公式是将所有不正确分类 ($j \ne y_i$) 加起来,所以我们得到两个部分:
\[L_i = max(0,-7-13+10) +max(0,11-13+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的损失函数想要正确分类类别 $y_i$ 的分数比不正确类别分数高,而且至少要高 $\Delta$ 。如果不满足这点,就开始计算损失值。
那么在这次的模型中,我们面对的是线性评分函数(),所以我们可以将损失函数的公式稍微改写一下:
其中是权重的第j行,被变形为列向量。然而,一旦开始考虑更复杂的评分函数公式,这样做就不是必须的了。
在结束这一小节前,还必须提一下的属于是关于0的阀值:函数,它常被称为折叶损失(hinge loss)。有时候会听到人们使用平方折叶损失SVM(即L2-SVM),它使用的是,将更强烈(平方地而不是线性地)地惩罚过界的边界值。不使用平方是更标准的版本,但是在某些数据集中,平方折叶损失会工作得更好。可以通过交叉验证来决定到底使用哪个。
我们对于预测训练集数据分类标签的情况总有一些不满意的,而损失函数就能将这些不满意的程度量化。
—————————————————————————————————————————
多类SVM“想要”正确类别的分类分数比其他不正确分类类别的分数要高,而且至少高出delta的边界值。如果其他分类分数进入了红色的区域,甚至更高,那么就开始计算损失。如果没有这些情况,损失值为0。我们的目标是找到一些权重,它们既能够让训练集中的数据样例满足这些限制,也能让总的损失值尽可能地低。
—————————————————————————————————————————
正则化(Regularization):上面损失函数有一个问题。假设有一个数据集和一个权重集W能够正确地分类每个数据(即所有的边界都满足,对于所有的i都有)。问题在于这个W并不唯一:可能有很多相似的W都能正确地分类所有的数据。一个简单的例子:如果W能够正确分类所有数据,即对于每个数据,损失值都是0。那么当时,任何数乘都能使得损失值为0,因为这个变化将所有分值的大小都均等地扩大了,所以它们之间的绝对差值也扩大了。举个例子,如果一个正确分类的分值和举例它最近的错误分类的分值的差距是15,对W乘以2将使得差距变成30。
换句话说,我们希望能向某些特定的权重W添加一些偏好,对其他权重则不添加,以此来消除模糊性。这一点是能够实现的,方法是向损失函数增加一个正则化惩罚(regularization penalty)部分。最常用的正则化惩罚是L2范式,L2范式通过对所有参数进行逐元素的平方惩罚来抑制大数值的权重:
上面的表达式中,将中所有元素平方后求和。注意正则化函数不是数据的函数,仅基于权重。包含正则化惩罚后,就能够给出完整的多类SVM损失函数了,它由两个部分组成:数据损失(data loss),即所有样例的的平均损失,以及正则化损失(regularization loss)。完整公式如下所示:
将其展开完整公式是:
其中,是训练集的数据量。现在正则化惩罚添加到了损失函数里面,并用超参数来计算其权重。该超参数无法简单确定,需要通过交叉验证来获取。
除了上述理由外,引入正则化惩罚还带来很多良好的性质,这些性质大多会在后续章节介绍。比如引入了L2惩罚后,SVM们就有了最大边界(max margin)这一良好性质。(如果感兴趣,可以查看CS229课程)。
其中最好的性质就是对大数值权重进行惩罚,可以提升其泛化能力,因为这就意味着没有哪个维度能够独自对于整体分值有过大的影响。举个例子,假设输入向量,两个权重向量,。那么,两个权重向量都得到同样的内积,但是的L2惩罚是1.0,而的L2惩罚是0.25。因此,根据L2惩罚来看,更好,因为它的正则化损失更小。从直观上来看,这是因为的权重值更小且更分散。既然L2惩罚倾向于更小更分散的权重向量,这就会鼓励分类器最终将所有维度上的特征都用起来,而不是强烈依赖其中少数几个维度。在后面的课程中可以看到,这一效果将会提升分类器的泛化能力,并避免过拟合。
需要注意的是,和权重不同,偏差没有这样的效果,因为它们并不控制输入维度上的影响强度。因此通常只对权重正则化,而不正则化偏差。在实际操作中,可发现这一操作的影响可忽略不计。最后,因为正则化惩罚的存在,不可能在所有的例子中得到0的损失值,这是因为只有当的特殊情况下,才能得到损失值为0。
代码:下面是一个无正则化部分的损失函数的Python实现,有非向量化和半向量化两个形式:
在本小节的学习中,一定要记得SVM损失采取了一种特殊的方法,使得能够衡量对于训练数据预测分类和实际分类标签的一致性。还有,对训练集中数据做出准确分类预测和让损失值最小化这两件事是等价的。
接下来要做的,就是找到能够使损失值最小化的权重了。
设置Delta:你可能注意到上面的内容对超参数及其设置是一笔带过,那么它应该被设置成什么值?需要通过交叉验证来求得吗?现在看来,该超参数在绝大多数情况下设为都是安全的。超参数和看起来是两个不同的超参数,但实际上他们一起控制同一个权衡:即损失函数中的数据损失和正则化损失之间的权衡。理解这一点的关键是要知道,权重的大小对于分类分值有直接影响(当然对他们的差异也有直接影响):当我们将中值缩小,分类分值之间的差异也变小,反之亦然。因此,不同分类分值之间的边界的具体值(比如或)从某些角度来看是没意义的,因为权重自己就可以控制差异变大和缩小。也就是说,真正的权衡是我们允许权重能够变大到何种程度(通过正则化强度来控制)。
与二元支持向量机(Binary Support Vector Machine)的关系:在学习本课程前,你可能对于二元支持向量机有些经验,它对于第i个数据的损失计算公式是:
其中,是一个超参数,并且。可以认为本章节介绍的SVM公式包含了上述公式,上述公式是多类支持向量机公式只有两个分类类别的特例。也就是说,如果我们要分类的类别只有两个,那么公式就化为二元SVM公式。这个公式中的和多类SVM公式中的都控制着同样的权衡,而且它们之间的关系是
备注:在初始形式中进行最优化。如果在本课程之前学习过SVM,那么对kernels,duals,SMO算法等将有所耳闻。在本课程(主要是神经网络相关)中,损失函数的最优化的始终在非限制初始形式下进行。很多这些损失函数从技术上来说是不可微的(比如当时,函数就不可微分),但是在实际操作中并不存在问题,因为通常可以使用次梯度。
备注:其他多类SVM公式。需要指出的是,本课中展示的多类SVM只是多种SVM公式中的一种。另一种常用的公式是One-Vs-All(OVA)SVM,它针对每个类和其他类训练一个独立的二元分类器。还有另一种更少用的叫做All-Vs-All(AVA)策略。我们的公式是按照Weston and Watkins 1999 (pdf)版本,比OVA性能更强(在构建有一个多类数据集的情况下,这个版本可以在损失值上取到0,而OVA就不行。感兴趣的话在论文中查阅细节)。最后一个需要知道的公式是Structured SVM,它将正确分类的分类分值和非正确分类中的最高分值的边界最大化。理解这些公式的差异超出了本课程的范围。本课程笔记介绍的版本可以在实践中安全使用,而被论证为最简单的OVA策略在实践中看起来也能工作的同样出色(在 Rikin等人2004年的论文In Defense of One-Vs-All Classification (pdf)中可查)。
参考 :
https://zhuanlan.zhihu.com/p/20918580标签:
原文地址:http://www.cnblogs.com/ooon/p/5869504.html