Pr1*_*mer 7 matlab machine-learning backpropagation neural-network
我正在尝试使用反向传播实现神经网络的梯度计算.我无法使用交叉熵误差和纠正线性单位(ReLU)作为激活.
我设法通过sigmoid,tanh和ReLU激活函数使我的实现工作为平方错误.正确计算具有S形激活梯度的交叉熵(CE)误差.但是,当我将激活更改为ReLU时 - 它失败了.(我正在为CE跳过tanh,因为它在(-1,1)范围内抽取值.)
是否因为log函数的行为接近于0(ReLU在归一化输入时约为50%的时间返回)?我试图通过以下方式解决这个问题:
log(max(y,eps))
Run Code Online (Sandbox Code Playgroud)
但它只能帮助将误差和渐变带回实数 - 它们仍然与数值梯度不同.
我使用数值梯度验证结果:
num_grad = (f(W+epsilon) - f(W-epsilon)) / (2*epsilon)
Run Code Online (Sandbox Code Playgroud)
以下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
Run Code Online (Sandbox Code Playgroud)
编辑
经过另一轮实验,我发现在最后一层使用softmax:
y=bsxfun(@rdivide, exp(z3), sum(exp(z3),2));
Run Code Online (Sandbox Code Playgroud)
和softmax成本函数:
f=-sum(sum(Y.*log(y)));
Run Code Online (Sandbox Code Playgroud)
使实现适用于所有激活功能,包括ReLU.
这使我得出结论,后勤成本函数(二元分类器)不适用于ReLU:
f=-sum(sum( Y.*log(max(y,eps))+(1-Y).*log(max(1-y,eps)) ));
Run Code Online (Sandbox Code Playgroud)
但是,我仍然无法弄清问题所在.
小智 0
如果您使用梯度下降,则需要导出稍后在反向传播方法中使用的激活函数。您确定“df=double(z>0)”吗?对于后勤和 tanh 似乎是正确的。
此外,您确定这个 'd3=yY' 吗?我想说,当您使用逻辑函数时,这是正确的,但对于 ReLu 则不然(导数不同,因此不会得出那个简单的方程)。
您可以使用 softplus 函数,它是 ReLU 的平滑版本,其导数是众所周知的(逻辑函数)。