cs231n系列1-2: 线性分类:支持向量机,Softmax

发布时间:2019-12-21 19:06    浏览次数 :

[返回]

澳门新葡亰7802网址 1

说明

本文作者基于论文阅读及实测,以尝试欺骗神经网络的方式,从工具安装到模型训练,逐步解析神经网络及其背后的数学原理。文章还提供了演示代码下载。神奇的神经网络当我打开Google Photos并从我的照片中搜索“skyline”时,它找到了我在八月拍摄的这张纽约地平线的照片,而我之前并未对它做过任何标记。当我搜索‘cathedral’,Google的神经网络会找到我曾看到的大教堂和教堂。这似乎很神奇。当然,神经网络并不神奇,一点都不!最近我阅读了一篇论文,“Explaining and Harnessing Adversarial Examples”,进一步削弱了我对神经网络的神秘感。这篇论文介绍了如何欺骗神经网络,让其犯下非常惊人的错误。通过利用比你想象更简单的网络事实来做到这一点。我们会使用一个线性函数来逼近这个网络!重点是要理解,这并不能解释神经网络犯下的所有类型的错误!有很多可能会犯的错误!但它确实在一些特定类型的错误上给了我们一些灵感,这非常好。在阅读这篇论文之前,我对神经网络的了解有以下三点:它在图片分类中表现得很出色大家都在网上谈论“深度”神经网络它们是由多层简单的函数构成,其结构如下图所示:错误我对神经网络了解的第四点是:它们有时会犯很可笑的错误。剧透一下本文后面的结果:这是两张图片,文章会展示神经网络是如何对其进行分类的。我们可以让它相信,下面黑色的图像是一张纸巾,而熊猫则会被识别为一只秃鹫!现在,这个结果对我来说并不吃惊,因为机器学习是我的工作,而且我知道机器学习习惯产生奇怪的结果。但如果要解决这个超级奇怪的错误,我们就需要理解其背后的原理!我们要学习一些与神经网络有关的知识,然后我会教你如何让神经网络认为熊猫就是一只秃鹫。做第一个预测我们首先加载一个神经网络,然后做一些预测,最后再打破这些预测。这听起来真棒。但首先我需要在电脑上得到一个神经网络。我在电脑上安装了Caffe,这是一个神经网络软件,是Berkeley Vision and Learning Center (BVLC) 社区贡献者开发的。我选择它是因为它是我第一个可以找到的软件,而且我可以下载一个预先训练好的网络。你也可以尝试下Theano或者Tensorflow。Caffe有非常清晰的安装说明,这意味着在我正式使用它进行工作前,仅仅只需花6个小时来熟悉。如果你想要安装Caffe,可以参考我写的程序,它会让你节省更多的时间。只需去the neural-networks-are-weird repo这个仓库,然后按照说明运行即可。警告:它会下载大约1.5G的数据,并且需要编译一大堆的东西。下面是构建它的命令,你也可以在仓库下的README文件中找到。

  1. 本系列文章翻译斯坦福大学的课程:Convolutional Neural Networks for Visual Recognition的课程讲义 原文地址:http://cs231n.github.io/。 最好有Python基础(但不是必要的),Python的介绍见该课程的module0。

  2. 本节的code见地址:
    https://github.com/anthony123/cs231n/tree/master/module1-2

  3. 如果在code中发现bug或者有什么不清楚的地方,可以及时给我留言,因为code没有经过很严格的测试。

git clone a href="" neural-nets-are-weirddocker build -t neural-nets-fun:caffe .docker run -i -p 9990:8888 -v $PWD:/neural-nets -t neural-nets-fun:caffe /bin/bash -c 'export PYTHONPATH=/opt/caffe/python  cd /neural-nets  ipython notebook --no-browser --ip 0.0.0.0'

这节课的主要内容:

这会启动你电脑中的IPython notebook服务,然后你便可以用Python做神经网络预测了。它需要在本地9990端口中运行。如果你不想照着做,完全没关系。我在这篇文章中也包含了实验图片。一旦我们有了IPtyon notebook并运行后,我们就可以开始运行代码并做预测了!在这里,我会贴一些美观的图片和少量的代码片段,但完整的代码和详细细节可以在这里查看。我们将使用一个名叫GoogLeNet的神经网络,它在LSVRC 2014 多个竞赛中胜出。正确分类是在耗费94%时间的前5大网络猜测中。这是我读过的那篇论文的网络。首先,让我们使用网络对一只可爱的kitten进行分类:下面是对kitten进行分类的代码:

  • 介绍线性分类
  • 线性分数函数
  • 澳门新葡亰平台游戏,解释线性分类器
  • 损失函数
    • 多类别SVM
    • Softmax分类器
    • SVM vs Softmax
  • 线性分类的交互性网页示例
  • 总结
