如何矢量化铰链损耗梯度计算

时间:2016-10-12 15:27:14

标签: python optimization machine-learning

我正在计算数千个渐变,并希望在Python中对计算进行矢量化。上下文是SVM,损失函数是铰链损失。 Y是Mx1,X是MxN,w是Nx1。

 L(w) = lam/2 * ||w||^2 + 1/m Sum i=1:m ( max(0, 1-y[i]X[i]w) )

这个梯度是

grad = lam*w + 1/m Sum i=1:m {-y[i]X[i].T if y[i]*X[i]*w < 1, else 0}

不是循环求和的每个元素并评估max函数,是否可以对此进行向量化?我想使用像np.where这样的东西,如下面的

grad = np.where(y*X.dot(w) < 1, -X.T.dot(y), 0)

这不起作用,因为条件为真,-X.T * y是错误的维度。

编辑:列表理解版本,想知道是否有更清洁或更优化的方式

def grad(X,y,w,lam):
    # cache y[i]*X[i].dot(w), each row of Xw is multiplied by a single element of y
    yXw = y*X.dot(w)
    # cache y[i]*X[i], note each row of X is multiplied by a single element of y
    yX = X*y[:,np.newaxis]
    # return the average of this max function
    return lam*w + np.mean( [-yX[i] if yXw[i] < 1 else 0 for i in range(len(y))] )

1 个答案:

答案 0 :(得分:2)

你有两个向量A和B,并且你想要返回数组C,这样如果B [i] <1,则C [i] = A [i]。 1和0其他,所以你需要做的就是

C := A * sign(max(0, 1-B)) # suprisingly similar to the original hinge loss, right?:)

因为

  • 如果B < 1然后1-B> 0,因此max(0,1-B)> 0 0和符号(max(0,1-B))== 1
  • 如果B> = 1则1-B <= 0,因此max(0,1-B)= 0且符号(max(0,1-B))== 0

因此,在您的代码中,它将类似于

A = (y*X.dot(w)).ravel()
B = (X*y[:,np.newaxis]).ravel()
C = A * np.sign(np.maximum(0, 1-B))