2016-10-12 10 views
1

Ich berechne Tausende von Verläufen und möchte die Berechnungen in Python vektorisieren. Der Kontext ist SVM und die Verlustfunktion ist Scharnierverlust. Y ist Mx1, X ist MxN und w ist Nx1.Wie vektorisieren Scharnier Verlustgradientenberechnung

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

Der Gradient dieser ist

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

stattdessen durch jedes Element der Summe der Looping und Auswertung der MAX-Funktion ist es möglich, dies zu vektorisieren? Ich möchte wie die

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

folgend etwas wie np.where verwenden Das funktioniert nicht, weil, wenn die Bedingung erfüllt ist, -X.T * y die falsche Dimension ist.

bearbeiten: Liste Verständnis Version, möchte wissen, ob es ein sauberes ist oder mehr optimal

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))]) 

Antwort

2

Sie zwei Vektoren A und B haben, und Sie wollen Array C zurückkehren, so dass C [i ] = A [i], wenn B [i] < 1 und 0 sonst, damit alles, was Sie tun müssen, ist

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

seit

  • wenn B < 1 dann 1-B> 0, also max (0, 1-B)> 0 und Vorzeichen (max (0, 1-B)) == 1
  • wenn B> = 1 dann 1-B < = 0, also max (0, 1-B) = 0 und Zeichen (max (0, 1-B)) == 0

so in Ihrem Code wird es so etwas wie

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