深度学习 | 斯坦福cs231n第二讲学习笔记 --- Linear Classification

课程主页

课程视频

课程PPT

斯坦福cs231n学习笔记系列博客基于cs231n 2017年春季版,课程主要内容关于视觉识别和深度学习,主要介绍卷积神经网络。

第二讲学习笔记主要更一步介绍图像分类问题,采用相对高级的线性分类器。

目录

1.Linear Classification简介

2.Linear score function

3.Linear classifier的解释

3.损失函数

4.总结

5.拓展阅读


1.Linear Classification简介

在上一节中,我们介绍了图像分类问题,即从固定的一组类别中为图像分配单个标签/类别的任务。此外,我们学习了k近邻(kNN)分类器,它通过将测试图像与训练集(带标签)的每张图像进行比较,找出距离前k近的训练图像,通过投票来标记该测试图像。正如我们之前学习的那样,kNN有很多缺点:

  • 分类器必须记住所有训练数据并将其存储以备将来与测试数据进行比较。 空间效率非常低下,因为数据集的大小可能很容易超过千兆字节。
  • 对测试图像进行分类的计算代价是昂贵的,因为它需要与所有训练图像进行比较。不符合实际应用的要求,我们希望测试过程能越快越好,训练慢些没关系,而kNN正好相反。

我们现在将开发一种更强大的图像分类方法,以便最终将自然地扩展到神经网络或卷积神经网络。 该方法将有两个主要组成部分:将原始数据映射到类别分数的分数函数,以及量化预测类别分数与真实类别标签之间一致性的损失函数。 然后我们将这个转化为一个优化问题,我们将通过优化模型参数最小化损失函数,从而得到一组最优的模型参数。

 

2.Linear score function

该方法的第一个组成部分是定义分数函数,该分数函数将图像的像素值映射到每个类的置信度分数。 我们将通过一个具体的例子来开发该方法。 和之前一样,我们假设训练集中的每张图像是D维空间中的一个点,即图像x_{i} \in R^{D},每张图像都有一个对应的的类别标签y_{i}。 这里i = 1,...,N,y_{i} \in 1,...,K. 也就是说,我们有N个训练样本/图像(每个都有D维)和K个不同的类别。 例如,在CIFAR-10中,我们有一个N = 50,000个图像的训练集,每个图像的D = 32 x 32 x 3 = 3072像素,K = 10,因为有10个不同的类(狗,猫,汽车等))。 我们现在将定义得分函数f:R^{D} -> R^{K},其将原始图像像素映射到类别得分。

  • Linear classifier

在本小节,我们将从最简单的函数开始,即线性映射:

在上面的等式中,我们假设图像x_{i}将其所有像素平坦化为形状[D×1]的单个列向量。 矩阵W(大小为[K x D])和向量b(大小为[K x 1])是函数的参数。 在CIFAR-10中,x_{i}包含第i个图像中的所有像素,扁平化为单个[3072 x 1]列向量,W为[10 x 3072],b为[10 x 1],因此3072个数字进入函数( 原始像素值)和10个数字出来(类别分数)。 W中的参数通常称为权重,b称为偏差矢量/偏置参数,因为它影响输出分数,但不与实际数据x_{i}相互作用。 但是,你经常会听到人们互换使用术语权重和参数。

由下面几点需要注意:

1.首先,请注意矩阵乘法Wx_{i}有效地并行评估10个单独的分类器(每个类别一个),其中每个分类器对应W中的一行。

2.另请注意,我们将输入数据(x_{i},y_{i})视为给定和固定的,但我们可以控制参数W,b的设置。 我们的目标是以这样的方式设置参数,使得计算得分与训练集中的真实类别标签相匹配。 我们将详细介绍如何完成此操作,但直观地说,我们希望正确类别的得分要高于其他不正确类别的得分。

3.这种方法的一个优点是训练数据用于学习参数W,b,但是一旦学习完成,我们就可以丢弃整个训练集并且仅保留学习好的参数。 这是因为新的测试图像可以简单地通过该函数,并基于在最优参数下函数计算出的类别得分,来进行分类。

4.最后,请注意,对测试图像进行分类涉及单个矩阵乘法和加法,这比kNN中将测试图像与所有训练图像进行比较要快得多。

