Здравствуйте !
Написал программу на дельфи которая позволила бы распознавать цифры...
Не могу толково отладить, постоянно при прогоне получаю странные
данные на выходе после применения алгоритма обратного распространения
ошибок. Скидываю главную процедуру алгоритма... Там думаю все понятно... я писал сам
алгоритм с комментариями. Значится, сеть сама архитектуры 64-6-9 (64
входы - от символьной матрицы, 6 нейроной скрытого слоя и 9 выходных )
Если надо, скину весь исходник. Но думаю, что я тут где-то в самом алгоритме ошибся...
Вот структуры данных использованные мною :
x:array[1..64] of integer; - входные сигналы
net1:array[1..6] of real; - комбинированный ввод1
net2:array[1..9] of real; - комбинированный ввод
o1:array[1..6] of real; - вывод1
o2:array[1..9] of real; - вывод1
w1:array[1..64,1..6] of real; - весы1
w2:array[1..6,1..9] of real; - вывод2
dw1,dw1_prev:array[1..64,1..6] of real; - дельты (изменения ) для весов
dw2,dw2_prev:array[1..6,1..9] of real; - дельты (изменения ) для весов 2
t:array[1..9] of integer; - требуемый выход
d1:array[1..6] of real; - а это сами дельты (ошибки)
d2:array[1..9] of real; - а это сами дельты (ошибки)
procedure TForm3.Button1Click(Sender: TObject);
var done:boolean;
i,j,h:integer;
sum,err:real;
counter:integer;
begin
init;
done:=false;
counter:=0;
while not done do begin
done:=true;
inc(counter);
if counter=3 then break;
for i:=1 to listbox1.items.Count do begin
ReadNextFile(i-1);
// сначала делаем прямой проход...
// вычисляем комбинированный ввод и вывод для скрытого слоя
for h:=1 to 6 do begin
sum:=0;
for j:=1 to 64 do begin
sum:=sum+x[j]*w1[j,h];
end;
net1[h]:=sum;
o1[h]:=1/(1+exp(-sum));
end;
// вычисляем комбинированный ввод и вывод для выходного слоя
for h:=1 to 9 do begin
sum:=0;
for j:=1 to 6 do begin
sum:=sum+o1[j]*w2[j,h];
end;
net2[h]:=sum;
o2[h]:=1/(1+exp(-sum));
end;
// сравниваем полученный вывод выходного слоя с требуемыми значениями
for h:=1 to 9 do begin
err:=t[h]-o2[h];
if abs(err)>(0.1*abs(t[h])) then done:=false;
end;
// начинаем обратный проход...
// вычисляем ошибку для каждого элемента выходного слоя
for h:=1 to 9 do
d2[h]:=(t[h]-o2[h])*o2[h]*(1-o2[h]);
// вычисляем ошибку для каждого элемента скрытого слоя
for h:=1 to 6 do begin
sum:=0;
for j:=1 to 9 do
sum:=sum+d2[j]*w2[h,j];
d1[h]:=o1[h]*(1-o1[h])*sum;
end;
// обновляем значения весов...сначала находим все дельты весов
for h:=1 to 64 do begin
for j:=1 to 6 do
dw1[h,j]:=n*d1[j]*x[h]+a*dw1[h,j];
end;
for h:=1 to 6 do begin
for j:=1 to 9 do
dw2[h,j]:=n*d2[j]*o1[h]+a*dw2[h,j];
end;
// а потом собственно и сами весы обновляем
for h:=1 to 64 do begin
for j:=1 to 6 do
w1[h,j]:=w1[h,j]+dw1[h,j];
end;
for h:=1 to 6 do begin
for j:=1 to 9 do
w2[h,j]:=w2[h,j]+dw2[h,j];
end;
end;
end;
WriteToFile;
end;