image = '/tmp/kitten.png'# preprocess the kitten and resize it to 224x224 pixelsnet.blobs['data'].data[...] = transformer.preprocess('data', caffe.io.load_image(image))# make a prediction from the kitten pixelsout = net.forward()# extract the most likely predictionprint("Predicted class is #{}.".format(out['prob'][0].argmax()))

线性分类

上一节课介绍了线性分类问题,它从一个固定的标签集合中选择一个标签,赋予一张图片。而且,我们介绍了KNN分类器,它通过将输入图像与训练集中的图像比较的方法赋予图像标签。我们知道,kNN有如下几个缺点:

  • 分类器必须记住所有的训练数据,并把它存储起来,将来与测试集中的图像进行比较。这种方式非常耗费空间,因为训练集往往在GB数量级。
  • 对一张图片进行分类非常耗费时间,因为它需要与训练集中所有的图片进行比较。

就这些!仅仅只需3行代码。同样,我可以对一只可爱的小狗进行分类!原来这只狗不是柯基犬,只是颜色非常相似。这个网络对狗的了解果真比我还多。一个错误是什么样的做这项工作时最有趣的事情是,我发现了神经网络认为英国女王戴在她的头上。所以,现在我们看到网络做了一件正确的事,同时我们也看到它在不经意间犯了一个可爱的错误。现在...我们让它故意去犯错误,并进入它的核心。故意犯错误在真正理解其工作原理之前,我们需要做一些数学变换,首先让我们看看它对黑色屏幕的一些描述。这张纯黑色图像被认为是天鹅绒的概率是27%,被认为是纸巾的概率为4%。还有一些其它类别的概率没有列出来,这些概率之和为100%。我想弄清楚如何让神经网络更有信心认为这是一个纸巾。要做到这一点,我们需要计算神经网络的梯度。也就是神经网络的导数。你可以将这看作是一个方向,让图像在这个方向上看起来更像一张纸巾。要计算梯度,我们首先需要选择一个预期的结果来移动方向,并设置输出概率列表,0表示任何方向,1表示纸巾的方向。反向传播算法是一种计算梯度的算法。我原以为它很神秘,但事实上它只是一个实现链式法则的算法。如果你想知道更多,这篇文章有一个奇妙的解释。下面是我编写的代码,实际上非常简单!反向传播是一种最基本的神经网络运算,因此在库中很容易获得。

概要

我们将要开发一个更强大的图像分类算法,它最终能够被扩展到整个神经网络和卷积神经网络。这个算法有两个主要的部分:1. 把原始数据映射到种类分数的分数函数;2.评估预测分数与真实标签一致性的损失函数。我们最终会把分类问题看成一个优化问题,即通过改变分数函数的参数来最小化损失函数。

def compute_gradient(image, intended_outcome): # Put the image into the network and make the prediction predict(image) # Get an empty set of probabilities probs = np.zeros_like(net.blobs['prob'].data) # Set the probability for our intended outcome to 1 probs[0][intended_outcome] = 1 # Do backpropagation to calculate the gradient for that outcome # and the image we put in gradient = net.backward(prob=probs) return gradient['data'].copy()

图像到标签分数的参数化映射

这个算法的第一个组成部分是定义一个分数函数,它将图像的像素值映射到对每个类的置信分数(confidence scores)。我们会以一个具体的例子来说明。和以前一样,我们假设一个图片训练集 x_i ∈ R^D, 每张图片都和一个标签 y_i,其中i=1…N,y_i∈1…K 相对应。也就是说,我们有N个例子(每个有D个维度)和K个不同的种类。比如,CIFAR-10测试集 N=50,000,每张图片的维度D=32x32x3=3072,K=10,因为我们有10类物品(狗,猫,车等)。我们现在定义一个分数函数

它将图像的原始像素映射到种类分数。

