el descenso de gradiente parece fallar


Implementé un algoritmo de descenso de gradiente para minimizar una función de costo con el fin de obtener una hipótesis para determinar si una imagen tiene una buena calidad. Lo hice en Octava. La idea se basa de alguna manera en el algoritmo de la clase machine learning de Andrew Ng

Por lo tanto tengo 880 valores "y" que contiene valores de 0.5 a ~12. Y tengo 880 valores de 50 a 300 en "X" que deberían predecir la calidad de la imagen.

Lamentablemente el algoritmo parece fallar, después de algunas iteraciones el valor de theta es tan pequeño, que theta0 y theta1 se convierten en "NaN". Y mi curva de regresión lineal tiene valores extraños...

Aquí está el código para el algoritmo de descenso de gradiente: (theta = zeros(2, 1);, alfa = 0.01, iteraciones=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

Y aquí está el cálculo para la costfunction:

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
Author: Edwin Ikechukwu, 2012-05-07

8 answers

Creo que tu computeCost función está mal. Asistí a la clase de NG el año pasado y tengo la siguiente implementación (vectorizada):

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

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

El resto de la implementación me parece bien, aunque también podría vectorizarlos.

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));

Después está configurando las thetas temporales (aquí llamadas theta_1 y theta_2) correctamente de vuelta a la theta "real".

Generalmente es más útil vectorizar en lugar de bucles, es menos molesto leer y depurar.

 25
Author: Thomas Jungblut,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-10-16 05:54:21

Vectoricé la cosa theta... may podría ayudar a alguien

theta = theta - (alpha/m *  (X * theta-y)' * X)';
 31
Author: Markus,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-04-28 18:50:30

Si se pregunta cómo el bucle for de aspecto aparentemente complejo puede ser vectorizado y reducido a una sola expresión de línea, siga leyendo. La forma vectorizada es:

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

A continuación se da una explicación detallada de cómo llegamos a esta expresión vectorizada utilizando el algoritmo de descenso de gradiente:

Este es el algoritmo de descenso de gradiente para afinar el valor de θ: introduzca la descripción de la imagen aquí

Supongamos que los siguientes valores de X, y y θ se dan:

  • m = número de ejemplos de entrenamiento
  • n = número de características + 1

introduzca la descripción de la imagen aquí

Aquí

  • m = 5 (ejemplos de entrenamiento)
  • n = 4 (características+1)
  • X = m x n matriz
  • y = m x 1 matriz vectorial
  • θ = n x 1 matriz vectorial
  • xi es el ith formación ejemplo
  • x j es la característica jth en un entrenamiento dado ejemplo

Además,

  • h(x) = ([X] * [θ]) (m x 1 matriz de valores predichos para nuestro conjunto de entrenamiento)
  • h(x)-y = ([X] * [θ] - [y]) (m x 1 matriz de errores en nuestras predicciones)

todo el objetivo del aprendizaje automático es minimizar los errores en las predicciones. Basado en el corolario anterior, nuestra matriz de errores es m x 1 matriz vectorial de la siguiente manera:

introduzca la descripción de la imagen aquí

Para calcular el nuevo valor de θj, tenemos que obtener una suma de todos errores (filas m) multiplicados por jth valor de característica del conjunto de entrenamiento X. Es decir, tomar todos los valores en E, multiplicarlos individualmente con jth característica del correspondiente ejemplo de entrenamiento, y sumarlos todos juntos. Esto nos ayudará a obtener el nuevo (y esperemos que mejor) valor de θ j . Repita este proceso para todos j o el número de entidades. En forma de matriz, esto se puede escribir como:

introduzca la descripción de la imagen aquí

Esto puede ser simplificada como: introduzca la descripción de la imagen aquí

  • [E]' x [X] nos dará una matriz vectorial fila, ya que E' es 1 x m matriz y X es m x n matriz. Pero estamos interesados en obtener una matriz de columna, por lo tanto transponemos la matriz resultante.

Más sucintamente, se puede escribir como: introduzca la descripción de la imagen aquí

Desde (A * B)' = (B' * A'), y A'' = A, también podemos escribir lo anterior como

introduzca la descripción de la imagen aquí

Esta es la expresión original con la que empezamos:

theta = theta - (alpha/m) * (X' * (X * theta - y))
 17
Author: jerrymouse,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-03-23 10:22:12

Si está de acuerdo con el uso de una función de costo de mínimos cuadrados, entonces podría intentar usar la ecuación normal en lugar del descenso de gradiente. Es mucho más simple only solo una línea comput y computacionalmente más rápido.

Aquí está la ecuación normal: http://mathworld.wolfram.com/NormalEquation.html

Y en forma de octava:

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

Aquí hay un tutorial que explica cómo usar la ecuación normal: http://www.lauradhamilton.com/tutorial-linear-regression-with-octave

 2
Author: user2437742,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-03-16 10:57:11

Aunque no es escalable como una versión vectorizada, un cálculo basado en bucles de un descenso de gradiente debería generar los mismos resultados. En el ejemplo anterior, el caso más probable de que el descenso del gradiente no calcule el theta correcto es el valor de alfa.

Con un conjunto verificado de funciones de descenso de costos y gradiente y un conjunto de datos similar al descrito en la pregunta, theta termina con valores NaN justo después de unas cuantas iteraciones si alpha = 0.01. Sin embargo, cuando se establece como alpha = 0.000001, el descenso del gradiente funciona como se esperaba, incluso después de 100 iteraciones.

 2
Author: AdiGri,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-03-02 07:29:58

Usando solo vectores aquí está la implementación compacta de LR con Descenso de Gradiente en 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}]

Nota: Por supuesto uno asume que X es una matriz n * 2, con X [[, 1]] conteniendo solamente 1s'

 0
Author: user34018,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-08-16 12:43:44

Esto debería funcionar:-

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
Author: Shubham Sharma,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-11-13 14:06:26

Es más limpio de esta manera, y vectorizado también

predictions = X * theta;
errorsVector = predictions - y;
theta = theta - (alpha/m) * (X' * errorsVector);
 0
Author: Edwin Ikechukwu,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-05-18 09:06:15