我正在尝试使用反向传播为神经网络实现梯度计算。
我无法使它与交叉熵误差和整流线性单位(ReLU)一起工作。

我设法通过Sigmoid,tanh和ReLU激活函数来使实现的平方误差起作用。正确计算出具有S型激活梯度的交叉熵(CE)误差。但是,当我将激活更改为ReLU时-失败。 (我跳过了CE的tanh,因为它重新显示(-1,1)范围内的值。)

是否由于log函数在接近0的值(归正输入的ReLU返回大约50%的时间)的情况下的行为?
我试图通过以下方法缓解该问题:

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

编辑

经过另一轮实验,我发现对最后一层使用softmax:
y=bsxfun(@rdivide, exp(z3), sum(exp(z3),2));

和softmax成本函数:
f=-sum(sum(Y.*log(y)));

使实现适用于所有激活功能,包括ReLU。

这使我得出结论,就是逻辑成本函数(二进制分类器)不适用于ReLU:
f=-sum(sum( Y.*log(max(y,eps))+(1-Y).*log(max(1-y,eps)) ));

但是,我仍然无法弄清楚问题出在哪里。

最佳答案

每个压扁函数sigmoid,tanh和softmax(在输出层中)
意味着不同的成本函数。
这样就可以理解,RLU(在输出层中)与交叉熵代价函数不匹配。
我将尝试一个简单的平方误差成本函数来测试RLU输出层。

RLU的真正功能在于深层网络的隐藏层,因为它不会遭受梯度消失误差的困扰。

关于matlab - 反向传播用于校正带有交叉熵误差的线性单元,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/24351206/

10-12 20:00