Я написал следующий скрипт для проблемы XOR с использованием обратного распространения.Может использоваться для двоичных или биполярных входов;однако, это не всегда сходится.Он часто «застревает в локальных минутах», поэтому я предполагаю, что что-то не так с моими расчетами градиентного спуска.Я попытался отладить, но я не могу точно определить проблему.Если у кого-то есть какие-либо идеи, это будет с благодарностью.Спасибо!
%type = 0 for binary and type = -1 for bipolar
type=-1;
npattern=4;
ninput=2;
nhidden=2;
noutput=1;
epochs=0;
MAX_EPOCHS=30000;
tol=5e-2;
%error
err=0.0;
avg_err=0.0;
old_avg_err=2*tol;
delt_err=0.0;
%Learning rate
eta=0.9;
%Momentum constant
alpha=0.2;
%bias
b_in=0.5;
b_hidden=-0.3;
%input row 1 &2 expected output row 3
if (type==0)
%Binary
x=[0 1 0 1; 0 0 1 1; 0 1 1 0];
a=1;
%Bipolar
elseif(type==-1)
x=[-1 1 -1 1; -1 -1 1 1; -1 1 1 -1];
a=1;
else
return
end
tx=transpose(x);
int_s=-0.5;
int_end=0.5;
%weights
w_input= int_s + (int_end - int_s).*rand(ninput,nhidden);
w_out=int_s + (int_end - int_s).*rand(ninput,noutput);
%initialize change in weights
del_w_input=zeros(ninput,nhidden);
del_w_out=zeros(nhidden,noutput);
del_w_input_old=zeros(ninput,nhidden);
del_w_out_old=zeros(nhidden,noutput);
output=zeros(1,npattern);
error=zeros(1,npattern);
v_in=zeros(ninput,npattern);
y_in=zeros(ninput,npattern);
v_out=zeros(noutput,npattern);
y_out=zeros(noutput,npattern);
delta_out=zeros(noutput,npattern);
delta_in=zeros(nhidden,npattern);
converged=0;
%For plotting
epochs_list=[];
error_list=[];
%while epochs<MAX_EPOCHS
while converged ~= 1
epochs=epochs+1;
for n=1:npattern;
%FORWARD
%input to hidden
v_in(:,n) = (w_input * x(1:2,n))+b_in;
for i=1:ninput
y_in(i,n)=activation(v_in(i,n),a,type);
end
%hidden to output
v_out(1,n)=(transpose(w_out)*y_in(:,n))+b_hidden;
y_out(1,n)=activation(v_out(1,n),a,type);
output(1,n)=y_out(1,n);
error(1,n)=x(3,n)-output(1,n);
err=(error(1,n))^2;
avg_err=avg_err+err;
%BACKPOPOGATION
%update weights: output to hidden
t=dactivation(v_out(1,n),a,type);
delta_out(1,n)=error(1,n)*t;
del_w_out_old=del_w_out;
for i=1:nhidden
del_w_out(i,1) = alpha * del_w_out_old(i,1) + eta * delta_out(1,n) * y_in(i,n);
w_out(i,1) = w_out(i,1) + del_w_out(i,1);
end
%update weights: hidden to input
for i=1:nhidden
delta_in(i,n)= delta_out(1,n)*dactivation(v_in(i,n),a,type)*w_out(i,1);
end
del_w_input_old=del_w_input;
del_w_input = alpha * del_w_input_old + eta * (delta_in(:,n) * tx(n,1:2));
w_input = w_input + del_w_input;
end
disp(' ');
disp(x);
disp(output);
disp(error);
x=x(:,randperm(4));
tx=transpose(x);
avg_err=avg_err/npattern;
delt_err=abs(avg_err-old_avg_err);
old_avg_err=avg_err;
error_list(end+1)=avg_err;
epochs_list(end+1)=epochs;
disp('Epochs: ')
disp(epochs)
disp(' ')
disp('Change in Error: ')
disp(delt_err)
avg_err=0;
if all(abs(error)<tol)
converged=1;
end
if (converged==1)
plot(epochs_list, error_list)
end
end
%Functions
function y = activation( x,a,type )
if (type==-1)
y = a*tanh(x);
elseif (type==0)
y=1/(1+exp(-a*x));
else
return
end
end
function y = dactivation( x,a,type )
if (type==-1)
y=a*(sech(x))^2;
elseif (type==0)
sig=activation(x,a,type);
y=a*sig*(1-sig);
else
return
end
end