我们之后学习的卷积神经网络也是将图像像素映射到完全如上所示的类别分数,但映射(f)将更复杂并且将包含更多参数。

 

3.Linear classifier的解释

请注意,线性分类器将每个类别的分数计算为图像所有3个颜色通道中所有像素值的加权和。 根据我们为这些权重设置的确切值,该函数具有在图像中的某些位置处喜欢或不喜欢(取决于每个权重的符号)某些颜色的能力。 例如,你可以想象如果图像两侧有很多蓝色(可能与水相对应),“船”类会更有可能。 你可能会认为“船”分类器在图像蓝色通道上的权重大于0的值更多(蓝色的存在会增加船的得分),红色/绿色通道中的负权重比较多(红色/绿色的存在会降低船的分数)。

上图是将图像像素值映射到类别得分的简单示例。为了方便可视化,我们假设图像只有4个像素(4个单色像素,为简洁起见,我们在此示例中不考虑颜色通道),并且我们有3个类别(红色(猫),绿色(狗),蓝色) (船)类)。 (注意上图中的颜色只是表示3个类,与RGB通道无关。)我们将图像像素拉伸到一列并执行矩阵乘法以获得每个类的分数。 请注意,这组特定的权重W(W中的每一行权重参数都对应一个单独的分类器,如上图中第一行代表一个猫分类器,可以得到猫类别的得分)并不是很好:权重为我们的猫图像指定了非常低的猫得分。 特别是,这组权重似乎确信它是一只狗。

  • 将图像看作是高维空间中的点

由于图像被拉伸为高维列向量,我们可以将每个图像解释为该空间中的单个点(例如,CIFAR-10中的每个图像是32×32×3像素,可以看作是3072维空间中的点)。 类似地,整个数据集是(标记的)是高维空间中的点集。

由于我们将每个类别的得分定义为所有图像像素值的加权和,因此每个类别得分是该空间上的线性函数。 我们无法想象3072维空间,但如果我们想象将所有这些维度压缩到只有两个维度,那么我们可以尝试可视化分类器可能正在做什么:

上图是图像空间的卡通表示,其中每个图像是单个点(压缩为2维空间),并且可视化三个线性分类器(每个分类器对应权重矩阵W中的一行,用于计算一个类别的得分)。 使用汽车分类器的示例(红色),红线显示空间中汽车类得分为零的所有点。 红色箭头显示汽车类得分增加的方向,因此红线右侧的所有点都有正(并且线性增加)分数,左边的所有点都有负(并且线性减少)分数。其他类别亦然。

如上所述,W的每一行都是其中一个类的分类器。 这些数字的几何解释是,当我们改变W的一行时,像素空间中的对应线将以不同的方向旋转。 另一方面,偏差b允许我们的分类器移动线条。 特别要注意的是,如果没有偏差项,插入xi = 0总是会得分为零而不管权重如何,因此所有线都将被强制越过原点。

 

  • 将线性分类器解释为模板匹配

将线性分类器解释为模板匹配。 权重W的另一种解释是W的每一行对应于一个类的模板(或有时也称为原型)。 然后通过逐个地使用内积(或点积)将每个模板与图像进行比较来获得图像的每个类的得分,以找到“最适合”的那个(分数最高的那个)。 使用这个术语,线性分类器正在进行模板匹配,模板(参数)已经学好了。 想到这一点的另一种方式是我们仍然在有效地做最近邻,但是我们把测试图像与每个类的单个图像(与每个类的模板进行比较)而不是数千个训练图像(尽管我们将学习模版(参数),并且它(模版)不一定必须是 训练集中的图像),我们使用内积作为距离而不是L1或L2距离。

上图是在学习CIFAR-10结束时学习的权重示例。每一幅图对应权重矩阵W中的一行,对应一个类别分类器,是该类别的一个模版。 请注意,例如,船模板包含许多预期的蓝色像素。 因此,一旦与海洋上的船舶图像匹配进行内积,该模板将给出高分。