这基本上告诉了我们,什么样的神经网络会在这一点上寻找。因为我们处理的所有东西都可以表示为一个图像,下面这个是compute_gradient(black, paper_towel_label)的输出,缩放到可见比例。现在,我们可以从我们的黑色屏幕添加或减去一个非常明亮的部分,使神经网络认为我们的图像或多或少像一张纸巾。由于我们添加的图像太亮,所以差异完全看不到。下面是这个结果:现在,神经网络以16%的概率肯定我们的黑色屏幕是一张纸巾,而不是4%!真灵巧。但是,我们可以做的更好。我们可以采取走十个小步来构成一个有点像纸巾的每一步,而不是在纸巾的方向直接走一步。你可以在下面看到随时间变化的概率。你会注意到概率值与之前的不同,因为我们的步长大小不同。最后的结果:下面是构成这张图像的像素值!他们都从0开始,而且你可以看到,我们已经转换了它们,使其认为该图像就是纸巾。我们还可以用50乘以这个图像从而获得一个更好的图像感知。对我来说,这看起来并不像一块纸巾,但对你可能就像。我猜测图像的所有漩涡都戏弄了神经网络使其认为这是一张纸巾。这牵扯到基本的概念证明和一些数学原理。马上我们就要接触更多的数学知识了,但首先我们来玩点有趣的。玩转神经网络一旦我理解了这个,它就会变得非常有趣。我们可以换一只猫变成浴巾:一个垃圾桶可以变成一个水壶/鸡尾酒调酒器:一只熊猫可以变成秃鹫。这张图表明,在将熊猫认为是秃鹰的100步内,其概率曲线转变地很迅速。你可以查看代码,让这些工作在IPython notebook中运行。真的很有趣。现在,是时候多一点数学原理了。如何工作:逻辑回归首先,让我们讨论一种最简单的图像分类方法——逻辑回归。什么是逻辑回归?下面我来试着解释下。假设你有一个线性函数,用于分类一张图像是否是浣熊。那么我们如何使用线性函数呢?现在假设你的图像只有5个像素,取值均在0和255之间。我们的线性函数都有一个权重,比如取值为,然后对图像进行分类,我们会将得到像素和权重的内积:引用result=23x​1​​−3x​2​​+9x​3​​+2x​4​​−5x​5​​假设现在的结果是794。那么794到底意味着它是浣熊或者不是呢?794是概率吗?794当然不是概率。概率是一个0到1之间的数。我们的结果在−∞到∞之间。人们将一个取值在−∞到∞之间的数转为一个概率值的一般方法是使用一个叫做logistic的函数:引用S(t)=1/(1+e^(-t))此函数的图形如下所示:S(794)的结果基本为1,所以如果我们从浣熊的权重得到794,那么我们就肯定它100%是个浣熊。在这个模型中——我们先使用线性函数变换数据,然后应用逻辑函数得到一个概率值,这就是逻辑回归,而且这是一种非常简单流行的机器学习技术。机器学习中的“学习”主要是在给定的训练集下,如何决定正确的权重),这样我们得到的概率值才能尽可能的好。通常训练集越大越好。现在我们理解了什么是逻辑回归,接下来让我们讨论下如何打破它吧!澳门新葡亰7802网址,打破逻辑回归这有一篇华丽的博文,Andrej Karpathy发表的Breaking Linear Classifiers on ImageNet,解释了如何完美地打破一个简单线性模型。后面我们将使用同样的原理来打破神经网络。这有一个例子,一些区分不同食物,鲜花以及动物的线性分类器,可视化为下图。你可以看到“Granny Smith”分类器基本上是问“是绿色么?”,而“menu”分类器发现菜单通常是白色。Karpathy 对其解释的非常清楚:引用例如,苹果是绿色的,所以线性分类器在所有的空间位置中,绿色通道上呈现正权值,蓝色和红色通道上呈现负权值。因此,它有效地计算了中间是绿色成分的量。所以,如果我想要让Granny Smith分类器认为我是一个苹果,我需要做的是:找出图中哪一个像素点最关心绿色给关心绿色的像素点着色证明!所以现在我们知道如何去欺骗一个线性分类器。但是神经网络并不是线性的,它是高度非线性的!为什么会相关呢?如何工作:神经网络在这我必须诚实一点:我不是神经网络专家,我对神经网络的解释并不会很出色。Michael Nielsen写了一本叫做《Neural Networks and Deep Learning》的书,写的很好。另外,Christopher

