2015-09-13 212 views
22

我想用RELU實現神經網絡。用RELU進行神經網絡反向傳播

輸入層 - > 1隱藏層 - > RELU - >輸出層 - > SOFTMAX層

以上是我的神經網絡的體系結構。 我很困惑這relu的反向傳播。 對於RELU的導數,如果x < = 0,則輸出爲0. 如果x> 0,則輸出爲1. 因此,當您計算梯度時,這是否意味着如果x < = 0,

有人可以解釋我的神經網絡架構「一步一步」的反向傳播嗎?

回答

7

如果您的圖層由單個ReLU製成,就像您的體系結構所暗示的那樣,那麼您可以在0處終止梯度。在訓練期間,ReLU將返回0到您的輸出層,如果您使用邏輯單元,則返回00.5,softmax將壓縮這些。因此,在當前體系結構下的0值對於前向傳播部分也沒有多大意義。

參見例如this。你可以做的是使用「泄漏ReLU」,這是一個在0的小值,如0.01

但我會重新考慮這個架構,然而,將單個ReLU饋入一堆其他單元然後應用softmax並沒有什麼意義。

5

如果x < = 0,輸出爲0,如果x> 0,輸出爲1

的RELU函數被定義爲:當x> 0時,輸出爲x,即F( X)= MAX(0,x)的

所以對於導函數f「(x)的它實際上:

如果x < 0,輸出爲0,如果x> 0,輸出爲1。

導數f'(0)未定義。所以它通常設置爲0,或者您可以將激活函數修改爲對於小e而言f(x)= max(e,x)。

通常:ReLU是使用整流器激活功能的單元。這意味着它的工作原理與其他任何隱藏層完全相同,但除了tanh(x),sigmoid(x)或您使用的任何激活之外,您將使用f(x)= max(0,x)。

如果您已經爲使用sigmoid激活的工作多層網絡編寫了代碼,它實際上是1行更改。前向或後向傳播在算法上沒有變化。如果你還沒有更簡單的模型工作,請回頭從頭開始。否則,你的問題不是關於ReLUs,而是關於整體實施NN。

+0

你確定這是對的嗎?我有工作反向代碼,並且我改變了激活函數(在前向支撐代碼中)和漸變(在反向代碼中),然後程序未能收斂以進行簡單的異或測試。 –

+1

@嚴景賢是的。這可能是由於體重不足造成的。你也不需要改變任何關於漸變的東西。 – runDOSrun

+0

謝謝,修復了一些錯誤後,我認爲你是對的。對於一些隨機初始權重,整個網絡可能已經死了。 –

2

這裏是一個很好的例子,使用RELU實現XOR: 參考,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() 

更多RELU的導數,你可以在這裏看到:http://kawahara.ca/what-is-the-derivative-of-relu/

相關問題