另外,请注意马模板似乎包含一个双头马,这是由于数据集中面向左右两侧的马。线性分类器将数据中的这两种马模式合并为单个模板。同样,汽车分类器似乎已将几种模式合并为一个模板,该模板必须识别来自所有侧面和所有颜色的汽车。特别是,这个模板最终变成红色,这暗示CIFAR-10数据集中的红色汽车比任何其他颜色都多。线性分类器太弱而无法正确解释不同颜色的汽车,但正如我们稍后将看到的,神经网络将允许我们执行此任务。神经网络将能够通过其隐藏层中的中间神经元,检测特定的汽车类型(例如,面向左侧的绿色汽车,面向前方的蓝色汽车等),下一层的神经元可以将这些组合在一起通过各个汽车探测器的加权总和得到更准确的汽车得分。

  • 偏差技巧

在继续学习之前,我们想提到一个常见的简化技巧,将两个参数W,b表示为一个。 回想一下,我们将得分函数定义为:

当我们继续学习时,分别跟踪两组参数(偏差b和权重W)有点麻烦。 一个常用的技巧是将两组参数组合成一个矩阵,通过扩展矢量x_{i}来保持它们两者,在x_{i}中增加一个维度,并且其值设置为1  - 默认的偏差维度。 使用额外维度,新分数函数将简化为单个矩阵乘法:

使用我们的CIFAR-10示例,x_{i}现在是[3073 x 1]而不是[3072 x 1]  - (额外维度保持常量1),W现在是[10 x 3073]而不是[10 x 3072]。 W增加对应于偏差b的额外列。 如下所示:

进行矩阵乘法然后添加偏置向量(左)相当于向所有输入向量添加常数为1的偏置维,并将权重矩阵扩展1列 - 偏置列(右)。 因此,如果我们通过将数据附加到所有向量来预处理数据,我们只需要学习单个权重矩阵而不是两个保持权重和偏差的矩阵。

  • 图像数据预处理

在上面的例子中,我们使用了原始像素值(范围从[0 ... 255])。 在机器学习中,常见做法是对输入特征进行规范化(在图像的情况下,每个像素值都被视为一个特征)。 特别是,通过从每个特征中减去平均值,来居中数据非常重要。 在图像的情况下,这对应于计算训练图像上的平均图像并从每个图像中减去它以获得像素的范围为大约[-127 ... 127]的图像。 进一步常见的预处理是缩放每个输入特征(除以标准差),使其值的范围为[-1,1]。 其中,零均值化可能更重要,具体原因等到学习完梯度下降后再做解释,它可以加速梯度下降速度,加速模型训练。
 

3.损失函数

在上一节中,我们定义了一个从像素值到类别得分的函数,它由一组权重W参数化。而且,我们看到我们无法控制数据(x_{i},y_{i}) (它是给定和固定的),但是我们可以控制这些权重,我们想要设置它们,以便让预测的类别分数与训练数据中的真实标签一致。

例如,回到之前猫示例图像分类的例子,有“猫”,“狗”和“船”三个类别,得到对应这三个类别的分数。我们看到该示例中的权重取值不是很好:我们输入猫图像的像素值,与其他类别(狗得分437.9和船舶得分61.95)相比,猫得分非常低(-96.8)。 我们将衡量我们对结果/输出的不满,例如使用损失函数(或有时也称为成本函数或目标)计算的结果。 直观地说,如果我们在对训练数据进行分类方面做得很差,那么损失就会很高,如果我们做得好的话,它就会很低。

  • 多分类SVM损失

有几种方法可以定义损失函数。 作为第一个例子,我们将首先使用一种常用的损失函数,称为多分类支持向量机(SVM)损失。 SVM损失被这样设置,使得SVM“想要”每个图像的正确类别的得分高于其他不正确类别得分一定的固定余量Δ。 SVM“想要”某种结果/输出,结果/输出会产生较低的损失(这是好的)。

现在给出更精确的定义。 回想一下,对于第i个训练样本/图像,我们给出了图像像素值拉伸后的向量x_{i}和对应的正确类别标签索引y_{i}。 得分函数计算出各类得分的向量f(x_{i},W),我们将其缩写为s。 例如,第j(j=1,...,K)类的得分是得分向量的第j个元素:s_{j}=f(x_{i},W)_{j}。 然后将第i个训练样本/图像的多类SVM损失形式化如下:

例子:

