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
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.
j'ai vectorisé la chose thêta ... peut peut-être aider quelqu'un
theta = theta - (alpha/m * (X * theta-y)' * X)';
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.
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
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
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) );
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.
son nettoyeur de cette façon, et vectorisé aussi
predictions = X * theta;
errorsVector = predictions - y;
theta = theta - (alpha/m) * (X' * errorsVector);