2014-06-22 61 views
7

我試圖實現用於使用反向傳播神經網絡梯度計算。 我不能讓它與交叉熵錯誤一起工作,並將線性單位(ReLU)糾正爲激活。反向傳播整流線性單元激活與交叉熵誤差

我設法讓我的實現工作與sigmoid,tanh和ReLU激活函數的平方誤差。交叉熵(CE)誤差與S形激活梯度計算正確。但是,當我將激活更改爲ReLU時 - 它失敗。 (我爲CE跳過tanh,因爲它在(-1,1)範圍內後退值)。

是否因爲日誌函數的值接近於0的行爲(通過ReLUs返回大約50%標準化輸入的時間)? 我試圖mitiage這個問題有:

log(max(y,eps)) 

但它只能有助於使誤差和梯度回真正的號碼 - 他們仍然從數值梯度不同。

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

以下MATLAB代碼呈現在我的實驗中使用的簡化的和冷凝的反向傳播實現::

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 

編輯

我使用數值梯度驗證結果

Afte [R另一輪的實驗,我發現用Softmax最後一層:

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

和SOFTMAX成本函數:

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

使implementaion所有激活功能,包括RELU工作。

這使我的結論,這是物流成本函數(二進制clasifier)不與RELU工作:

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

但是,我仍然無法找出問題所在。

回答

0

如果使用漸變後代,則需要導出稍後在後向傳播方法中使用的激活函數。你確定'df = double(z> 0)'?'。對於邏輯和tanh似乎是正確的。

另外,你確定這個'd3 = y-Y'嗎?當你使用邏輯函數而不是ReLu時,我會說這是真實的(導數不相同,因此不會導致這個簡單的等式)。

您可以使用softplus函數,該函數是ReLU的光滑版本,衍生物是衆所周知的(邏輯函數)。

+1

ReLU函數的導數爲:對於輸入<= 0,df = 0,輸入> 0時df = 1,這在matlab中相當於'double(z> 0)'。 d3是最後一層的增量,它是正確的形式。例如,ReLU比softplus功能具有優勢 - 選中[here](http://machinelearning.wustl.edu/mlpapers/paper_files/icml2010_NairH10.pdf)。 – Pr1mer

2

每個擠壓函數sigmoid,tanh和softmax(在輸出層) 意味着不同的成本函數。 然後有意義的是RLU(在輸出層中)與交叉熵代價函數不匹配。 我會嘗試一個簡單的平方誤差成本函數來測試RLU輸出層。

RLU的真正力量是在深層的隱藏層,因爲它不會遭受梯度消失的錯誤。

+0

我經歷了幾篇關於神經網絡的論文後,得出了類似的結論。當我需要分類時,softmax的輸出層由sigmoid單元組成。其他圖層(隱藏)仍然由ReLUs組成。 – Pr1mer

0

我認爲這個缺陷在於與數值計算的衍生物進行共同映射。在您的衍生激活函數中,您定義ReLu在0處的導數爲0.在x = 0處的數值計算導數表明它爲 (ReLU(x + epsilon)-ReLU(x-ε)/(2 * epsilon))在x = 0時爲0.5。因此,將x = 0處的ReLU的導數定義爲0.5將解決問題

0

我想我會分享我遇到的類似問題的經驗。我也設計了我的多分類器ANN,所有隱藏層都使用RELU作爲非線性激活函數,輸出層使用softmax函數。

我的問題與我在使用的編程語言/平臺的數值精度有關。在我的情況下,我注意到,如果我使用的「普通」 RELU它不僅殺死梯度但我用產生了以下softmax輸出向量的編程語言(這只是一個例子樣品):

⎡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⎦ 

通知的大多數元素的值接近0,但最重要的是注意輸出中的值1

我用了一個不同的cross-entropy錯誤函數。我堅持使用基本的log(1-y),而不是計算log(max(1-y, eps))。因此,考慮到上面的輸出向量,當我計算log(1-y)時,由於cross-entropy,我得到了-Inf,這明顯地導致了算法的死亡。

我想象如果你的eps不合理的高度,以至於log(max(1-y, eps)) - >log(max(0, eps))不會產生太小的輸出,你可能會像我一樣在類似的泡菜。

我對此問題的解決方案是使用Leaky RELU。一旦我開始使用它,我可以繼續使用多分類器cross-entropy反對您決定嘗試的softmax-cost函數。