การไล่ระดับสีของการสูญเสียบานพับ


25

ฉันกำลังพยายามใช้การไล่ระดับสีพื้นฐานและฉันทดสอบด้วยฟังก์ชันการสูญเสียบานพับเช่นlhinge=max(0,1y xw)}) อย่างไรก็ตามฉันสับสนเกี่ยวกับการไล่ระดับสีของการสูญเสียบานพับ ฉันอยู่ภายใต้ความประทับใจที่มันเป็น

wlhinge={y xif y xw<10if y xw1

แต่นี่จะไม่ส่งกลับเมทริกซ์ที่มีขนาดเท่ากับxหรือไม่ ฉันคิดว่าเราต้องการคืนเวกเตอร์ที่มีความยาว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
ฟังก์ชั่นของคุณไม่แตกต่างกันทุกที่
robin girard

2
ในฐานะโรบินโน้ตการสูญเสียบานพับไม่สามารถหาอนุพันธ์ได้ที่ x = 1 นี่หมายความว่าคุณต้องใช้อัลกอริธึมการไล่ระดับย่อย
Alex Kreimer

คำตอบ:


27

ที่จะได้รับการไล่ระดับสีที่เราแยกความแตกต่างการสูญเสียที่เกี่ยวกับส่วนประกอบของ TH WWiw

เขียนซ้ำการสูญเสียบานพับในแง่ของเป็นโดยที่และf ( g ( w ) ) f ( z ) = สูงสุด( 0 , 1 - y z ) g ( w ) = xwwf(g(w))f(z)=max(0,1y z)g(w)=xw

ใช้กฎลูกโซ่ที่เราได้รับ

wif(g(w))=fzgwi

ระยะแรกอนุพันธ์ที่ได้รับการประเมินกลายเป็นเมื่อและ 0 เมื่อ 1 ระยะที่สองกลายเป็นอนุพันธ์x_iดังนั้นในที่สุดคุณจะได้รับ g(w)=xwyxw<1xw>1xi

f(g(w))wi={y xiif y xw<10if y xw>1

เนื่องจากอยู่เหนือส่วนประกอบของคุณสามารถดูข้างบนเป็นปริมาณเวคเตอร์และเขียนเป็นแบบย่อสำหรับixw(w1,w2,)


ขอบคุณ! นั่นเป็นการล้างสิ่งต่าง ๆ สำหรับฉัน ตอนนี้ฉันแค่ต้องทำให้ถูกต้องในสภาพแวดล้อมที่ใช้ได้จริง คุณคงไม่ทราบว่าทำไมโค้ดด้านบนใช้งานไม่ได้ ดูเหมือนว่าจะมาบรรจบกันใน 4 รอบโดยมีการสูญเสียเริ่มต้นที่ 1 และลดลง 0.25 ในแต่ละครั้งและมาบรรจบกันที่ 0 อย่างไรก็ตามน้ำหนักที่เกิดขึ้นมันค่อนข้างผิด
brcs

1
คุณสามารถตรวจสอบสิ่งที่คาดการณ์ให้กับข้อมูลการฝึกอบรมของคุณ หากการสูญเสียลดลงเป็นศูนย์ทุกกรณีควรได้รับการจำแนกอย่างสมบูรณ์
Yaroslav Bulatov

นี่เป็นกรณีสำหรับการจำแนกไบนารี คุณช่วยอธิบายความชันของการจำแนกประเภทหลายคลาสโดยใช้การสูญเสียบานพับได้ไหม
Shyamkkhadka

12

นี่คือ 3 ปีที่ผ่านมา แต่ก็อาจจะเกี่ยวข้องกับใครบางคน ...

Let แสดงตัวอย่างของจุดx ฉันR dและชุดของฉลากที่สอดคล้องกันY ฉัน{ - 1 , 1 } เราค้นหาเพื่อหาไฮเปอร์เพลWที่จะลดรวมบานพับขาดทุน W * = argmin  W L ชั่วโมงฉันn กรัมอีเอส ( W ) = argmin  W Σฉันลิตรต่อชั่วโมงฉันn กรัมE ( W ,SxiRdyi{1,1}w เพื่อหา w หาอนุพันธ์ของการสูญเสียบานพับทั้งหมด ความชันของแต่ละองค์ประกอบคือ: l h i n g e

w=argmin wLShinge(w)=argmin wilhinge(w,xi,yi)=argmin wimax{0,1yiwx}
w
lhingew={0yiwx1yixyiwx<1

LShingew=ilhingew
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()

ฉันเป็นกรณีนี้สำหรับการจำแนกไบนารี คุณช่วยอธิบายความชันของการจำแนกประเภทหลายคลาสโดยใช้การสูญเสียบานพับได้ไหม
Shyamkkhadka

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 = 10,000 เพื่อมาบรรจบกัน

[1] "การสูญเสีย: 0.090000, xw: 1.0899999999999995,0.90999999999999905, -1.190000000000000000, -1.69000000000011" [1] "การสูญเสีย: 0.100000, xw: 1.3399999999999999,999,991,991,991,199 0.9399999999999999,0.82999999999999905, -1.32000000000000007, -1.77000000000011 "[1]" การสูญเสีย: 0.3700009999999999999999999999999999999999999999999999999999999999999999999999999999999999991991991991991991991991991991991991991991991991991991991991991991991991991991991 การสูญเสียน้ำหนัก: 0.991,099,099,099,099,499,099,966,499,499,499,499,499,499,499,499,499,499,499,099,099,910,499,199,199,199,199,199,199,199,0] [1] "การสูญเสีย: 0.240000, xw: 1.49999999999995,1.2099999999999, -0.7600000000007575, -1.33000000000011" [1] "การสูญเสีย: 0.080000, xw: 1.0999999999999,999999995, -1.18000000000007, -1.61800000000," 11: 1, "0.9900000000" 1.34999999999995,1.1299999999999, -.890000000000075, -1.41000000000011"[1] "การสูญเสีย: 0.210000, xw: 0.9499999999999999,0.83999999999999905, -1.31000000000000000", 1: 1, 1, การสูญเสีย: 0.380000, xw: 1.659999999999999999999999999999999999999999999999999990901, 1, 1, 000, 0000000000000 1.25999999999995,1.0099999999999, -1.04000000000008, -1.59000000000011 "[1]" การสูญเสีย: 0.000000, xw: 1.25999999999999,1.0099999999999, -1.04000000000008, -1.09000000000011 "


3
ผู้คน, การไล่ระดับสีเป็นเรื่องเกี่ยวกับอัลกอริธึมการเพิ่มประสิทธิภาพที่แย่ที่สุดและควรใช้เมื่อไม่มีทางเลือกเท่านั้น ภูมิภาคที่เชื่อถือได้หรือการค้นหาบรรทัดอัลกอริธึม Quasi-Newton ที่ใช้ค่าฟังก์ชันวัตถุประสงค์และการไล่ระดับสีจะทำให้การไล่ระดับสีลงมาจากน้ำและมาบรรจบกันได้อย่างน่าเชื่อถือมากขึ้น และอย่าเขียนแก้ปัญหาของคุณเองจนกว่าคุณจะรู้ว่าคุณกำลังทำอะไรอยู่
Mark L. Stone

2
ฉันจะเห็นด้วยกับทั้งสองงบ อย่างไรก็ตามการไล่ระดับสีที่มีรสชาติต่าง ๆ นั้นง่ายกว่าที่จะนำไปใช้ในสภาพแวดล้อมแบบกระจายอย่างน้อยก็ตามห้องสมุดโอเพ่นซอร์สที่มีอยู่
John Jiang
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.