2015-09-13 21 views
22

Sto provando ad implementare la rete neurale con RELU.Backpropagation della rete neurale con RELU

livello di input -> 1 strato nascosto -> Relu -> strato di output -> strato softmax

Sopra è l'architettura della mia rete neurale. Sono confuso riguardo la backpropagation di questo relu. Per derivata di RELU, se x < = 0, l'uscita è 0. se x> 0, l'uscita è 1. Quindi quando si calcola il gradiente, significa che ho il gradiente di decente se x < = 0?

Qualcuno può spiegare "passo dopo passo" la backpropagation della mia architettura di rete neurale?

risposta

7

Se si dispone di un layer costituito da una sola ReLU, come suggerisce la propria architettura, quindi sì, si uccide il gradiente a 0. Durante l'allenamento, ReLU restituirà 0 al livello di output, che restituirà 0 o 0.5 se si utilizzano unità logistiche e il softmax lo schiaccerà. Quindi un valore di 0 sotto l'attuale architettura non ha molto senso per la parte di propagazione in avanti.

Vedere ad esempio this. Quello che puoi fare è usare un "leaky ReLU", che è un piccolo valore a 0, come 0.01.

Vorrei riconsiderare questa architettura, tuttavia, per me non ha molto senso alimentare un singolo ReLU in un gruppo di altre unità, quindi applicare un softmax.

5

se x < = 0, l'uscita è 0. Se x> 0, l'uscita è 1

La funzione relu è definita come: Per x> 0 l'uscita è x, cioè f (x) = max (0, x)

Così, per la derivata f '(x) in realtà è:

se x < 0, l'uscita è 0. se x> 0, l'uscita è 1.

La derivata f '(0) non è definita. Di solito è impostato su 0 o si modifica la funzione di attivazione in f (x) = max (e, x) per una piccola e.

In generale: A ReLU è un'unità che utilizza la funzione di attivazione del raddrizzatore. Ciò significa che funziona esattamente come qualsiasi altro livello nascosto ma ad eccezione di tanh (x), sigmoid (x) o qualsiasi altra attivazione tu usi, invece userai f (x) = max (0, x).

Se si è scritto codice per una rete multilayer funzionante con attivazione sigmoid è letteralmente una riga di modifica. Nulla sulle modifiche di propagazione in avanti o indietro a livello algoritmico. Se non hai ancora funzionato il modello più semplice, torna indietro e inizia con quello. Altrimenti la tua domanda non riguarda realmente i ReLU ma l'implementazione di un NN nel suo insieme.

+0

Sei sicuro che sia corretto? Ho un codice backprop funzionante e ho cambiato la funzione di attivazione (nel codice di forward prop) e il gradiente (nel codice backprop) e quindi il programma non riesce a convergere per un semplice test XOR. –

+1

@Yan King Yin Sì. Ciò potrebbe accadere a causa di pesi morti. Inoltre, non dovrebbe essere necessario modificare nulla sul gradiente. – runDOSrun

+0

Grazie, dopo aver corretto alcuni bug, penso che tu abbia ragione. Per alcuni pesi iniziali casuali, l'intera rete potrebbe essere morta però. –

2

Ecco un buon esempio, utilizzare Relu per implementare XOR: di riferimento, 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() 

Maggiori informazioni sul derivato di Relu, potete vedere qui: http://kawahara.ca/what-is-the-derivative-of-relu/