矢量化SVM梯度

Nik*_*rma 6 python numpy svm

我正在浏览SVM损失和衍生的代码,我确实理解了损失,但我无法理解如何以矢量化方式计算梯度

def svm_loss_vectorized(W, X, y, reg):

loss = 0.0
dW = np.zeros(W.shape) # initialize the gradient as zero
num_train = X.shape[0]

scores = X.dot(W)
yi_scores = scores[np.arange(scores.shape[0]),y] 
margins = np.maximum(0, scores - np.matrix(yi_scores).T + 1)
margins[np.arange(num_train),y] = 0
loss = np.mean(np.sum(margins, axis=1))
loss += 0.5 * reg * np.sum(W * W)
Run Code Online (Sandbox Code Playgroud)

到目前为止理解了,在这之后我无法理解为什么我们在二进制矩阵中逐行求和并用它的总和减去

binary = margins
binary[margins > 0] = 1
row_sum = np.sum(binary, axis=1)
binary[np.arange(num_train), y] = -row_sum.T
dW = np.dot(X.T, binary)

# Average
dW /= num_train

# Regularize
dW += reg*W

return loss, dW
Run Code Online (Sandbox Code Playgroud)

Pau*_*zer 5

让我们首先回顾一下场景和损失函数,这样我们就达成了共识:

给定 维空间中以矩阵 形式存在的样本P点,因此这些点就是该矩阵的行。中的每个点都分配给一个类别。它们以长度向量的形式给出,其整数值介于 0 和 之间。NPxNXXMYPM-1

目标是通过以形状 的M权重矩阵形式给出的线性分类器(每个类别一个)来预测所有点的类别,因此分类器是 的列。为了预测所有样本的类别,形成所有点和所有权重向量之间的标量积。这与矩阵相乘并产生一个分数矩阵相同,该矩阵的行按照 的 h 个元素进行排序,每一行对应一个样本。每个样本的预测类别就是得分最大的类别。WNxMWXXWY0Y

没有偏差项,所以我认为存在某种对称性或零均值假设。

现在,为了找到一组好的权重,我们需要一个损失函数,对于好的预测来说较小,对于不好的预测来说较大,这样我们就可以进行梯度下降。最直接的方法之一是对每个样本的i每个大于该样本正确类别得分的分数进行惩罚,并让惩罚随着差异线性增长。因此,如果我们为 得分高于正确类别的A[i]一组类别编写,则样本的损失可以写为jY0[i, j] > Y0[i, Y[i]]i

sum_{j in A[i]} (Y0[i, j] - Y0[i, Y[i]])

或者等效地,如果我们写出#A[i]元素的数量A[i]

(sum_{j in A[i]} Y0[i, j]) - #A[i] Y0[i, Y[i]]

因此,关于分数的偏导数很简单

                    | -#A[i]      if j == Y[i]
dloss / dY0[i, j] = {      1      if j in A[i]
                    |      0      else
Run Code Online (Sandbox Code Playgroud)

这正是您所说的您不理解的前四行的计算内容。

下一行应用链式法则dloss/dW = dloss/dY0 dY0/dW

仍然需要除以样本数以获得每个样本的损失,并添加调节项的导数,其中调节项只是一个分量二次函数很容易。