线性分类器

我们从一个最简单的线性函数出发,一个线性映射:

在上面的表达式中,我们假设图像 Xi 所有的像素都放在一个行向量中,它的形状为[Dx1]。矩阵W(大小为[KxD])和向量b(大小为[Kx1])都是函数的参数,在CIFAR-10中,Xi 包含第i张图片的所有像素,其大小为[3072x1], W的大小为[10x3072],b的大小为[10x1]。所以输入3072个数字到函数中,输出10个数字。W中的参数称之为权重b称之为偏置向量(bias vector),因为它虽然影响输出,但是它并不和实际的数据交互。在实践中,人们经常将权重参数互换使用。

下面有几件事情需要说明一下:

  • 单独的乘积 WXi 能够并发地同时评估10个分类器,其中,W的每一行是一个分类器

  • 注意我们将输入数据(Xi,yi)视作固定的,而我们可以控制W和b的值。我们的目标是设置它们的值,使得对整个训练集图片的预测和它们的真实标签尽可能一致。我们以后会讨论如何做到这一点,但是从直觉上说,我们希望正确的类别分数比错误类别的分数要高。

  • 这个算法的一个优点是训练集用来学习参数W,b,一旦学习结束,我们可以丢弃整个训练集,只保留学习的参数。测试图片可以通过分数函数的输出结果来获得分类的标签。

  • 对测试图片分类只包括了一个简单的矩阵乘法和加法,它比将它与所有的训练集比较要快的多。

    卷积神经网络和上面描述的方法那样,将图像像素映射成类别分数,但是映射函数(f)会更复杂,参数也会更多。

Olah的博客也不错。我所知道的神经网络是:它们是函数。你输入一张图像,你会得到一个概率列表,对每个类都有一个概率。这些是你在这篇文章中看到的图像的数字。因此,一个神经网络,就像1000个函数。但1000个函数对于推理来说非常复杂。因此,做神经网络的人,他们把这1000个概率组合并为一个单一的“得分”,并称之为“损失函数”。每个图像的损失函数取决于图像实际正确的输出。假设我有一张鸵鸟的图片,并且神经网络有一个输出概率Pj,其中j=1...1000,但对于每只鸵鸟我想要得到的是概率yj。那么损失函数为:假设与“鸵鸟”对应的标签值是700,那么y700=1,其它的yj就为0,L=-logp700。在这里,重点是要理解神经网络给你的是一个函数,当你输入一张图像,你会得到损失函数的最终值。因为它是一个单值函数,所以我们将该函数的导数赋值给另一张图像。然后,你就可以使用这个图像来欺骗神经网络,也就是用我们在这篇文章前面讨论的方法!打破神经网络下面是关于如何打破一个线性函数/逻辑回归与神经网络的关系!也就是你一直在等待的数学原理!思考下我们的图像,损失函数看起来像:其中,梯度grad等于∇L(x)。因为这是微积分。为了让损失函数的变化的更多,我们要最大化移动的delta和梯度grad两者的点积。让我们通过compute_gradient()函数计算梯度,并把它画成一个图片:直觉告诉我们需要做的是创建一个delta,它重点强调神经网络认为重要的图像像素。现在,假设grad为(−0.01,−0.01,0.01,0.02,0.03).我们可以取delta=(−1,−1,1,1,1),那么grad⋅delta的值为0.08.。让我们尝试一下!在代码中,就是delta

