2014-06-22 7 views
7

Ich versuche Gradientenberechnung für neuronale Netze mit Backpropagation zu implementieren. Ich kann es nicht mit Cross-Entropie-Fehler und rektifizierte lineare Einheit (ReLU) als Aktivierung arbeiten.Backpropagation für gleichgerichtete Lineareinheit Aktivierung mit Kreuz-Entropie-Fehler

Ich habe es geschafft, meine Implementierung arbeiten für quadrierten Fehler mit sigmoid, tanh und ReLU Aktivierungsfunktionen. Kreuz-Entropie (CE) -Fehler mit sigmoidem Aktivierungsgradienten wird korrekt berechnet. Wenn ich jedoch die Aktivierung zu ReLU ändere, schlägt es fehl. (Ich überspringe tanh für CE, wie es Werte in (-1,1) Bereich retails.)

Ist es wegen des Verhaltens der Protokollfunktion bei Werten in der Nähe von 0 (die von ReLUs ca. 50% zurückgegeben wird) der Zeit für normalisierte Eingaben)? Ich habe versucht, dieses Problem mitiage mit:

log(max(y,eps)) 

aber es half nur Fehler und Steigungen auf reelle Zahlen zurück zu bringen - sie sind aus der numerischen Gradienten noch anders.

prüfe ich die Ergebnisse numerische Gradienten:

num_grad = (f(W+epsilon) - f(W-epsilon))/(2*epsilon) 

Der folgende MATLAB-Code stellt eine vereinfachte und verkürzte backpropagation Umsetzung in meinen Experimenten verwendet:

function [f, df] = backprop(W, X, Y) 
% W - weights 
% X - input values 
% Y - target values 

act_type='relu'; % possible values: sigmoid/tanh/relu 
error_type = 'CE'; % possible values: SE/CE 

N=size(X,1); n_inp=size(X,2); n_hid=100; n_out=size(Y,2); 
w1=reshape(W(1:n_hid*(n_inp+1)),n_hid,n_inp+1); 
w2=reshape(W(n_hid*(n_inp+1)+1:end),n_out, n_hid+1); 

% feedforward 
X=[X ones(N,1)]; 
z2=X*w1'; a2=act(z2,act_type); a2=[a2 ones(N,1)]; 
z3=a2*w2'; y=act(z3,act_type); 

if strcmp(error_type, 'CE') % cross entropy error - logistic cost function 
    f=-sum(sum(Y.*log(max(y,eps))+(1-Y).*log(max(1-y,eps)))); 
else % squared error 
    f=0.5*sum(sum((y-Y).^2)); 
end 

% backprop 
if strcmp(error_type, 'CE') % cross entropy error 
    d3=y-Y; 
else % squared error 
    d3=(y-Y).*dact(z3,act_type); 
end 

df2=d3'*a2; 
d2=d3*w2(:,1:end-1).*dact(z2,act_type); 
df1=d2'*X; 

df=[df1(:);df2(:)]; 

end 

function f=act(z,type) % activation function 
switch type 
    case 'sigmoid' 
     f=1./(1+exp(-z)); 
    case 'tanh' 
     f=tanh(z); 
    case 'relu' 
     f=max(0,z); 
end 
end 

function df=dact(z,type) % derivative of activation function 
switch type 
    case 'sigmoid' 
     df=act(z,type).*(1-act(z,type)); 
    case 'tanh' 
     df=1-act(z,type).^2; 
    case 'relu' 
     df=double(z>0); 
end 
end 

bearbeiten

Afte r eine weitere Runde von Experimenten, fand ich heraus, dass eine softmax für die letzte Schicht mit:

y=bsxfun(@rdivide, exp(z3), sum(exp(z3),2)); 

und softmax Kostenfunktion:

f=-sum(sum(Y.*log(y))); 

die implementaion machen die Arbeit für alle Aktivierungsfunktionen einschließlich relu.

Dies führt mich zu dem Schluss, dass es die logistische Kostenfunktion (binär clasifier), die nicht mit relu funktioniert:

f=-sum(sum(Y.*log(max(y,eps))+(1-Y).*log(max(1-y,eps)))); 

aber ich kann immer noch nicht herausfinden, wo das Problem liegt.

Antwort

0

Wenn Sie den Gradienten-Abkömmling verwenden, müssen Sie die Aktivierungsfunktion ableiten, die später im Back-Propagation-Ansatz verwendet wird. Bist du dir sicher, dass 'df = double (z> 0)'? Für die Logistik und Tan scheint das richtig zu sein.

