Réponse courte:
- Dans de nombreux paramètres de Big Data (disons plusieurs millions de points de données), le calcul du coût ou du gradient prend très longtemps, car nous devons additionner tous les points de données.
- Nous n'avons PAS besoin d'avoir un gradient exact pour réduire le coût dans une itération donnée. Une approximation du gradient fonctionnerait bien.
- Le gradient stochastique décent (SGD) se rapproche du gradient en utilisant un seul point de données. Ainsi, l'évaluation du gradient permet de gagner beaucoup de temps par rapport à la somme de toutes les données.
- Avec un nombre "raisonnable" d'itérations (ce nombre pourrait être de quelques milliers, et bien inférieur au nombre de points de données, qui peuvent être des millions), le gradient stochastique décent peut obtenir une bonne solution raisonnable.
Longue réponse:
Ma notation suit le cours Coursera d'apprentissage automatique d'Andrew NG. Si vous ne le connaissez pas, vous pouvez consulter la série de conférences ici .
Supposons une régression sur la perte au carré, la fonction de coût est
J( θ ) = 12 m∑i = 1m( hθ( x( i )) - y( i ))2
et le gradient est
réJ( θ )réθ= 1m∑i = 1m( hθ( x( i )) - y( i )) x( i )
pour un gradient décent (GD), nous mettons à jour le paramètre en
θn e w= θo l d- α 1m∑i = 1m( hθ( x( i )) - y( i )) x( i )
1 / mX( i ), y( i )
θn e w= θo l d- α ⋅ ( hθ( x( i )) - y( i )) x( i )
Voici pourquoi nous gagnons du temps:
Supposons que nous ayons 1 milliard de points de données.
Dans GD, afin de mettre à jour les paramètres une fois, nous devons avoir le gradient (exact). Cela nécessite de résumer ces 1 milliard de points de données pour effectuer 1 mise à jour.
Dans SGD, nous pouvons penser qu'il essaie d'obtenir un gradient approximatif au lieu d'un gradient exact . L'approximation provient d'un point de données (ou de plusieurs points de données appelés mini-lots). Par conséquent, dans SGD, nous pouvons mettre à jour les paramètres très rapidement. De plus, si nous "bouclons" sur toutes les données (appelées une époque), nous avons en fait 1 milliard de mises à jour.
L'astuce est que, dans SGD, vous n'avez pas besoin d'avoir 1 milliard d'itérations / mises à jour, mais beaucoup moins d'itérations / mises à jour, disons 1 million, et vous aurez un modèle "assez bon" à utiliser.
J'écris un code pour démo l'idée. Nous résolvons d'abord le système linéaire par une équation normale, puis le résolvons avec SGD. Ensuite, nous comparons les résultats en termes de valeurs de paramètres et de valeurs de fonctions objectives finales. Afin de le visualiser plus tard, nous aurons 2 paramètres à régler.
set.seed(0);n_data=1e3;n_feature=2;
A=matrix(runif(n_data*n_feature),ncol=n_feature)
b=runif(n_data)
res1=solve(t(A) %*% A, t(A) %*% b)
sq_loss<-function(A,b,x){
e=A %*% x -b
v=crossprod(e)
return(v[1])
}
sq_loss_gr_approx<-function(A,b,x){
# note, in GD, we need to sum over all data
# here i is just one random index sample
i=sample(1:n_data, 1)
gr=2*(crossprod(A[i,],x)-b[i])*A[i,]
return(gr)
}
x=runif(n_feature)
alpha=0.01
N_iter=300
loss=rep(0,N_iter)
for (i in 1:N_iter){
x=x-alpha*sq_loss_gr_approx(A,b,x)
loss[i]=sq_loss(A,b,x)
}
Les resultats:
as.vector(res1)
[1] 0.4368427 0.3991028
x
[1] 0.3580121 0.4782659
124.1343123.0355
Voici les valeurs de la fonction de coût sur les itérations, nous pouvons voir qu'elle peut effectivement réduire la perte, ce qui illustre l'idée: nous pouvons utiliser un sous-ensemble de données pour approximer le gradient et obtenir des résultats "assez bons".
1000sq_loss_gr_approx
3001000