np.sign(grad)。当我们通过这个数量移动时,果然–现在熊猫变成黄鼠狼了。但是,这是为什么呢?让我们来思考下损失函数。我们开始看到的结果显示,它是熊猫的概率为99.57%。−log(0.9957)=0.0018。非常小!因此,添加一个delta倍会增加我们的损失函数,而减去一个delta倍会减少我们的损失函数。但事实正好相反!我对这一点还是很困惑。你欺骗不了狗现在我们了解了数学原理,一个简短的描述。我还尝试去欺骗网络,让它识别先前那只可爱的小狗:但对于狗,网络会强烈地抵抗将其归类为除狗之外的东西!我花了一些时间试图让它相信那只狗是一个网球,但是它仍然是一只狗。是其它种类的狗!但仍然还是一只狗。我在一个会议上遇到了Jeff Dean,并向他请教了这一点。他告诉我,这个网络在训练集中有一堆狗,比熊猫多。所以他假设是要训练更好的网络来识别狗。似乎有道理!我认为这非常酷,这让我觉得训练更精确的网络更有希望。关于这个话题还有另一件更有趣的事情–当我试图让网络认为熊猫是一只秃鹫时,它在中间花了一点时间去思考它是否是鸵鸟。当我问Jeff Dean关于熊猫和狗这个问题时,他随口提到了“熊猫鸵鸟空间”,而我并没有提到让网络认为熊猫是秃鹫时曾思考过它是否是鸵鸟。这真的很酷,他用数据和这些网络花足够的时间一下子就清楚地知道鸵鸟和熊猫以某种关系紧密地结合在一起。更少的神秘感当我开始做这件事的时候,我几乎不知道什么是神经网络。现在我可以使它认为熊猫是一只秃鹰,并看到它是如何聪明的分类狗,我一点点的了解他们。我不再认为谷歌正在做的很神奇了,但对于神经网络我仍然很疑惑。有很多需要学习!使用这种方式去欺骗它们,会消除一些神秘感,并且现在对它们的了解更多了。相信你也可以的!这个程序的所有代码都在neural-networks-are-weird这个仓库中。它使用的是Docker,所以你可以轻易地安装,而且你不需要一个GPU或是新电脑。这些代码都是在我这台用了3年的老GPU笔记本上运行的。想要了解更多,请阅读原论文:Explaining and Harnessing Adversarial Examples。论文内容简短,写得很好,会告诉你更多本文没提及到的内容,包括如何使用这个技巧建立更好的神经网络!最后,感谢Mathieu Guay-Paquet, Kamal Marhubi以及其他在编写这篇文章帮助过我的人!原文地址:How to trick a neural network into thinking a panda is a vulture

解释线性分类

线性分类器通过求一张图片三个通道所有像素的权重和来计算计算类别分数。 通过设置这些权重值,类别函数可以“喜欢”或“不喜欢”图片特定位置的像素颜色。比如, 你可以想象类别为“船”的图像,它周边的蓝色像素值比较高,所以你可以预期类别船在蓝色通道有很多正的权重(蓝色的出现提高了类别船的分数),而在红色/绿色通道有很多负的权重(红色/绿色的出现降低了船的分数)。

将一张图片映射到类别分数的一个例子。为了显示的简单性,我们假设这张图只有四个像素,三个类别(红色(猫), 绿色(狗)和蓝色(船))。我们把图像的像素放入一个列向量中,进行矩阵乘法来获得每个类别的分数。注意 这个W设置的并不好,把这张猫的图片赋予猫类别的分数很低,而且这个参数W似乎认为它更像一条狗

图像与高维度点集的类比

因为图像可以看成高维度的列向量,我们可以把每张图看做成在这个空间中的一个点(比如, 在CIFAR-10中,图像可以看做是3072维度上的一个点),所以整个数据集可以看成是一个点的集合。

因为我们把类别的分数看成这张图片的所有像素权重和,那么每个类别分数可以看成是在这个空间内的一个线性函数。我们无法直观地感受3027维度的空间,但是如果我们能把所有的点放在二维空间内,那我们就可以直观地看到这个分类器做了些什么:

图像空间的卡通展示,其中每张图片是一个点,三条直线表示三个分类器。以汽车分类器(红色)为例:红线表示所有汽车类别分数为0的点。红色的箭头表示增长的方向,所以在红色线的右边的点,其汽车类别分数为正(离的越远,其类别分数值越高), 所有在红色线左边的点,其汽车类别分数为负(离的越远,其类别分数值越小)

我们知道, W的每一行都是一个类别的分类,这些数字的几何解释是,当我们改变W中一行中的某些数字,在像素空间中对应的直线会沿不同方向上旋转。偏置量b可以使得这些直线的位移发生变化。特别地,如果没有偏置量,而且Xi=0,那么不管权重取什么值,得到的分数都是0。所有的直线都被迫穿过原点。

把线性分类器作为模型匹配的解释

