Estou tentando implementar a descida básica do gradiente e estou testando-a com uma função de perda de dobradiça, ou seja, . No entanto, estou confuso sobre o gradiente da perda de dobradiça. Estou com a impressão de que é
Mas isso não retorna uma matriz do mesmo tamanho que ? Eu pensei que estávamos procurando retornar um vetor de comprimento ? Claramente, tenho algo confuso em algum lugar. Alguém pode apontar na direção certa aqui?
Incluí algum código básico, caso minha descrição da tarefa não esteja clara
#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)
Atualização: embora a resposta abaixo tenha me ajudado a entender o problema, a saída desse algoritmo ainda está incorreta para os dados fornecidos. A função de perda é reduzida em 0,25 a cada vez, mas converge muito rápido e os pesos resultantes não resultam em uma boa classificação. Atualmente, a saída parece
#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"
...
fonte
Respostas:
Para obter o gradiente, diferenciamos a perda em relação ao componente de .wi w
Reescreva a perda de dobradiça em termos de como que ef ( g ( w ) ) f ( z ) = max ( 0 , 1 - y z ) g ( w ) = x ⋅ ww f(g(w)) f(z)=max(0,1−y z) g(w)=x⋅w
Usando a regra da cadeia, obtemos
O primeiro termo derivado é avaliado em se tornando quando e 0 quando . O segundo termo derivado torna-se . Portanto, no final, você obtémg(w)=x⋅w −y x⋅w<1 x⋅w>1 xi
Como varia sobre os componentes de , você pode ver o acima como uma quantidade vetorial e escrever como abreviação dei x ∂∂w (∂∂w1,∂∂w2,…)
fonte
Está atrasado 3 anos, mas ainda pode ser relevante para alguém ...
Deixe denotar uma amostra dos pontos x i ∈ R d e o conjunto de etiquetas correspondentes y i ∈ { - 1 , 1 } . Nós pesquisa para encontrar um hiperplana w que minimizaria a dobradiça-perda total: w * = argmin w L h i n g e S ( w ) = argmin w Σ i l h i n g e ( w ,S xi∈Rd yi∈{−1,1} w
fonte
Eu consertei seu código. O principal problema é a sua definição de funções de dobradiça e d_hinge. Estes devem ser aplicados uma amostra de cada vez. Em vez disso, sua definição agrega todas as amostras antes de obter o máximo.
Eu preciso n = 10000 para convergir.
[1] "perda: 0.090000, xw: 1.08999999999995,0.909999999999905, -1.19000000000008, -1.69000000000011" [1] "perda: 0.100000, xw: 1.33999999999995,1.1199999999999, -0.900000000000075, -1.42000000000011:", 1 x 0,939999999999948,0,829999999999905, -1,32000000000007, -1,77000000000011 "[1]" perda: 0,370000, xw: 1,64999999999995,1,2899999999999, -0,630000000000000075, -1,25000000000011 "[1]" perda: 0,00000000009999 ", 990000000099" [1] "perda: 0,240000, xw: 1,49999999999995,1.2099999999999, -0,760000000000075, -1,33000000000011" [1] "perda: 0,080000, xw: 1,09999999999995,0,91999999999999905, -1,18000000000007, -1,680000 x 011: [1] 1.34999999999995,1.1299999999999, -0.890000000000075, -1.41000000000011 "[1] "perda: 0,210000, xw: 0,949999999999948,0,839999999999905, -1,31000000000007, -1,76000000000011" [1] "perda: 0,380000, xw: 1,65999999999995,1,2999999999999, -0,620000000000074, -1,24000000000011" [1] 1.25999999999995,1.0099999999999, -1.04000000000008, -1.59000000000011 "[1]" perda: 0.000000, xw: 1.25999999999995,1.0099999999999, -1.04000000000008, -1.5900000000000011 "
fonte