让我们用一个例子解释它,看看它是如何工作的。 假设我们得到三个类别得分s = [13,-7,11],并且第一个类是正确的类(即y_{i} = 0)。 还假设Δ(这是一个超参数,我们将很快详细介绍)是10。上面的表达式总结了所有不正确的类(j≠yi),因此我们会得到两项:

你可以看到第一项给出零,因为[-7  -  13 + 10]给出一个负数,然后使用max(0, - )函数将其阈值化为零。我们得到零损失,因为正确的类别分数(13)比不正确的类别分数(-7)大至少10分。事实上,差异是20,远远大于10,但SVM仅仅关心差异至少要为10;高于margin的任何额外差异在最大操作时被钳制为零。第二项计算[11  -  13 + 10],得出8.即使正确的类别得分高于不正确的类别得分(13> 11),但是他们的差距不比设置的margin10大,只有2,这就是损失达到8的原因(即,为了满足margin,需要多大的差别)。总之,SVM损失函数希望正确类别yi的得分比不正确的类别得分大至少Δ(delta/margin)。如果不是这种情况,我们将累积损失。

注意,在本小节中,我们使用线性得分函数(f(x_{i},W)=Wx_{i}),因此我们也可以用这种等效形式重写损失函数:

其中w_{j}是W的第j行重新转形为列向量(计算第j个类别的得分)。 然而,一旦我们开始考虑更复杂形式的得分函数f,情况就不一定如此。

在我们完成本节之前我们将提到的最后一个术语是 zero max(0, - )函数的阈值通常称为hinge 损失。 你有时会听到人们使用平方hinge损失SVM(或L2-SVM),它使用形式为max(0,-)^{2}来更强烈地惩罚违反margin(正确类别得分要比不正确类别得分高出margin,不满足margin时,平方会使损失更大)(平方而不是线性)。 非平方版本更标准/常用,但在某些数据集中,平方hinge损失可以更好地工作。 这可以在交叉验证期间确定。

损失函数量化了我们对训练集预测的不满程度:

多分类支持向量机“希望”正确类别的分数比所有其他不正确类别的分数高至少delta/margin的余量。 如果任何一个类别在红色区域(或更高区域)内有分数,则会累积损失。 否则损失将为零。 我们的目标是找到同时满足训练数据中所有训练样本/图像约束的权重,并给出尽可能低的总损失(通过最小化损失,优化权重,最后得到一组最优的权重)。

 

  • 正则化

我们之前介绍的损失函数有一个bug。 假设我们有一个训练集和一组参数W,它们可以正确地对每个训练样本进行分类(即所有分数都满足margin,并且每个训练样本i的损失Li = 0)。 问题是这组W不一定是唯一的:可能有许多类似的W也能正确地对所有训练样本进行分类。 一个简单的方法是,如果某些参数W正确地对所有训练样本进行分类(因此每个训练样本的损失为零),那么对于λ> 1,所有λW的任何倍数也将给出零损失,因为该变换均匀地拉伸所有分数的量级 因此也是他们的绝对差异。 例如,如果正确类和最近的不正确类之间的分数差异为15,那么将W的所有元素乘以2将使新差异为30。

换句话说,我们希望对某组特定权重W的某些偏好(some preference)进行编码,以消除这种歧义。 我们可以通过用正则化惩罚项R(W)来扩展损失函数来实现。 最常见的正则化惩罚项是L2范数,它通过对权重W中的所有元素取平方再求和进行惩罚,来避免出现大的权重:

在上面的表达式中,我们对W中所有元素的平方求和。注意,正则化函数不是数据的函数,它仅基于权重。 完整的多类支持向量机损失函数,其由两个部分组成:数据损失(所有训练样本的损失Li取平均)和正则化损失。 也就是说,完整的多类SVM损失变为:

或以完整形式来扩充他(使用之前的线性得分函数):

其中N是训练样本的数量/训练集的大小。 如你所见,我们将正则化惩罚项附加到损失函数中,由超参数λ加权。 没有简单的方法来设置这个超参数,它通常由交叉验证/验证集决定/调试。

除了我们上面提供的使用正则化的动机/原因之外,还有许多理想的属性/特性需要包括正则化惩罚,其中许多我们将在后面的章节中回过头来看。 例如,事实证明,包括L2惩罚会使SVM具有最大间隔(margin)特性(如果您感兴趣,请参阅 CS229讲义以获取完整详细信息)。

