我试图用ANN来近似一个函数(单输入单输出)。使用MATLAB工具箱,我可以看到在隐藏层中有5个或更多的神经元,我可以达到一个非常好的结果。因此,我尝试手动完成此操作。
计算:由于网络只有一个输入和一个输出,相对于连接隐藏神经元j和输出神经元的权重的误差的偏导数(e=d-o,其中'd‘是期望输出,'o’是实际输出)将是-hj (其中hj是隐藏神经元j的输出);误差相对于输出偏置的偏导数将是-1;关于将输入连接到隐藏神经元j的权重的误差的偏导数将是- woj * f‘*i,其中woj是隐藏神经元j的输出权重,f’是tanh()导数,'i‘是输入值;最后,关于隐藏层偏差的误差的偏导数将与上面相同(关于输入权重),除了这里我们没有输入:-woj*f’
问题是: MATLAB算法总是收敛得更快更好。我可以实现与MATLAB相同的曲线,但我的算法需要更多的历元。我试着从MATLAB算法中删除预处理函数和后处理函数。它仍然收敛得更快。我还尝试创建和配置网络,并在训练前提取权重/偏差值,以便将它们复制到我的算法中,看看它是否更快地收敛,但没有任何变化(创建/配置或训练功能中的权重/偏差初始化?)。
MATLAB算法是否在代码中进行了某种优化?或者,这种差异可能只是在训练集的组织和权重/偏差初始化方面?
如果有人想看我的代码,下面是进行训练的主循环:
Err2 = N;
epochs = 0;
%compare MSE of error2
while ((Err2/N > 0.0003) && (u < 10000000) && (epochs < 100))
epochs = epochs+1;
Err = 0;
%input->hidden weight vector
wh = w(1:hidden_layer_len);
%hidden->output weigth vector
wo = w((hidden_layer_len+1):(2*hidden_layer_len));
%hidden bias
bi = w((2*hidden_layer_len+1):(3*hidden_layer_len));
%output bias
bo = w(length(w));
%start forward propagation
for i=1:N
%take next input value
x = t(i);
%propagate to hidden layer
neth = x*wh + bi;
%propagate through neurons
ij = tanh(neth)';
%propagate to output layer
neto = ij*wo + bo;
%propagate to output (purelin)
output(i) = neto;
%calculate difference from target (error)
error(i) = yp(i) - output(i);
%Backpropagation:
%tanh derivative
fhd = 1 - tanh(neth').*tanh(neth');
%jacobian matrix
J(i,:) = [-x*wo'.*fhd -ij -wo'.*fhd -1];
%SSE (sum square error)
Err = Err + 0.5*error(i)*error(i);
end
%calculate next error with updated weights and compare with old error
%start error2 from error1 + 1 to enter while loop
Err2 = Err+1;
%while error2 is > than old error and Mu (u) is not too large
while ((Err2 > Err) && (u < 10000000))
%Weight update
w2 = w - (((J'*J + u*eye(3*hidden_layer_len+1))^-1)*J')*error';
%New Error calculation
%New weights to propagate
wh = w2(1:hidden_layer_len);
wo = w2((hidden_layer_len+1):(2*hidden_layer_len));
%new bias to propagate
bi = w2((2*hidden_layer_len+1):(3*hidden_layer_len));
bo = w2(length(w));
%calculate error2
Err2 = 0;
for i=1:N
%forward propagation again
x = t(i);
neth = x*wh + bi;
ij = tanh(neth)';
neto = ij*wo + bo;
output(i) = neto;
error2(i) = yp(i) - output(i);
%Error2 (SSE)
Err2 = Err2 + 0.5*error2(i)*error2(i);
end
%compare MSE from error2 with a minimum
%if greater still runing
if (Err2/N > 0.0003)
%compare with old error
if (Err2 <= Err)
%if less, update weights and decrease Mu (u)
w = w2;
u = u/10;
else
%if greater, increment Mu (u)
u = u*10;
end
end
end
end发布于 2014-08-27 07:31:10
要知道Levenberg Marquardt算法在Matlab中的具体实现并不容易。您可以尝试一次一个迭代地运行该算法,并查看它是否与您的算法相同。您还可以尝试其他实现,例如http://www.mathworks.com/matlabcentral/fileexchange/16063-lmfsolve-m--levenberg-marquardt-fletcher-algorithm-for-nonlinear-least-squares-problems,看看是否可以提高性能。对于简单的学习问题,收敛速度可能与学习率有关。您可以简单地增加学习率以获得更快的收敛速度。
https://stackoverflow.com/questions/25516463
复制相似问题