我想用RELU實現神經網絡。用RELU進行神經網絡反向傳播
輸入層 - > 1隱藏層 - > RELU - >輸出層 - > SOFTMAX層
以上是我的神經網絡的體系結構。 我很困惑這relu的反向傳播。 對於RELU的導數,如果x < = 0,則輸出爲0. 如果x> 0,則輸出爲1. 因此,當您計算梯度時,這是否意味着如果x < = 0,
有人可以解釋我的神經網絡架構「一步一步」的反向傳播嗎?
我想用RELU實現神經網絡。用RELU進行神經網絡反向傳播
輸入層 - > 1隱藏層 - > RELU - >輸出層 - > SOFTMAX層
以上是我的神經網絡的體系結構。 我很困惑這relu的反向傳播。 對於RELU的導數,如果x < = 0,則輸出爲0. 如果x> 0,則輸出爲1. 因此,當您計算梯度時,這是否意味着如果x < = 0,
有人可以解釋我的神經網絡架構「一步一步」的反向傳播嗎?
如果您的圖層由單個ReLU製成,就像您的體系結構所暗示的那樣,那麼您可以在0
處終止梯度。在訓練期間,ReLU將返回0
到您的輸出層,如果您使用邏輯單元,則返回0
或0.5
,softmax將壓縮這些。因此,在當前體系結構下的0
值對於前向傳播部分也沒有多大意義。
參見例如this。你可以做的是使用「泄漏ReLU」,這是一個在0
的小值,如0.01
。
但我會重新考慮這個架構,然而,將單個ReLU饋入一堆其他單元然後應用softmax並沒有什麼意義。
如果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。
此外,在這裏你可以找到朱古力框架的實現:https://github.com/BVLC/caffe/blob/master/src/caffe/layers/relu_layer.cpp
的negative_slope指定是否將「泄漏」通過與坡度值乘以它,而不是將其設置爲0。當然,你應該負部分將此參數設置爲零以具有經典版本。
這裏是一個很好的例子,使用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/
是在原單RELU函數你描述的問題。 因此,他們後來對公式進行了修改,並將其稱爲泄漏Relu 實質上,Leaky Relu將函數的水平部分略微傾斜了很小的一部分。欲瞭解更多信息,請看這裏:
An explantion of activation methods, and a improved Relu on youtube
你確定這是對的嗎?我有工作反向代碼,並且我改變了激活函數(在前向支撐代碼中)和漸變(在反向代碼中),然後程序未能收斂以進行簡單的異或測試。 –
@嚴景賢是的。這可能是由於體重不足造成的。你也不需要改變任何關於漸變的東西。 – runDOSrun
謝謝,修復了一些錯誤後,我認爲你是對的。對於一些隨機初始權重,整個網絡可能已經死了。 –