最有吸引力的特性是通过正则化惩罚大权重,可以提高模型的泛化能力,因为这意味着没有哪个输入维度可以对分数本身产生非常大的影响。例如,假设我们有一些输入向量x = [1,1,1,1]和两个权向量w1 = [1,0,0,0],w2 = [0.25,0.25,0.25,0.25]。然后W_{1}^{T}x=W_{2}^{T}x=1因此两个权重向量导致相同的点积,但是w1的L2罚分是1.0而w2的L2罚分仅为0.25。因此,根据L2惩罚,权重向量w2将是优选的,因为它实现了较低的正则化损失。直觉上,这是因为w2中的权重较小且更加分散。由于L2惩罚倾向于使用更小且更分散的权重向量,因此鼓励最终分类器将所有输入维度对应一个小权重而不是有一些输入维度对应非常大的权重。正如我们将在本课后面看到的,这种效果可以提高分类器在测试图像上的泛化性能,并减少过度拟合(使分类器在没有见过的图像上也能取得很好的效果,过拟合意味着分类器在训练集上准确率很高,在测试集上很低,2者差距很大,正则化可以缓解过拟合,降低分类器在训练集上的表现,提高其在测试集/没有见过的样本上的表现,这才是我们真正关心的)。

注意,偏差不具有相同的效果,因为与权重不同,它们不能控制每个输入维度对结果的影响强度。 因此,通常正则化项中仅调整权重W而不包括偏差b。 然而,在实践中,包不包括偏差b这通常会产生微不足道的影响,无伤大雅。 最后,请注意,由于正则化惩罚,我们永远无法在所有训练样本中实现精确0.0的损失,因为这只能在W = 0的病理设置中实现。

 

这是在Python中实现的损失函数(没有正则化),有非向量化和半向量化形式:

def L_i(x, y, W):
  """
 非向量化版本. 对单个样本 (x,y)计算多分类SVM损失。
  - x 是一个列向量,表示一个图像 (e.g. 3073 x 1 CIFAR-10)
    包含一个偏置维度,其值为1
  - y是一个整数 表示该训练样本对应正确类别标签的索引 (e.g. 在CIFAR-10是 0-9)
  - W 权重矩阵 (e.g. 10 x 3073  CIFAR-10)
  """
  delta = 1.0 
  scores = W.dot(x) # 得到每个类别的得分向量。 CIFAR-10 中(10,1)
  correct_class_score = scores[y] #正确类别对应的得分
  D = W.shape[0] # 分类的类别数 如10
  loss_i = 0.0
  for j in range(D): # 遍历所有错误类别
    if j == y:
      # 跳过正确类别
      continue
    # 累加第i个训练样本的损失
    loss_i += max(0, scores[j] - correct_class_score + delta)
  return loss_i

def L_i_vectorized(x, y, W):
  """
  一个更快的半向量化实现版本. 半向量化实现指的是对于单个训练样本计算损失的过程
   没有任何for循环,但是仍然需要一个for循环遍历所有训练样本(在此函数之外)
  """
  delta = 1.0 
  scores = W.dot(x) # 得到每个类别的得分向量。 CIFAR-10 中(10,1)
  # 计算正确类别与所有不正确类别的得分margin。得到一个向量。如10*1
  margins = np.maximum(0, scores - scores[y] + delta)
  # 向量的第y个位置 scores[y] - scores[y] 抵消 只剩下delta. 
  # 忽略第y个位置。仅考虑不正确的类别的margin
  margins[y] = 0
  loss_i = np.sum(margins) #求和 得到单个训练样本的损失
  return loss_i

def L(X, y, W):
  """
  全向量实现版本:
  - X 包含所有的训练样本 每一列代表一个训练样本 (e.g. 3073 x 50,000 in CIFAR-10)
  - y 包含所有训练样本对应的正确类别标签的索引 (e.g. 50,000-D array)
  - W 权重 (e.g. 10 x 3073)
  """
  # 遍历X中的所有训练样本来计算损失 不需要任何循环
  #剩余部分在实验中实现

