Я пытаюсь реализовать базовый градиентный спуск, и я тестирую его с функцией потери шарнира, т.е. . Тем не менее, я запутался в градиенте потери шарнира. У меня сложилось впечатление, что это
Но разве это не возвращает матрицу того же размера, что и ? Я думал, что мы хотим вернуть вектор длины ? Очевидно, я где-то запутался. Может ли кто-то указать правильное направление здесь?
Я включил некоторый основной код на случай, если мое описание задачи было неясным
#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"
...
источник
Ответы:
Чтобы получить градиент, мы дифференцируем потери по й составляющей .жя вес
Перепишите потерю шарнира в терминах как где иf ( g ( w ) ) f ( z ) = max ( 0 , 1 - y z ) g ( w ) = x ⋅ wвес е( г( ш ) ) е( з) = max ( 0 , 1 - у Z) г( w ) = x ⋅ w
Используя правило цепи мы получаем
Первый производный член оценивается при становящемся когда , и 0, когда . Второй производный член становится . Таким образом, в конце вы получаете - у й ⋅ ш < 1 х ⋅ ш > 1 х я ∂ F ( г ( ж ) )г( w ) = x ⋅ w - у x⋅w<1 x⋅w>1 xi
Так как охватывает компоненты , вы можете просмотреть вышеупомянутое как векторную величину и написать качестве сокращения длях ∂i x (∂∂∂w (∂∂w1,∂∂w2,…)
источник
Это на 3 года позже, но все еще может быть актуально для кого-то ...
Обозначим через выборку точек и множество соответствующих меток . Мы ищем, чтобы найти гиперплоскость , которая минимизировала бы общую потерю шарнира: Чтобы найти взять производную от общей потери шарнира. Градиент каждого компонента:S xi∈Rd yi∈{−1,1} w w ∗ ∂ l h i n g e
Градиент суммы является суммой градиентов. Пример Python, который использует GD для поиска следует оптимальная гиперплоскость с потерей шарнира (вероятно, это не самый эффективный код, но он работает)
источник
Я исправил твой код. Основная проблема - это ваше определение функций hinge и d_hinge. Они должны применяться один образец за один раз. Вместо этого ваше определение объединяет все выборки, прежде чем брать максимум.
Мне нужно n = 10000, чтобы сходиться.
[1] "потери: 0,090000, xw: 1,08999999999995,0,909999999999905, -1,190000000008, -1,69000000000011" [1] "потери: 0,100000, xw: 1,33999999999995,1,1199999999999, -0,900000000000075, -1,400000000, -1,400000000, -1,400000000, -1,400000000, -1,4000000, 10000000000, -1,400000000, 10000000000, 10000000000, 10000000000 0,939999999999948,0,829999999999905, -1,32000000000007, -1,77000000000011 [1] "потеря: 0,240000, XW: 1.49999999999995,1.2099999999999, -0,760000000000075, -1,33000000000011" [1] "потеря: 0,080000, XW: 1.09999999999995,0.919999999999905, -1,18000000000007, -1,68000000000011" [1] «потеря: 0,110000, XW: 1.34999999999995,1.1299999999999, -0,890000000000075, -1,41000000000011"[1] "потери: 0,210000, xw: 0,949999999999948,0,839999999999905, -1,31000000000007, -1,76000000000011" [1] "потери: 0,380000, xw: 1,65999999999995,1,2999999999999, -0,62000000000074: 0,0000: 1: 100: 100000000000000000000000000000000000000000000000000000000000000000 1,25999999999995,1,0099999999999, -1,04000000000008, -1,59000000000011 "[1]" Потеря: 0,000000, xw: 1,25999999999995,1,0099999999999, -1,04000000000008, -1,59000000000011 "
источник