权重W的另外一个解释是W的每一行都对应于一个类别的模型(有的时候也称之为原型)。一个图像的类别分数通过內积来比较图像与各个模型的匹配程度。使用这种术语, 线性分类器就是模型匹配,这些模型都是通过学习获得的。另一种思考方式是它在做最近邻分析。不同的是,之前是和训练集中所有的图像进行比较,现在只需要和一张图像比较(这张图片不一定是训练集中的一张图片)。同时,我们使用(负)內积来作为距离,而不是L1或者L2距离。

CIFAR-10的学习权重,以船类别为例,与预期的一样,船类别包含许多蓝色的像素,所以如果与在海洋中的船图像做內积,将会得到一个更高的类别分数。

从上图我们可以观察到,马的模型好像包含一个双头马,这是因为在数据集中马既有朝左的,也有朝右的。线性分类器把数据集中马的这两种模式都编码到一个模型当中。类似的,车分类器似乎融合了各个朝向和颜色的车。特别地, 这个车模型的颜色是红色。说明在CIFAR-10中,红色的车远多于其他颜色的车。这个线性分类器在分类不同颜色的车时比较弱,在后面我们会看到神经网络可以使得我们很好地识别不同颜色的车。先剧透一下,神经网络可以在隐藏层里有中间的神经网络,它可以识别特定模式的车(比如,朝左的绿色的车, 朝前的蓝色的车等)。而下一层的神经元可以把这些特征都结合起来,通过一个权重和,获得一个更准确的车类别分数。

偏置的小技巧

在继续进行下去之前,我们来讲一个将W和b合并成一个参数的小技巧,回忆一下,我们将分数函数定义为

我们之后会发现要记录两个参数W和b会有些麻烦,一个常用的小技巧是将W和B表示为一个矩阵,它通过将Xi扩展一个维度,并且这个维度的值一直为1。增加一个维度之后,新的分数函数将被简化为一个矩阵乘法:

以CIFAR-10为例,Xi 现在是[3073x1],而不是[3072x1](多出来的维度里面的值为1)。W现在是[10x3073]而不是[10x3072]。W中多出来的一列对应于偏置值b。下面的图示可以帮助理解:

偏置技巧的示意图。先做一个矩阵乘法,然后在加上一个偏置向量(如左边所示)与 如下做法是等价的,即在输入向量中加入一个维度,将其值设为1,将权重矩阵也扩充一列,将这列的值设为偏置向量的值,再将这两个矩阵相乘。所以,如果我们对数据进行以上的预处理,那么我们只需要操作一个单独的矩阵了

图像数据预处理

在上面的例子中,我们使用的是原始的像素值([0...255])。 在机器学习中,将输入特征归一化(在图像的例子中,每个像素可以看做是一个特征)是一个常见的做法。特别地, 通过减去每个特征的平均值,将每个特征中心化非常重要。在图像的领域中,对应的做法是计算训练集的平均图片,再将每张图片减去这个平均图片,就可以得到像素值在[-127,127]范围内的像素矩阵。更常见的做法是将像素值再缩放到[-1,1]的范围内。其中,零中心化非常重要,但是我们要等到我们理解了梯度下降的动态性,我才会证明它的重要性。

损失函数

在上一节中我们通过权重W,定义了一个将像素值映射到类别分数的函数。我们无法改变数据值(Xi,yi),但是我们可以控制这些权重,我们想要通过设定它们的值,使得我们预测的类别分数能够和真实的标签一致。

以之前的猫的例子为例,它的类别函数在猫,狗和船类别中做出预测。我们发现那个权重设置的并不好,我们输入一只猫的像素,但是猫的类别分数(-96.8)并不比其他两类高(狗的分数为437.9,船的分数为61.95)。我们用损失函数(有时候也称之为花费函数或目标函数)测量我们对结果的不满意。从直觉上来说,如果损失函数大,那么我们分类结果不是很好,反之,如果分类结果好,则损失函数的值就会很低。

多类别支持向量机损失

有很多定义损失函数的方法,第一个例子是常用的损失函数:多类别支持向量机损失(Multiclass Support Vector Machine Loss)。SVM损失希望正确的类别分数比不正确的类别分数至少高Δ。有时候把损失函数做上面那样的类比是正确的,即SVM希望最终的损失值比较小。

现在我们具体来说明,对于第i张图片,我们已知这张图片的所有像素Xi和它的类别标签yi,分数函数输入图像的像素,输出一个类别分数的向量,我们用s表示。比如,第j个类别的分数我们可以表示为Sj, 那么第i张图片的多类别SVM损失可以表示为