本节的内容是SVM损失采用一种特殊的方法来衡量训练数据的预测与真实类别标签的一致性。 此外,对训练集进行良好预测相当于最大限度地减少损失。

我们现在需要做的是通过一种方法找到一组最优的权重来最小化损失。

 

实际应用中要考虑的因素:

1.设置delta:注意,我们不主要考虑超参数Δ及其设置。 应该设置什么值,我们是否必须交叉验证它? 事实证明,在所有情况下,这个超参数可以安全地设置为Δ= 1.0。 超参数Δ和λ看起来像两个不同的超参数,但实际上它们都控制着相同的权衡:数据损失与正则化损失之间的权衡。 理解这一点的关键是权重W的大小直接影响分数(因此也影响分数之间的绝对差异):当我们缩小W内的所有值时,每个类别的分数会变低,分数间的差异将会变得更低,并且当我们按比例增加分数时 差异将变得更高。 因此,分数之间的边界的精确值(例如Δ= 1,或Δ= 100)在某种程度上是没有意义的,因为权重可以任意缩小或拉伸差异。 因此,唯一真正的权衡是我们允许权重增长的程度(通过正则化惩罚系数λ)。

2.联系2分类SVM:我们之前学习过2分类SVM,其中第i个训练样本的损失可以写成:

其中C是超参数,y_{i}∈{-1,1}两个类别。 我们本节介绍的多分类SVM包括这个2分类SVM的特殊情况,只有两个类别。 也就是说,如果我们只有两个类,损失函数可以化简为上述的2分类SVM的形式。 此外,该公式中的C和我们公式中的λ控制相同的权衡,2者具有倒数关系C \propto 1/\lambda

3.原始优化。 我们之前学习SVM时,可能听说过kernels,duals,SMO算法等。在cs231n课程中(主要是学习神经网络,一般来说和神经网络的情形一样)我们将一直使用 无约束原始形式的优化目标。 这些目标大多在技术上是不可微分的(例如,max(x,y)函数在x=y时有纽结kink),但实际上这不是问题,通常使用子梯度subgradient。

4.Other Multiclass SVM formulations. It is worth noting that the Multiclass SVM presented in this section is one of few ways of formulating the SVM over multiple classes. Another commonly used form is the One-Vs-All (OVA) SVM which trains an independent binary SVM for each class vs. all other classes. Related, but less common to see in practice is also the All-vs-All (AVA) strategy. Our formulation follows the Weston and Watkins 1999 (pdf) version, which is a more powerful version than OVA (in the sense that you can construct multiclass datasets where this version can achieve zero data loss, but OVA cannot. See details in the paper if interested). The last formulation you may see is a Structured SVM, which maximizes the margin between the score of the correct class and the score of the highest-scoring incorrect runner-up class. Understanding the differences between these formulations is outside of the scope of the class. The version presented in these notes is a safe bet to use in practice, but the arguably simplest OVA strategy is likely to work just as well (as also argued by Rikin et al. 2004 in In Defense of One-Vs-All Classification (pdf)).

 

  • Softmax分类器

事实证明,SVM是两种常见的分类器之一。 另一个受欢迎的选择是Softmax分类器,它具有不同的损失函数。 如果你之前听说过二元Logistic回归分类器(2分类),则Softmax分类器是其在多分类(>=2)上的推广。 与将输出f(x_{i},W)视为每个类的(未校准且可能难以解释)分数的SVM不同,Softmax分类器提供稍微更直观的输出(标准化类概率)并且还具有概率解释的简要描述。 在Softmax分类器中,函数映射f(x_{i},W)=Wx_{i}保持不变,但我们现在将这些分数解释为每个类的非标准化对数概率,并用具有以下形式的交叉熵损失替换hinge损失:

我们使用符号f_{j}表示类别得分向量f的第j个元素。 如前所述,数据集的完整损失是所有训练样本的损失Li的平均值以及正则化项R(W)。 函数f_{j}(z) = e^{z_{j}}/\Sigma_{k}e^{z_{k}}称为softmax函数:它采用任意实值得分向量z,并将其压缩为各个分量取值在0到1之间的向量,该向量总和为1。 如果你第一次看到它,那么涉及softmax函数的完全交叉熵损失可能看起来很可怕但是它相对容易激励/激活。

