2014-10-31 10 views
5

Ciao Sto cercando di implementare l'algoritmo Gradient Descent per una funzione:Cosa c'è di sbagliato con il mio algoritmo di discesa del gradiente

enter image description here

mio punto di partenza per l'algoritmo è w = (u, v) = (2,2). Il tasso di apprendimento è eta = 0,01 e legato = 10^-14. Ecco il mio codice MATLAB:

function [resultTable, boundIter] = gradientDescent(w, iters, bound, eta) 
% FUNCTION [resultTable, boundIter] = gradientDescent(w, its, bound, eta) 
% 
% DESCRIPTION: 
% - This function will do gradient descent error minimization for the 
% function E(u,v) = (u*exp(v) - 2*v*exp(-u))^2. 
% 
% INPUTS: 
% 'w' a 1-by-2 vector indicating initial weights w = [u,v] 
% 'its' a positive integer indicating the number of gradient descent 
% iterations 
% 'bound' a real number indicating an error lower bound 
% 'eta' a positive real number indicating the learning rate of GD algorithm 
% 
% OUTPUTS: 
% 'resultTable' a iters+1-by-6 table indicating the error, partial 
% derivatives and weights for each GD iteration 
% 'boundIter' a positive integer specifying the GD iteration when the error 
% function got below the given error bound 'bound' 
% 


% The error function 
E = @(u,v) (u*exp(v) - 2*v*exp(-u))^2; 

% Partial derivative of E with respect to u 
pEpu = @(u,v) 2*(u*exp(v) - 2*v*exp(-u))*(exp(v) + 2*v*exp(-u)); 
% Partial derivative of E with respect to v 
pEpv = @(u,v) 2*(u*exp(v) - 2*v*exp(-u))*(u*exp(v) - 2*exp(-u)); 

% Initialize boundIter 
boundIter = 0; 
% Create a table for holding the results 
resultTable = zeros(iters+1, 6); 
% Iteration number 
resultTable(1, 1) = 0; 
% Error at iteration i 
resultTable(1, 2) = E(w(1), w(2)); 
% The value of pEpu at initial w = (u,v) 
resultTable(1, 3) = pEpu(w(1), w(2)); 
% The value of pEpv at initial w = (u,v) 
resultTable(1, 4) = pEpv(w(1), w(2)); 
% Initial u 
resultTable(1, 5) = w(1); 
% Initial v 
resultTable(1, 6) = w(2); 

% Loop all the iterations 
for i = 2:iters+1 

    % Save the iteration number 
    resultTable(i, 1) = i-1; 
    % Update the weights 
    temp1 = w(1) - eta*(pEpu(w(1), w(2))); 
    temp2 = w(2) - eta*(pEpv(w(1), w(2))); 
    w(1) = temp1; 
    w(2) = temp2; 
    % Evaluate the error function at new weights 
    resultTable(i, 2) = E(w(1), w(2)); 
    % Evaluate pEpu at the new point 
    resultTable(i, 3) = pEpu(w(1), w(2)); 
    % Evaluate pEpv at the new point 
    resultTable(i, 4) = pEpv(w(1), w(2)); 
    % Save the new weights 
    resultTable(i, 5) = w(1); 
    resultTable(i, 6) = w(2); 
    % If the error function is below a specified bound save this iteration 
    % index 
    if E(w(1), w(2)) < bound 
     boundIter = i-1; 
    end 

end 

Questo è un esercizio nella mia macchina corso di formazione, ma per qualche ragione i miei risultati sono tutti sbagliati. Ci deve essere qualcosa di sbagliato nel codice. Ho provato il debugging e il debugging e non ho trovato nulla di sbagliato ... qualcuno può identificare qual è il mio problema qui? ... In altre parole, puoi verificare che il codice sia un algoritmo di discesa del gradiente valido per la funzione data?

Si prega di farmi sapere se la mia domanda è troppo chiaro o se avete bisogno di più informazioni :)

Grazie per il vostro sforzo e aiuto! =)

Ecco il mio risultato per cinque iterazioni e quello che gli altri hanno ottenuto:

PARAMETRI: w = [2,2], l'ETA = 0,01, limite = 10^-14, iter = 5

enter image description here

+0

Avete i dati di input e il risultato? –

+0

@ AnderBiguri Ciao, non ci sono dati di input per questo problema. Il punto è solo per minimizzare la funzione data E (u, v) con la discesa del gradiente. Il punto di partenza è w = (u, v) = (2,2), eta = 0,01, legato = 10^-14. Il parametro 'iters' può essere scelto liberamente, ad es. iters = 50. Pubblicherò i miei risultati con cinque iterazioni e quindi i risultati corrispondenti dal forum di discussione dei miei corsi che altre persone hanno ricevuto. – jjepsuomi

+1

Haha c'è dati di input, e appena me lo dai! grazie, controllerò. –

risposta

4

come descritto di seguito la domanda: direi che gli altri hanno torto ... il tuo minimizzazione porta a valori minori di E(u,v), controllare:

E(1.4,1.6) = 37.8 >> 3.6 = E(0.63, -1.67) 
+0

+1 Grazie :) – jjepsuomi

+1

sei il benvenuto;) – matheburg

2

(mi scuso per non solo commentare, ma io sono nuovo a così e non posso commentare.)

Sembra che l'algoritmo sta facendo la cosa giusta. Quello che vuoi essere sicuro è che ad ogni passo l'energia si sta restringendo (che è). Ci sono diversi motivi per cui i tuoi punti dati potrebbero non essere d'accordo con gli altri nella classe: potrebbero essere sbagliati (tu o altri della classe), forse hanno iniziato in un altro punto, forse hanno usato una dimensione di passo diversa (cosa sei chiamando eta credo).

Idealmente, non si desidera codificare il numero di iterazioni. Si desidera continuare fino a raggiungere un minimo locale (che si spera sia il minimo globale). Per verificarlo, vuoi che entrambe le derivate parziali siano zero (o molto vicine). Inoltre, per essere sicuro di avere un minimo locale (non un massimo locale, o un punto di sella) dovresti controllare il segno di E_uu * E_vv - E_uv^2 e il segno di E_uu guarda: http://en.wikipedia.org/wiki/Second_partial_derivative_test per i dettagli (il secondo test derivativo, in alto). Se ti trovi in ​​un punto max o sella locale, il tuo gradiente ti dirà di non muoverti (poiché le derivate parziali sono 0). Poiché sai che questo non è ottimale, devi solo perturbare la tua soluzione (a volte chiamata ricottura simulata).

Spero che questo aiuti.

+0

+1 Grazie @TravisJ risposta eccellente:) Hai anche ragione. Ho la risposta giusta Sembra che gli altri fossero davvero sbagliati :) – jjepsuomi

4

Non è una risposta completa, ma lascia andare per esso:

ho aggiunto una parte tracciando nel codice, in modo da poter vedere cosa sta succedendo.

u1=resultTable(:,5); 
v1=resultTable(:,6); 
E1=E(u1,v1); 
E1(E1<bound)=NaN; 
[x,y]=meshgrid(-1:0.1:5,-5:0.1:2);Z=E(x,y); 
surf(x,y,Z) 

hold on 
plot3(u1,v1,E1,'r') 
plot3(u1,v1,E1,'r*') 

enter image description here Il risultato dimostra che l'algoritmo sta facendo la cosa giusta per quella funzione.Quindi, come altri hanno detto, o tutti gli altri sono sbagliati, o non stai usando l'equazione giusta dall'inizio.

+0

+1 Molto bello, grazie @AnderBiguri apprezzo molto i tuoi sforzi! :) – jjepsuomi