2015-09-13 4 views
22

Ich versuche neuronales Netzwerk mit RELU zu implementieren.Neuronales Netzwerk Backpropagation mit RELU

Eingangsschicht -> 1 verborgene Schicht -> relu -> Ausgangsschicht -> softmax Schicht

Oben ist die Architektur meines neuronalen Netzes. Ich bin verwirrt über die Rückpropagation dieses Relukts. Für Derivat von RELU, wenn x < = 0, ist Ausgang 0. wenn x> 0, ist Ausgang 1. Also, wenn Sie den Gradienten berechnen, bedeutet das, dass ich Gradient abtönen, wenn x < = 0?

Kann jemand die Backpropagation meiner neuronalen Netzwerkarchitektur "Schritt für Schritt" erklären?

Antwort

7

Wenn Sie eine Schicht aus einer einzelnen ReLU haben, wie es Ihre Architektur vorschlägt, dann töten Sie den Farbverlauf bei 0. Während des Trainings gibt die ReLU 0 an Ihre Ausgabeschicht zurück, die entweder 0 oder 0.5 zurückgibt, wenn Sie logistische Einheiten verwenden, und die Softmax wird diese komprimieren. Ein Wert von 0 unter Ihrer aktuellen Architektur macht also auch für den Forward-Propagation-Teil wenig Sinn.

Siehe zum Beispiel this. Was Sie tun können, ist ein "Leaky ReLU", das ist ein kleiner Wert bei 0, wie 0.01.

Ich würde diese Architektur überdenken, aber es macht mir nicht viel Sinn, eine einzelne ReLU in eine Reihe anderer Einheiten zu füttern und dann eine Softmax anzuwenden.

5

wenn x < = 0 ist, ausgegeben wird, 0. Wenn x> 0, Ausgang 1

Die relu Funktion definiert ist als: für x> 0 die Ausgabe x ist, das heißt f (x) = max (0, x)

Also für die Ableitung f ‚(x) es ist eigentlich:

wenn x < 0, Ausgang 0 ist, wenn x> 0, Ausgang 1.

Die Ableitung f '(0) ist nicht definiert. Also ist es normalerweise auf 0 gesetzt oder Sie modifizieren die Aktivierungsfunktion, um f (x) = max (e, x) für ein kleines e zu sein.

Allgemein: Ein ReLU ist eine Einheit, die die Gleichrichteraktivierungsfunktion verwendet. Das heißt, es funktioniert genau wie jede andere versteckte Ebene, außer tanh (x), sigmoid (x) oder was auch immer Sie verwenden, verwenden Sie stattdessen f (x) = max (0, x).

Wenn Sie Code für ein funktionierendes Multilayer-Netzwerk mit Sigmoid-Aktivierung geschrieben haben, ist dies buchstäblich eine Zeile der Änderung. Es ändert sich algorithmisch nichts über die Vorwärts- oder Rückwärtsausbreitung. Wenn Sie das einfachere Modell noch nicht haben, gehen Sie zurück und beginnen Sie damit zuerst. Ansonsten geht es bei Ihrer Frage nicht wirklich um ReLUs, sondern darum, ein NN als Ganzes zu implementieren.

+0

Sind Sie sicher, dass ist richtig? Ich habe backprop Code arbeiten, und ich änderte die Aktivierungsfunktion (im Forward-Prop-Code) und den Gradienten (im Backprop-Code) und dann konvergiert das Programm für einen einfachen XOR-Test nicht. –

+1

@Yan König Yin Ja. Das könnte aufgrund von Eigengewichten passieren. Sie sollten auch nichts über den Farbverlauf ändern müssen. – runDOSrun

+0

Danke, nachdem du einige Fehler behoben hast, denke ich, dass du recht hast. Für einige zufällige Anfangsgewichte könnte das gesamte Netzwerk jedoch tot sein. –

1

Zusätzlich können Sie hier eine Implementierung in caffe Rahmen finden: https://github.com/BVLC/caffe/blob/master/src/caffe/layers/relu_layer.cpp

Die negative_slope gibt an, ob den negativen Teil zu „Leck“, indem sie es mit dem Steigungswert multipliziert wird, anstatt es auf 0 Natürlich Einstellung sollten Sie Setzen Sie diesen Parameter auf Null, um die klassische Version zu erhalten.

2

Hier ist ein gutes Beispiel verwenden relu XOR zu implementieren: Referenz, http://pytorch.org/tutorials/beginner/pytorch_with_examples.html

# -*- coding: utf-8 -*- 
import numpy as np 
import matplotlib.pyplot as plt 

# N is batch size(sample size); D_in is input dimension; 
# H is hidden dimension; D_out is output dimension. 
N, D_in, H, D_out = 4, 2, 30, 1 

# Create random input and output data 
x = np.array([[0, 0], [0, 1], [1, 0], [1, 1]]) 
y = np.array([[0], [1], [1], [0]]) 

# Randomly initialize weights 
w1 = np.random.randn(D_in, H) 
w2 = np.random.randn(H, D_out) 

learning_rate = 0.002 
loss_col = [] 
for t in range(200): 
    # Forward pass: compute predicted y 
    h = x.dot(w1) 
    h_relu = np.maximum(h, 0) # using ReLU as activate function 
    y_pred = h_relu.dot(w2) 

    # Compute and print loss 
    loss = np.square(y_pred - y).sum() # loss function 
    loss_col.append(loss) 
    print(t, loss, y_pred) 

    # Backprop to compute gradients of w1 and w2 with respect to loss 
    grad_y_pred = 2.0 * (y_pred - y) # the last layer's error 
    grad_w2 = h_relu.T.dot(grad_y_pred) 
    grad_h_relu = grad_y_pred.dot(w2.T) # the second laye's error 
    grad_h = grad_h_relu.copy() 
    grad_h[h < 0] = 0 # the derivate of ReLU 
    grad_w1 = x.T.dot(grad_h) 

    # Update weights 
    w1 -= learning_rate * grad_w1 
    w2 -= learning_rate * grad_w2 

plt.plot(loss_col) 
plt.show() 

Mehr zu der derivate von relu, können Sie hier sehen: http://kawahara.ca/what-is-the-derivative-of-relu/

Verwandte Themen