信息论观点。 “真实”分布p和估计分布q之间的交叉熵定义为:

Softmax分类器最小化估计的类别概率(如上所示的q=e^{f_{y_{i}}}/\Sigma_{j}e^{f_{j}})和“真实”分布之间的交叉熵,真实分布的所有概率集中在正确类别上( 即p = [0,... 1,...,0]在第y_{i}个位置包含单个1。)。 此外,由于交叉熵可以用熵和Kullback-Leibler散度写成H(p,q)=H(p)+D_{KL}(p||q),并且delta函数p的熵是 零,这也相当于最小化两个分布之间的KL散度(一种距离度量)。 换句话说,交叉熵目标希望预测分布的所有概率都在正确的答案上。

 

概率解释。 观察下列表达式:

可以解释为给定图像x_{i}由W参数化分配给正确标签y_{i}的(标准化)概率。为此,请记住Softmax分类器将输出向量f内的分数解释为非标准化的log(对数)概率。因此,指数这些分量给出(非标准化的)概率,并且除法执行归一化以使概率总和为1。在概率解释中,我们最小化正确类的负对数似然,其可被解释为执行最大似然估计(MLE)。这个观点的一个很好的特点是我们现在也可以将完整损失函数中的正则化项R(W)解释为来自权重矩阵W的高斯先验,而不是MLE我们正在执行最大后验概率(MAP)估计。我们提到这些解释来帮助你有一个直觉,但这种推导的全部细节超出了本课程的范围。

实际问题:数字稳定性。 当你在实践中编写用于计算Softmax函数的代码时,由于指数运算,中间项e^{f_{y_{i}}}\Sigma_{j}e^{f_{j}}可能非常大。 除以大数字可能在数值上不稳定,因此使用规范化技巧很重要。 请注意,如果我们将分式的分子和分母都同时乘以常数C,并进一步推导,我们得到以下(数学上等效的)表达式:

我们可以自由选择C的值。这不会改变任何结果,但是我们可以使用这个值来提高计算的数值稳定性。 C的常见选择是设置logC=-max_{j}f_{j}。 这简单地说明我们应该在向量f内移动值,使得最高值为零。 在代码中这样实现:

f = np.array([123, 456, 789]) # 以3个类别的得分向量为例 ,每一个类别都有一个很大的得分
p = np.exp(f) / np.sum(np.exp(f)) # 不友好的实现,数值问题,指数爆炸

# 更好的做法,首先移动f中的值,使其最大值为0
f -= np.max(f) # f 变成 [-666, -333, 0]
p = np.exp(f) / np.sum(np.exp(f)) # 更安全的做法 得到正确答案

可能令人困惑的命名约定。 确切地说,SVM分类器使用hinge损失,或者有时也称为最大margin损失。 Softmax分类器使用交叉熵损失。 Softmax分类器的名称来自softmax函数,该函数用于将原始类别分数压缩为归一化正值并且和为1,以便可以应用交叉熵损失。 特别要注意的是,技术上谈论“softmax损失”是没有意义的,因为softmax只是压缩(归一化)功能,但它是一种相对常用的简写。

  • SVM vs. Softmax

下图可能有助于阐明Softmax和SVM分类器之间的区别:

一个训练样本的SVM和Softmax分类器之间的差异示例。 在两种情况下,我们计算相同的得分向量f(例如,通过本节中的矩阵乘法)。 不同之处在于f中得分的解释:SVM将这些解释为类别得分,其损失函数鼓励正确的类别(类别2,蓝色)得分高于其他类别得分。 Softmax分类器将分数解释为每个类的(非标准化的)对数概率,然后鼓励正确类的(标准化的)对数概率为高(相当于它的负值为低)。 上述示例,SVM分类器的最终损失为1.58,softmax分类器的最终损失为1.04(注意这里的1.04使用自然对数计算,而不是基数2或基数10),注意,这些数字不具有可比性; 它们仅对在同一分类器中相同数据计算的损失有意义。

 

