SVM 的损失函数的梯度

Posted

技术标签:

【中文标题】SVM 的损失函数的梯度【英文标题】:Gradient of a Loss Function for an SVM 【发布时间】:2016-11-29 14:12:22 【问题描述】:

我正在学习this 卷积神经网络课程。我一直在尝试为 svm 实现损失函数的梯度,并且(我有解决方案的副本)我无法理解为什么解决方案是正确的。

在this 页面上,它定义了损失函数的梯度如下: 在我的代码中,当在代码中实现时,我的分析梯度与数字匹配如下:

 dW = np.zeros(W.shape) # initialize the gradient as zero

  # compute the loss and the gradient
  num_classes = W.shape[1]
  num_train = X.shape[0]
  loss = 0.0
  for i in xrange(num_train):
    scores = X[i].dot(W)
    correct_class_score = scores[y[i]]
    for j in xrange(num_classes):
      if j == y[i]:
        if margin > 0:
            continue
      margin = scores[j] - correct_class_score + 1 # note delta = 1
      if margin > 0:
        dW[:, y[i]] += -X[i]
        dW[:, j] += X[i] # gradient update for incorrect rows
        loss += margin

但是,从注释看来,dW[:, y[i]] 应该在每次 j == y[i] 时更改,因为我们会在每次 j == y[i] 时减去损失。我很困惑为什么代码不是:

  dW = np.zeros(W.shape) # initialize the gradient as zero

  # compute the loss and the gradient
  num_classes = W.shape[1]
  num_train = X.shape[0]
  loss = 0.0
  for i in xrange(num_train):
    scores = X[i].dot(W)
    correct_class_score = scores[y[i]]
    for j in xrange(num_classes):
      if j == y[i]:
        if margin > 0:
            dW[:, y[i]] += -X[i]
            continue
      margin = scores[j] - correct_class_score + 1 # note delta = 1
      if margin > 0:
        dW[:, j] += X[i] # gradient update for incorrect rows
        loss += margin

j == y[i] 时,损失会发生变化。为什么J != y[i] 时它们都被计算?

【问题讨论】:

" 从注释中得知,dW[:, y[i]] 应该在每次 j == y[i] 时更改,因为我们会在 j == y[i] 时减去损失。 " 求和符号对 j 求和不等于 y[i] 吗? 现在看来,确实是这样。让我失望的是,当它写成“对于 j !=yi 的其他行,渐变是......”。听起来第一个是在 j==yi 的情况下。这里的正确含义是什么?另外(可能相关),为什么第一个函数有总和,而第二个函数没有? 这里有关于不同变量的梯度。第一个是关于 j == y_i(注意左边是 grad_y_i),其表达式涉及所有不等于 y_i 的 j 的总和;第二个是关于每个不等于 y_i 的 j。 啊,现在我明白了。为什么第一个只有一个总和,而第二个没有?在代码中,它们使用相同的比较运行相同的次数... 没有查看您的 L_i、w_i 的定义,也没有查看您的上下文,所以我不确定。但是不,代码很好。您正在对 j 进行内部循环,并且 1. 对于每个不等于 y[i] 的 j,您添加到 dW[: y[i]] 2. 您添加到 dW[: j]每个 j 不等于 y[i]。在第 2 步中,您为每个 j 添加到数组中的不同索引,所以不,那里没有求和。 【参考方案1】:

我没有足够的声誉来发表评论,所以我在这里回答。每当您为x[i]ith 训练示例计算损失向量并获得一些非零损失时,这意味着您应该将不正确类(j != y[i]) 的权重向量移开x[i],同时移动x[i] 附近正确类 (j==y[i]) 的权重或超平面。根据平行四边形定律,w + x 位于wx 之间。所以这种方式w[y[i]] 每次找到loss>0 时都会尝试更接近x[i]

因此,dW[:,y[i]] += -X[i]dW[:,j] += X[i] 是在循环中完成的,但是在更新时,我们将按照梯度递减的方向进行,所以我们本质上是添加 X[i] 以纠正类权重并消失 X[i]来自未分类的权重。

【讨论】:

以上是关于SVM 的损失函数的梯度的主要内容,如果未能解决你的问题,请参考以下文章

2多类SVM

SVM算法的另外一种理解

SVM、Softmax 损失函数

Keras 中的自定义损失函数(IoU 损失函数)和梯度误差?

多分类SVM损失函数: Multiclass SVM loss

机器学习P6 逻辑回归的 损失函数 以及 梯度下降