例子

让我们用一个例子来说明。假设我们有三个类别,它们的分数是s=[13,-7,11]。其中 第一个类别是正确的类别。我们假设Δ(超参数,后面我们会详细讨论)为10。上面的公式是把所有不正确的类别分数加起来,我们得到两项:我们可以发现第一项等于零,因为[-7-13+10]为负数。所以这一项的损失为0,因为正确类别的分数(13)至少比不正确类别分数(-7)大10.实际上, 它们之间的差距是20,比10大得多。但是我们只关心它是否比10大。第二项[11-13+10]为8,虽然错误类别分数比正确类别分数小,但是它们之间的差异小于10.所以SVM损失希望正确类别的分数至少比错误类别的分数大Δ,如果不是这种情况,那么损失就会累积。

在这个特殊的例子中, 我们使用的是线性分数函数f(xi;W) = Wxi,所以我们可以把损失函数改写为:

其中Wj是W的第j行。注意当我们考虑更复杂的f时,情况就会不同。

在结束这一节之前,我们再介绍一个术语:铰链损失(hinge loss)。它指的就是max(0, -)定义的损失函数。你有时候会看到人们使用平方铰链损失(或者L2-SVM),它使用max(0, -)^2来加强损失的程度。标准铰链损失是一种常见的做法,但是有时候平方铰链损失能达到更好的结果, 这可以通过交叉验证来决定。

损失函数用来把我们对测试集的测试不满意度量化。

多类别支持向量机“希望”正确类别的分数至少比其他的分数高Δ, 任何在红色区域的类别分数(或更高)都会累积损失值,其他情况,损失值为0。我们的目标是找出一个权重值,使得在训练集中所有的图像都满足这个限制,并且整个损失越低越好。

正则项

我们上面给出的损失函数有一个错误。假设我们有一个数据集和可以将每一类都正确分类参数W。那么这样的W不是唯一的。还有很多相似的W可以将数据集中的例子正确分类。一个简单的例子:如果W能够正确地将例子分类,那么W的倍数λW(λ>1)也能使损失为0,因为这个变换将所有的分数都增加了,它们的差异分数也是。比如,如果一个正确的类与一个最近的错误的类之间的差异分数为15,那么把W中所有的权重乘2,新的差异就变为30。
我们将通过一种方法使得W能够去除这种不确定性。即通过在损失函数中增加正则惩罚(regularization penalty)R(W). 最常见的正则惩罚是L2,它通过逐元素的平方惩罚能够识别数值较大的权重。公式如下:

在上面的表达式中,我们把W所有权重的平方加起来了。注意正则函数不是关于数据的函数,它只基于权重。加入权重惩罚之后,多类别支持向量机公式才完成了,它包括两个部分:一个是数据损失(它是所有例子的平均损失),一个是正则损失。最终完整的多类别SVM损失函数为:

或者把它扩展为一个完整的形式:

其中N为训练例子的数目。你可以看到,我们将正则惩罚项加入到了损失函数中,并使用λ控制它的权重。没有一个简单的方式设置这个超参数,它经常是使用交叉验证的方式来确定。

除了以上提到的原因外,加入正则项还有其他的好处。我们会在后面的内容讲到。例如,加入L2项可以使得SVM容易获得最大的边界(max margining)。
惩罚数值大的权重的一个最大的好处是可以提高可扩展性。它意味着没有一个单独的输入维度可以对结果产生过大的影响。比如:我们有一个输入向量:x=[1,1,1,1]和两个权重向量 w1=[1,0,0,0]和w2=[.25,.25,.25,.25]。它们都与输入向量的点积都为1, 但是w1的L2惩罚项为1.0 而w2的L2惩罚项为0.25。因此,w2是更好的权重向量。直观上,我们可以看出w2中权重值更小,也更分散,最终的分类器也依赖于更多的权重。在之后的课程我们可以看到,这个行为可以增加可扩展性,减少过度拟合。
注意偏置项并没有相同的效果。因为,不像权重值,它们没有控制输入维度的影响力。因此,通常只对W进行正则化。但是,在实践中,如果也将偏置项正则化,影响也可以忽略不计。最后,由于我们加入了正则惩罚,损失项永远不可能达到0,除非W中的权重都为0.

下一篇:没有了