Softmax分类器为每个类提供“概率”。 与计算所有类的未校准且不易解释分数的SVM不同,Softmax分类器允许我们计算所有类别标签的“概率”。 例如,给定一个图像,SVM分类器可能会为“cat”,“dog”和“ship”类提供分数[12.5,0.6,-23.0]。 softmax分类器可以将三个标签的概率计算为[0.9,0.09,0.01],这样您就可以解释它在每个类中的置信度。 然而,我们将“概率”这个词放在引号中的原因是,这些概率的高峰或扩散程度如何直接取决于正则化强度λ。 例如,假设某三个类的非标准化对数概率为[1,-2,0]。 然后softmax函数计算:

具体采取的步骤是取以e为底的指数并归一化和为1。 现在,如果正则化强度λ更高,则权重W将受到更多惩罚,这会导致更小的权重。 例如,假设权重变小了一半,那么得分也会小一半([0.5,-1,0])。 softmax现在计算:

现在概率更加分散。 此外,由于非常强的正则化强度λ使得权重朝向微小数量变化,输出概率将接近均匀。 因此,Softmax分类器计算的概率更好地被认为是置信度,类似于SVM,分数的排序是可解释的,但他们之间的差异技术上是不可解释的。

 

在实践中,SVM和Softmax通常具有可比性。 SVM和Softmax之间的性能差异通常非常小,不同的人对于哪种分类器能更好地工作会有不同的看法。与Softmax分类器相比,SVM是更局部的目标(local objective),可以将其视为错误bug或特征feature。考虑一个计算得到的分数向量[10,-2,3]且第一个类别是正确类别。 SVM(例如,Δ= 1)将看到正确的类已经具有高于其他类的分数且差距在delta之上,所以损失为0。 SVM并不关心单个分数的细节:如果它们是[10,-100,-100]或[10,9,9],则SVM将无关紧要,因为delta=1得到满足,因此损失是零。然而,这些场景并不等同于Softmax分类器,它会为分数[10,9,9]累积比[10,-100,-100]更高的损失。换句话说,Softmax分类器永远不会对它产生的分数感到满意:正确的类总是具有更高的概率,不正确的类总是具有更低的概率,并且损失总是会变得更好。然而,一旦margin得到满足,SVM就会感到高兴,并且它不会对超出此约束的精确分数进行微观管理。这可以直观地被认为是一个特征/特点:例如,汽车分类器可能将大部分“努力”用于将汽车从卡车上分离出来的困难问题,不应该受到蛙类实例的影响,因为它已经分配给蛙类非常低的得分,这是和汽车完全不同的一类。也就是说softmax是一个精益求精的分类器,没有最好只有更好;而SVM只要正确类别分数和不正确分数满足margin即可。

 

4.总结

  • 我们定义了从图像像素值到类别得分的得分函数(在本节中,使用线性函数,它取决于权重W和偏差b)。
  • 与kNN分类器不同,这种参数化方法的优点是,一旦我们学习好了参数,我们就可以丢弃训练数据。 另外,对新测试图像的预测是快速的,因为它只需要与W进行单个矩阵乘法,而不是与每个训练示例的详尽比较。
  • 我们引入了偏置技巧,它允许我们将偏置矢量添加到权重矩阵中,以方便仅跟踪一个参数矩阵。
  • 我们定义了一个损失函数(我们为线性分类器引入了两个常用的损失:SVM和Softmax),它们衡量一组给定参数与训练数据集中的真实类别标签的兼容性。 我们还发现损失函数的定义方式是对训练数据做出良好的预测此时损失会很小。

我们现在看到了一种方法来获取图像数据集,并根据一组参数将每个图像映射到类别得分,我们看到了两个可用于衡量预测质量的损失函数示例。 但是,我们如何有效地确定产生最佳(最低)损失的参数? 这个过程是优化,它是下一节的主题。

注意本节损失函数的定义可能和之前学习的有所不同,但是原理是一样的。之前在进行多分类(>2)时,我们把训练样本的标签y_{i}表示为one-hot形式,比如进行3分类,类别标签索引为2,表示为one-hot为[0,0,1];而在本节中我们并没有把y_{i}表示为one-hot,而是直接使用的类别标签对应的索引。所以损失函数的定义有所不同。

5.拓展阅读

 

 

 

 

 

 

猜你喜欢

转载自blog.csdn.net/sdu_hao/article/details/86571587
今日推荐