web-dev-qa-db-fra.com

la descente du gradient semble échouer

J'ai mis en œuvre un algorithme de descente de gradient afin de minimiser une fonction de coût afin de générer une hypothèse permettant de déterminer si une image est de bonne qualité. Je l'ai fait dans Octave. L'idée est en quelque sorte basée sur l'algorithme du cours d'apprentissage automatique par Andrew Ng

Par conséquent, j'ai 880 valeurs "y" qui contiennent des valeurs de 0,5 à ~ 12. Et j'ai 880 valeurs de 50 à 300 en "X" qui devraient prédire la qualité de l'image.

Malheureusement, l'algorithme semble échouer, après quelques itérations, la valeur de thêta est si petite que theta0 et theta1 deviennent "NaN". Et ma courbe de régression linéaire a des valeurs étranges ...

voici le code de l'algorithme de descente de gradient: (theta = zeros(2, 1);, alpha = 0.01, itérations = 1500)

function [theta, J_history] = gradientDescent(X, y, theta, alpha, num_iters)

m = length(y); % number of training examples
J_history = zeros(num_iters, 1);

for iter = 1:num_iters


    tmp_j1=0;
for i=1:m, 
    tmp_j1 = tmp_j1+ ((theta (1,1) + theta (2,1)*X(i,2)) - y(i));
end

    tmp_j2=0;
for i=1:m, 
    tmp_j2 = tmp_j2+ (((theta (1,1) + theta (2,1)*X(i,2)) - y(i)) *X(i,2)); 
end

    tmp1= theta(1,1) - (alpha *  ((1/m) * tmp_j1))  
    tmp2= theta(2,1) - (alpha *  ((1/m) * tmp_j2))  

    theta(1,1)=tmp1
    theta(2,1)=tmp2

    % ============================================================

    % Save the cost J in every iteration    
    J_history(iter) = computeCost(X, y, theta);
end
end

Et voici le calcul de la fonction coût:

function J = computeCost(X, y, theta)   %

m = length(y); % number of training examples
J = 0;
tmp=0;
for i=1:m, 
    tmp = tmp+ (theta (1,1) + theta (2,1)*X(i,2) - y(i))^2; %differenzberechnung
end
J= (1/(2*m)) * tmp
end
25
Tyzak

Je pense que votre fonction computeCost est fausse. J'ai assisté au cours de NG l'année dernière et j'ai l'implémentation suivante (vectorisée):

m = length(y);
J = 0;
predictions = X * theta;
sqrErrors = (predictions-y).^2;

J = 1/(2*m) * sum(sqrErrors);

Le reste de la mise en œuvre me semble correct, bien que vous puissiez également les vectoriser.

theta_1 = theta(1) - alpha * (1/m) * sum((X*theta-y).*X(:,1));
theta_2 = theta(2) - alpha * (1/m) * sum((X*theta-y).*X(:,2));

Ensuite, vous réglez correctement les thêtas temporaires (appelés ici theta_1 et theta_2) sur le "vrai" thêta.

Généralement, il est plus utile de vectoriser au lieu de boucles, il est moins gênant de lire et de déboguer.

25
Thomas Jungblut

j'ai vectorisé la chose thêta ... peut peut-être aider quelqu'un

theta = theta - (alpha/m *  (X * theta-y)' * X)';
31
Markus

Bien qu’il ne soit pas évolutif comme une version vectorisée, un calcul en boucle d’une descente de gradient devrait générer les mêmes résultats. Dans l'exemple ci-dessus, le cas le plus probable où la descente de gradient n'a pas permis de calculer le thêta correct est la valeur de alpha. 

Avec un ensemble vérifié de fonctions de coût et de descente de gradient et un ensemble de données similaires à celui décrit dans la question, thêta se termine avec les valeurs de NaN juste après quelques itérations si alpha = 0.01. Cependant, lorsqu'il est défini sur alpha = 0.000001, la descente de gradient fonctionne comme prévu, même après 100 itérations.

2
AdiGri

Si vous êtes d'accord avec l'utilisation d'une fonction de coût par moindres carrés, vous pouvez essayer d'utiliser l'équation normale au lieu de la descente de gradient. C'est beaucoup plus simple - une seule ligne - et plus rapide en calcul.

Voici l'équation normale: http://mathworld.wolfram.com/NormalEquation.html

Et sous forme d'octave:

theta = (pinv(X' * X )) * X' * y

Voici un tutoriel qui explique comment utiliser l'équation normale: http://www.lauradhamilton.com/tutorial-linear-regression-with-octave

2
user2437742

En utilisant uniquement des vecteurs, voici l'implémentation compacte de LR avec Gradient Descent dans Mathematica:

Theta = {0, 0}
alpha = 0.0001;
iteration = 1500;
Jhist = Table[0, {i, iteration}];
Table[  
  Theta = Theta - 
  alpha * Dot[Transpose[X], (Dot[X, Theta] - Y)]/m; 
  Jhist[[k]] = 
  Total[ (Dot[X, Theta] - Y[[All]])^2]/(2*m); Theta, {k, iteration}]

Remarque: Bien entendu, on suppose que X est une matrice n * 2, avec X [[ 1]] contenant uniquement

0
user34018

Cela devrait fonctionner: -

theta(1,1) = theta(1,1) - (alpha*(1/m))*((X*theta - y)'* X(:,1) ); 

theta(2,1) = theta(2,1) - (alpha*(1/m))*((X*theta - y)'* X(:,2) ); 
0
Gator-aid

Si vous vous souvenez du premier fichier Pdf pour le cours d’apprentissage Machine de formulaire Gradient Descent, vous vous occuperiez du taux d’apprentissage. Voici la note du pdf mentionné. 

Note d'implémentation: Si votre vitesse d'apprentissage est trop grande, J(theta) peut di -verge et blow up', resulting in values which are too large for computer calculations. In these situations, Octave/MATLAB will tend to return NaNs. NaN stands for pas un nombre 'et est souvent causé par des opérations non résolues Qui impliquent - l'infini et + l'infini. 

0
morteza

son nettoyeur de cette façon, et vectorisé aussi

predictions = X * theta;
errorsVector = predictions - y;
theta = theta - (alpha/m) * (X' * errorsVector);
0
Edwin Ikechukwu