Sind Sie sich außerdem sicher 'd3 = y-Y'? Ich würde sagen, das ist wahr, wenn Sie die logistische Funktion verwenden, aber nicht für die ReLu (die Ableitung ist nicht die gleiche und wird daher nicht zu dieser einfachen Gleichung führen).

Sie könnten die softplus-Funktion verwenden, die eine glatte Version der ReLU ist, die das Derivat wohlbekannt ist (logistische Funktion).

+1

Die Ableitung von relu Funtion ist: df = 0 für Eingabe <= 0 und df = 1 für input> 0, das in Matlab 'Doppel entspricht (z> 0)'. d3 ist das Delta der letzten Schicht und es ist die korrekte Form. ReLU hat Vorteile gegenüber der softplus-Funktion - überprüfen Sie [hier] (http://machinelearning.wustl.edu/mlpapers/paper_files/icml2010_NairH10.pdf) zum Beispiel. – Pr1mer

2

Jede Quetschfunktion sigmoid, tanh und softmax (in der Ausgabeschicht) bedeutet unterschiedliche Kostenfunktionen. Dann macht es Sinn, dass ein RLU (in der Ausgabeschicht) nicht mit der Kreuz-Entropie-Kostenfunktion übereinstimmt. Ich werde eine einfache quadratische Fehlerkostenfunktion versuchen, um eine RLU-Ausgabeschicht zu testen.

Die wahre Macht der RLE ist in den verborgenen Schichten eines tiefen Netz, da sie nicht von Gradienten verschwinden Fehler leiden.

+0

Ich kam zu dem ähnlichen Schluss, nachdem ich mehrere Artikel über NNs durchgearbeitet hatte. Wenn ich eine Klassifizierung benötige, besteht die Ausgabeschicht für Softmax aus Sigmoid-Einheiten. Andere Ebenen (versteckt) bestehen aus ReLUs. – Pr1mer

0

Ich denke, der Fehler liegt im Vergleich mit den numerisch berechneten Ableitungen. In Ihrer derivativeActivation-Funktion definieren Sie die Ableitung von ReLu bei 0 zu 0. Wenn Sie die Ableitung bei x = 0 numerisch berechnen, zeigt dies (ReLU (x + epsilon) -ReLU (x-epsilon)/(2 *) Epsilon)) bei x = 0, was 0,5 ist. Daher 0 definiert die Ableitung von relu bei x = auf 0,5 das Problem

0

lösen wird ich dachte, dass ich meine Erfahrungen teilen würde ich mit ähnlichem Problem hatte. Auch ich habe meinen Multi-Classifier ANN so entworfen, dass alle versteckten Layer RELU als nichtlineare Aktivierungsfunktion verwenden und die Ausgabeschicht softmax verwendet.

Mein Problem bezog sich zu einem gewissen Grad auf numerische Präzision der Programmiersprache/Plattform, die ich verwendete. In meinem Fall bemerkte ich, dass, wenn ich „plain“ verwendet RELU es nicht nur die Steigung aber die Programmiersprache nicht töten ich die folgenden softmax Ausgangsvektoren verwendet wird (dies ist nur ein Beispiel Probe):

⎡1.5068230536681645e-35⎤ 
⎢ 2.520367499064734e-18⎥ 
⎢3.2572859518007807e-22⎥ 
⎢      1⎥ 
⎢ 5.020155103452967e-32⎥ 
⎢1.7620297760773188e-18⎥ 
⎢ 5.216008990667109e-18⎥ 
⎢ 1.320937038894421e-20⎥ 
⎢2.7854159049317976e-17⎥ 
⎣1.8091246170996508e-35⎦ 

Beachten Sie die Werte der meisten Elemente sind nahe 0, aber am wichtigsten beachten Sie den 1 Wert in der Ausgabe.

verwendete ich einen anderen cross-entropy Fehlerfunktion als das von Ihnen verwendete. Anstatt log(max(1-y, eps)) zu berechnen, blieb ich bei der Basis log(1-y). Wenn ich also den obigen Ausgabevektor berechne, habe ich, als ich log(1-y) berechnet habe, das -Inf als Ergebnis von cross-entropy erhalten, was offensichtlich den Algorithmus zunichte gemacht hat.

Ich stelle mir vor, wenn Ihr eps so vernünftigerweise nicht hoch genug ist, dass log(max(1-y, eps)) ->log(max(0, eps)) nicht Art und Weise in einer ähnlichen Gurke wie ich Ihnen zu klein log Ausgang hat ergeben könnte.

Meine Lösung für dieses Problem war Leaky RELU zu verwenden. Sobald ich angefangen habe, es zu benutzen, konnte ich fortfahren, den multi classifier cross-entropy als softmax-cost Funktion zu verwenden, die Sie beschlossen, zu versuchen.

Verwandte Themen