हिंग की हानि का क्रम


25

मैं मूल ढाल वंश को लागू करने की कोशिश कर रहा हूं और मैं इसे एक काज हानि समारोह के साथ परीक्षण कर रहा हूं अर्थात एलकाज=अधिकतम(0,1-y एक्सw) । हालांकि, मैं काज हानि के ढाल के बारे में उलझन में हूँ। मैं इस धारणा के तहत हूं कि यह है

wएलकाज={-y एक्सअगर y एक्सw<10अगर y एक्सw1

लेकिन क्या यह एक मैट्रिक्स को \ boldsymbol {x} के समान आकार में नहीं लौटाता हैएक्स ? मुझे लगा कि हम लंबाई \ boldsymbol {w} के एक वेक्टर को वापस करना wचाहते हैं? जाहिर है, मुझे कहीं न कहीं कुछ गड़बड़ लगी है। क्या कोई यहां सही दिशा में इशारा कर सकता है?

मैंने कुछ मूल कोड शामिल किए हैं, जब कार्य का मेरा विवरण स्पष्ट नहीं था

#Run standard gradient descent
gradient_descent<-function(fw, dfw, n, lr=0.01)
{
    #Date to be used
    x<-t(matrix(c(1,3,6,1,4,2,1,5,4,1,6,1), nrow=3))
    y<-c(1,1,-1,-1)
    w<-matrix(0, nrow=ncol(x))

    print(sprintf("loss: %f,x.w: %s",sum(fw(w,x,y)),paste(x%*%w, collapse=',')))
    #update the weights 'n' times
    for (i in 1:n)
    {
      w<-w-lr*dfw(w,x,y)
      print(sprintf("loss: %f,x.w: %s",sum(fw(w,x,y)),paste(x%*%w,collapse=',')))
    }
}
#Hinge loss
hinge<-function(w,x,y) max(1-y%*%x%*%w, 0)
d_hinge<-function(w,x,y){ dw<-t(-y%*%x); dw[y%*%x%*%w>=1]<-0; dw}
gradient_descent(hinge, d_hinge, 100, lr=0.01)

अद्यतन: जबकि नीचे दिए गए उत्तर ने समस्या के बारे में मेरी समझ में मदद की, इस एल्गोरिदम का आउटपुट अभी भी दिए गए डेटा के लिए गलत है। प्रत्येक बार हानि फ़ंक्शन 0.25 से कम हो जाता है, लेकिन बहुत तेज़ी से परिवर्तित हो जाता है और परिणामस्वरूप भार एक अच्छा वर्गीकरण नहीं होता है। वर्तमान में आउटपुट जैसा दिखता है

#y=1,1,-1,-1
"loss: 1.000000, x.w: 0,0,0,0"
"loss: 0.750000, x.w: 0.06,-0.1,-0.08,-0.21"
"loss: 0.500000, x.w: 0.12,-0.2,-0.16,-0.42"
"loss: 0.250000, x.w: 0.18,-0.3,-0.24,-0.63"
"loss: 0.000000, x.w: 0.24,-0.4,-0.32,-0.84"
"loss: 0.000000, x.w: 0.24,-0.4,-0.32,-0.84"
"loss: 0.000000, x.w: 0.24,-0.4,-0.32,-0.84"
...  

ग्रेडिएंट एक वेक्टर है क्योंकि आपके नुकसान फ़ंक्शन में वास्तविक मूल्य हैं।
वोक नोव

3
आपका फ़ंक्शन हर जगह भिन्न नहीं है।
रॉबिन जिरार्ड 11:17

2
जैसा कि रॉबिन नोट्स काज हानि x = 1 पर भिन्न नहीं है। इसका सिर्फ यह अर्थ है कि आपको उप-ग्रेडिएंट
डिसेंट

जवाबों:


27

ग्रेडिएंट पाने के लिए हम वें घटक के संबंध में नुकसान को अलग करते हैं ।wमैंw

रूप में संदर्भ में हानि को कम करें जहाँ औरf ( g ( w ) ) f ( z ) = अधिकतम ( 0 , 1 - y z )w(जी(w))(z)=अधिकतम(0,1-y z)जी(w)=एक्सw

चेन नियम का उपयोग करके हम प्राप्त करते हैं

wमैं(जी(w))=zजीwमैं

सबसे पहले व्युत्पन्न अवधि पर मूल्यांकन किया जाता है बनने जब , और 0 जब । दूसरा व्युत्पन्न शब्द हो जाता है । इसलिए अंत में आपको - y एक्सw < 1जी(w)=एक्सw-yएक्सw<1एक्स मैं ( जी ( डब्ल्यू ) )एक्सw>1एक्समैं

(जी(w))wमैं={-y एक्समैंअगर y एक्सw<10अगर y एक्सw>1

चूँकि के घटकों के ऊपर है, आप उपरोक्त को एक वेक्टर मात्रा के रूप में देख सकते हैं, और को शॉर्टहैंड के रूप मेंमैंएक्सw(w1,w2,...)


धन्यवाद! यह मेरे लिए चीजें साफ करता है। अब मुझे सिर्फ एक व्यावहारिक सेटिंग में इसे प्राप्त करना है। आपके पास कोई विचार नहीं होगा कि उपरोक्त कोड क्यों काम नहीं करता है? यह 4 पुनरावृत्तियों में 1 में शुरू होने वाले नुकसान के साथ और प्रत्येक बार 0.25 नीचे जाने और 0. पर परिवर्तित करने में परिवर्तित होता प्रतीत होता है। हालांकि, यह जो उत्पादन होता है वह काफी गलत लगता है।
11

1
आप जाँच सकते हैं कि यह आपके प्रशिक्षण डेटा को क्या भविष्यवाणियाँ देता है। यदि नुकसान शून्य से नीचे चला जाता है, तो सभी उदाहरणों को पूरी तरह से वर्गीकृत किया जाना चाहिए
यारोस्लाव बुलटोव

यह बाइनरी वर्गीकरण के लिए मामला है। क्या आप काज हानि का उपयोग करते हुए मल्टी क्लास वर्गीकरण के ग्रेडिएंट के लिए व्युत्पत्ति दे सकते हैं?
श्यामखड़का

12

यह 3 साल देर से है, लेकिन अभी भी किसी के लिए प्रासंगिक हो सकता है ...

बता दें कि पॉइंट का नमूना दिया है और इसी लेबल के । हम एक हाइपरप्लेन को खोजने के लिए खोज करते हैं जो कुल काज-नुकसान को कम करेगा: खोजने के लिए कुल काज हानि का व्युत्पन्न। प्रत्येक घटक का ग्रेडिएंट है: एसएक्समैंआरyमैं{-1,1}wडब्ल्यू * एल एच मैं एन जी

w*=argmin wएलएसमैंnजी(w)=argmin wΣमैंएलमैंnजी(w,एक्समैं,yमैं)=argmin wΣमैंअधिकतम{0,1-yमैंwएक्स}
w*
एलमैंnजीw={0yमैंwएक्स1-yमैंएक्सyमैंwएक्स<1

योग का ग्रेडिएंट ग्रेडिएंट का योग है। पायथन उदाहरण, जो खोजने के लिए जीडी का उपयोग करता है। काज-नुकसान इष्टतम सेपरैटिंज हाइपरप्लेन इस प्रकार है (यह शायद सबसे कुशल कोड नहीं है, लेकिन यह काम करता है)

एलएसमैंnजीw=Σमैंएलमैंnजीw
import numpy as np
import matplotlib.pyplot as plt

def hinge_loss(w,x,y):
    """ evaluates hinge loss and its gradient at w

    rows of x are data points
    y is a vector of labels
    """
    loss,grad = 0,0
    for (x_,y_) in zip(x,y):
        v = y_*np.dot(w,x_)
        loss += max(0,1-v)
        grad += 0 if v > 1 else -y_*x_
    return (loss,grad)

def grad_descent(x,y,w,step,thresh=0.001):
    grad = np.inf
    ws = np.zeros((2,0))
    ws = np.hstack((ws,w.reshape(2,1)))
    step_num = 1
    delta = np.inf
    loss0 = np.inf
    while np.abs(delta)>thresh:
        loss,grad = hinge_loss(w,x,y)
        delta = loss0-loss
        loss0 = loss
        grad_dir = grad/np.linalg.norm(grad)
        w = w-step*grad_dir/step_num
        ws = np.hstack((ws,w.reshape((2,1))))
        step_num += 1
    return np.sum(ws,1)/np.size(ws,1)

def test1():
    # sample data points
    x1 = np.array((0,1,3,4,1))
    x2 = np.array((1,2,0,1,1))
    x  = np.vstack((x1,x2)).T
    # sample labels
    y = np.array((1,1,-1,-1,-1))
    w = grad_descent(x,y,np.array((0,0)),0.1)
    loss, grad = hinge_loss(w,x,y)
    plot_test(x,y,w)

def plot_test(x,y,w):
    plt.figure()
    x1, x2 = x[:,0], x[:,1]
    x1_min, x1_max = np.min(x1)*.7, np.max(x1)*1.3
    x2_min, x2_max = np.min(x2)*.7, np.max(x2)*1.3
    gridpoints = 2000
    x1s = np.linspace(x1_min, x1_max, gridpoints)
    x2s = np.linspace(x2_min, x2_max, gridpoints)
    gridx1, gridx2 = np.meshgrid(x1s,x2s)
    grid_pts = np.c_[gridx1.ravel(), gridx2.ravel()]
    predictions = np.array([np.sign(np.dot(w,x_)) for x_ in grid_pts]).reshape((gridpoints,gridpoints))
    plt.contourf(gridx1, gridx2, predictions, cmap=plt.cm.Paired)
    plt.scatter(x[:, 0], x[:, 1], c=y, cmap=plt.cm.Paired)
    plt.title('total hinge loss: %g' % hinge_loss(w,x,y)[0])
    plt.show()

if __name__ == '__main__':
    np.set_printoptions(precision=3)
    test1()

I यह बाइनरी वर्गीकरण के लिए मामला है। क्या आप काज हानि का उपयोग करते हुए मल्टी क्लास वर्गीकरण के ग्रेडिएंट के लिए व्युत्पत्ति दे सकते हैं?
श्यामखड़का

1

मैंने आपका कोड तय कर दिया। मुख्य समस्या काज और d_hinge कार्यों की आपकी परिभाषा है। इन्हें एक समय में एक नमूना लागू किया जाना चाहिए। इसके बजाय आपकी परिभाषा अधिकतम लेने से पहले सभी नमूनों को एकत्र करती है।

#Run standard gradient descent
gradient_descent<-function(fw, dfw, n, lr=0.01)
{
    #Date to be used
    x<-t(matrix(c(1,3,6,1,4,2,1,5,4,1,6,1), nrow=3))
    y<-t(t(c(1,1,-1,-1)))
    w<-matrix(0, nrow=ncol(x))


    print(sprintf("loss: %f,x.w: %s",sum(mapply(function(xr,yr) fw(w,xr,yr), split(x,row(x)),split(y,row(y)))),paste(x%*%w, collapse=',')))
    #update the weights 'n' times
    for (i in 1:n)
    {
      w<-w-lr*dfw(w,x,y)
      print(sprintf("loss: %f,x.w: %s",sum(mapply(function(xr,yr) fw(w,xr,yr), split(x,row(x)),split(y,row(y)))),paste(x%*%w,collapse=',')))
    }
}

#Hinge loss
hinge<-function(w,xr,yr) max(1-yr*xr%*%w, 0)
d_hinge<-function(w,x,y){ dw<- apply(mapply(function(xr,yr) -yr * xr * (yr * xr %*% w < 1),split(x,row(x)),split(y,row(y))),1,sum); dw}
gradient_descent(hinge, d_hinge, 100, lr=0.01)

मुझे अभिसरण करने के लिए n = 10000 की आवश्यकता है।

] 0.939999999999948,0.829999999999905, -1.32000000000007, -1.7700000000001111 "[1]" नुकसान: 0.370000, xw: 1.64999999999595..2899999999999, -0.63000000000075, -1.25000000000011, "1: 00:33": "1": "1:": "# 1:" #: "#:": "#:": "#:"। [1] "नुकसान: .२,४०,०००, xw: 1.49999999999995,1.2099999999999, -.760000000000075, -1.33000000000011" [1] "नुकसान: .०,८०,०००, xw: 1.09999999999995,0.919999999999905, -1.18000000000007, -1.68000000000011" [1] "नुकसान: .१,१०,०००, xw: 1.34999999999995,1.1299999999999, -.890000000000075, -1.41000000000011 "[१] "हानि: 0.210000, xw: 0.949999999999948,0.839999999999905, -1.31000000000007, -1.76000000000011" "[1]" नुकसान: 0.380000, xw: 1.659999999995,1.2999999999999, -0.620000000000074, 1-420000000000074, 1-40000000074, 1 1.25999999999995,1.0099999999999, -1.04000000000008, -1.59000000000011 "[1]" नुकसान: 0.000000, xw: 1.259999999995,1.0099999999999, -1.04000000000008, -1.59000000000011 "


3
लोगों, ग्रेडिएंट डीसेंट बस वर्स्ट ऑप्टिमाइज़ेशन एल्गोरिदम के बारे में है, और इसका उपयोग केवल तभी किया जाना चाहिए जब कोई विकल्प न हो। एक ट्रस्ट रीजन या लाइन सर्च क्वैसी-न्यूटन एल्गोरिदम, ऑब्जेक्टिव फंक्शन वैल्यू और ग्रेडिएंट का उपयोग करते हुए, पानी से धीरे-धीरे वंश को उड़ा देगा, और बहुत अधिक मज़बूती से अभिसरण करेगा। और अपने स्वयं के सॉल्वर को तब तक न लिखें जब तक आपको पता न हो कि आप क्या कर रहे हैं, जो बहुत कम लोग करते हैं।
मार्क एल। स्टोन

2
मैं दोनों बयानों से सहमत हूं। हालांकि, विभिन्न स्वादों के साथ ढाल वंश एक वितरित वातावरण में लागू करने के लिए बहुत आसान है, कम से कम उपलब्ध ओपन सोर्स पुस्तकालयों के अनुसार।
जॉन जियांग
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.