2.4. Описание основных модулей программы.
Разрабатываемая программа должная выполнять следящие функции:
Добавления, удаления, редактирования турнирной таблицы и информации той или иной команды в отдельности;
Просмотр турнирной таблицы и результата каждого матча той или иной команды в отдельности;
Добавления нового матча, выбор скорости обучения и числа проходов;
Обучения двухслойного персептрона с алгоритмом обратного распространения ошибки;
Прогнозирования результатов того или иного хоккейного матча;
Добавления с играного матча в БД с правильным результатом игры.
Обучения двухслойного персептрона с алгоритмом обратного распространения ошибки реализовано следующим образом:
procedure TFormMain.Learn;
var i,j,i0,i1,i2,l: Longint;
tmp: Real;
begin
temp:= StrToFloat(LabeledEditSpeed.Text);//скорость
//Задаем случайные веса;
for i0:= 1 to k0 do
for i1:= 0 to k1 do
W1[i0, i1]:= (random(100)-50)/1000;
for i1:= 0 to k1 do
for i2:= 0 to k2 do
W2[i1, i2]:= (random(100)-50)/2000;
l:= StrToInt(LabeledEditLearnCount.Text);//кол-во проходов
//обучение сети:
for i:= 1 to l do begin
j:= random(mCount)+1;//выбираем случайный образец
for i0:= 1 to k0 do
X[i0]:= Ims[j, i0];//формируем входной вектор
for i2:= 0 to k2 do//формируем выходной вектор
if(i2 = NetOuts[j]) then
T[i2]:= 1
else T[i2]:= 0;
NeuronOuts;//получаем выход нейронной сети в Y
if(NetOuts[j] <> d) then begin//если не совпадает с парвильным, то изменяем веса:
//Расчитываем ошибку выходного слоя
for i2:= 0 to k2 do
B2[i2]:= Y2[i2]*(1 - Y2[i2])*(T[i2] - Y2[i2]);
// Расчитываем ошибку входного слоя
for i1:= 0 to k1 do begin
tmp:= 0;
for i2:= 0 to k2 do
tmp:= tmp + B2[i2]*W2[i1, i2];
B1[i1]:= Y1[i1]*(1 - Y1[i1])*tmp;
end;
//Изменяем веса 1-го слоя
for i0:= 1 to k0 do
for i1:= 0 to k1 do
W1[i0, i1]:= W1[i0, i1] + temp*B1[i1]*X[i0];
//Изменение веса 2-го слоя
for i1:= 0 to k1 do
for i2:= 0 to k2 do
W2[i1, i2]:= W2[i1, i2] + temp*B2[i2]*Y1[i1];
end;
end;
//считаем кол-во обученных образцов:
i:= 0;
for j:= 1 to mCount do begin
for i0:= 1 to k0 do
X[i0]:= Ims[j, i0];
NeuronOuts;
if(NetOuts[j] = d) then inc(i);
end;
LabelResult.Caption:= IntToStr(i)+'/'+IntToStr(mCount);//выводим их в надпись на форме
end;
procedure TFormMain.FormNet;
var i,j,O,G,Oi,Gi: Longint;
TCodes: array[1..MAX_TEAMS] of Integer;//коды команд в таблице
begin
with DM.ADOTableTeams do begin
First;
tCount:= 0;//кол-во команд
while not Eof do begin
inc(tCount);
TCodes[tCount]:= FieldByName('Code').AsInteger;//коды команд
Next;
end;
end;
for i:= 1 to tCount do begin//по всем командам
for j:= 1 to LAST_MATCHES do begin//предварительно зануляем голы по последним матчам:
LastGoals[i,1,j]:= 0;
LastGoals[i,2,j]:= 0;
end;
for j:= 1 to 3 do//зануляем статистику команд:
TMs[i,j]:= 0;
end;
with DM.ADOTableAllMatches do begin
i:= 0;//счетчик матчей
Active:= True;
First;
while not Eof do begin//по всем состоявшимся матчам:
//коды хозяев и гостей:
OCode:= FieldByName('OwnerTeam').AsInteger;
GCode:= FieldByName('GuestTeam').AsInteger;
//номера в таблице:
Oi:= 1;
while(TCodes[Oi] <> OCode) do inc(Oi);
Gi:= 1;
while(TCodes[Gi] <> GCode) do inc(Gi);
//забитые голы:
O:= FieldByName('OwnerGoals').AsInteger;
G:= FieldByName('GuestGoals').AsInteger;
//добавляем отдельный обучающий набор для хозяев:
inc(i);
for j:= 1 to LAST_MATCHES do begin//записываем результаты последних 5-ти матчей команды и соперника:
Ims[i, j]:= LastGoals[ Oi, 1, j];
Ims[i, j+LAST_MATCHES]:= LastGoals[ Oi, 2, j];
Ims[i, j+2*LAST_MATCHES]:= LastGoals[ Gi, 1, j];
Ims[i, j+3*LAST_MATCHES]:= LastGoals[ Gi, 2, j];
end;
for j:= 1 to 3 do begin//добавляем статистику команды и ее соперника в турнире:
Ims[i, j+4*LAST_MATCHES]:= TMs[ Oi, j];
Ims[i, j+4*LAST_MATCHES+3]:= TMs[ Gi, j];
end;
Ims[i, k0]:= OWNER_MATCH_FACTOR;//на своем поле
NetOuts[i]:= O;//выход сети - номер нейрона (число забитых голов)
//аналогично добавляем отдельный обучающий набор для гостей:
inc(i);
for j:= 1 to LAST_MATCHES do begin
Ims[i, j]:= LastGoals[ Gi, 1, j];
Ims[i, j+LAST_MATCHES]:= LastGoals[ Gi, 2, j];
Ims[i, j+2*LAST_MATCHES]:= LastGoals[ Oi, 1, j];
Ims[i, j+3*LAST_MATCHES]:= LastGoals[ Oi, 2, j];
end;
for j:= 1 to 3 do begin
Ims[i, j+4*LAST_MATCHES]:= TMs[ Gi, j];
Ims[i, j+4*LAST_MATCHES+3]:= TMs[ Oi, j];
end;
Ims[i, k0]:= 0;//на чужом поле
NetOuts[i]:= G;
for j:= 1 to LAST_MATCHES-1 do begin//смещаем забитые голы на один матч:
LastGoals[ Gi, 1, j]:= LastGoals[ Gi, 1, j+1];
LastGoals[ Oi, 1, j]:= LastGoals[ Oi, 1, j+1];
LastGoals[ Gi, 2, j]:= LastGoals[ Gi, 2, j+1];
LastGoals[ Oi, 2, j]:= LastGoals[ Oi, 2, j+1];
end;
//и добавляем результаты последнего (текущего) для обучающих наборов будущих игр:
LastGoals[ Gi, 1, LAST_MATCHES]:= G;//забитые командой:
LastGoals[ Oi, 1, LAST_MATCHES]:= O;
LastGoals[ Gi, 2, LAST_MATCHES]:= O;//забитые команде соперниками:
LastGoals[ Oi, 2, LAST_MATCHES]:= G;
//добавляем результаты матча в текущую статистику команд:
if(O>G) then begin//победа хозяев:
TMs[ Oi, 1]:= TMs[ Oi, 1]+1;
TMs[ Gi, 3]:= TMs[ Gi, 3]+1;
end
else if(O=G) then begin//ничья:
TMs[ Oi, 2]:= TMs[ Oi, 2]+1;
TMs[ Gi, 2]:= TMs[ Gi, 2]+1;
end
else begin//победа гостей:
TMs[ Oi, 3]:= TMs[ Oi, 3]+1;
TMs[ Gi, 1]:= TMs[ Gi, 1]+1;
end;
Next;
end;
end;
mCount:= i;//}
//удаление малоинформативных (первых LAST_MATCHES) матчей:
i:= 1;
while(i <= mCount) do begin
if((Ims[i,L_GOALS2+1]+Ims[i,L_GOALS2+2]+Ims[i,L_GOALS2+3] < LAST_MATCHES)
or (Ims[i,L_GOALS2+4]+Ims[i,L_GOALS2+5]+Ims[i,L_GOALS2+6] < LAST_MATCHES)) then begin
for j:= 1 to k0 do
Ims[i, j]:= Ims[mCount, j];
NetOuts[i]:= NetOuts[mCount];
dec(mCount);
end
else inc(i);
end;//}
if (mCount > 0) then begin
Learn;
ButtonCalculate.Enabled:= True;
end
else ShowMessage('Нельзя обучить нейронную сеть: недостаточно сыгранных матчей у команд!');
end;
Прогнозирования результатов того или иного хоккейного матча осуществляется следующим образом:
procedure TFormMain.Prognosis;
var i,j,O,G: Longint;
Ims:array[1..2,1..k0] of real;
Outs: array[1..MAX_MATCHES] of Integer;
LastGoals: array[1..2,1..2,0..LAST_MATCHES+1] of Integer;
OwnerS,GuestS: String;
begin
with DM.ADOTableNewMatches do begin
First;
while not Eof do begin//прогнозы для всех новых матчей:
OwnerS:= FieldByName('OwnerTeam').AsString;
GuestS:= FieldByName('GuestTeam').AsString;
//формируем дла входных сигнала - для команды и соперника:
with DM.ADOTableTeamPointsEdit do begin//статистика турнира:
Active:= False;
Filtered:= True;
Filter:= 'Code = '+OwnerS;
Active:= True;
Ims[1, L_GOALS2+1]:= FieldByName('Win').AsInteger;
Ims[1, L_GOALS2+2]:= FieldByName('Draw').AsInteger;
Ims[1, L_GOALS2+3]:= FieldByName('Lost').AsInteger;
Ims[2, L_GOALS2+4]:= FieldByName('Win').AsInteger;
Ims[2, L_GOALS2+5]:= FieldByName('Draw').AsInteger;
Ims[2, L_GOALS2+6]:= FieldByName('Lost').AsInteger;
Active:= False;
Filter:= 'Code = '+GuestS;
Active:= True;
Ims[2, L_GOALS2+1]:= FieldByName('Win').AsInteger;
Ims[2, L_GOALS2+2]:= FieldByName('Draw').AsInteger;
Ims[2, L_GOALS2+3]:= FieldByName('Lost').AsInteger;
Ims[1, L_GOALS2+4]:= FieldByName('Win').AsInteger;
Ims[1, L_GOALS2+5]:= FieldByName('Draw').AsInteger;
Ims[1, L_GOALS2+6]:= FieldByName('Lost').AsInteger;
Active:= False;
end;
Ims[1, k0]:= OWNER_MATCH_FACTOR;
Ims[2, k0]:= 0;
with DM.ADOTableMatches do begin//голы последних матчей:
Active:= False;
Filtered:= True;
Filter:= 'OwnerTeam = '+OwnerS+' OR GuestTeam = '+OwnerS+'';//сначала голы хозяев (в новой игре)
Active:= True;
Last;
j:= LAST_MATCHES;
while(j > 0) do begin
O:= FieldByName('OwnerGoals').AsInteger;
G:= FieldByName('GuestGoals').AsInteger;
if(OwnerS = FieldByName('OwnerTeam').AsString) then begin
LastGoals[1,1,j]:= O;
LastGoals[1,2,j]:= G;
end
else begin
LastGoals[1,2,j]:= O;
LastGoals[1,1,j]:= G;
end;
Prior;
dec(j);
end;
Active:= False;
Filter:= 'OwnerTeam = '+GuestS+' OR GuestTeam = '+GuestS+'';//голы гостей (забитые и пропущенные)
Active:= True;
Last;
j:= LAST_MATCHES;
while(j > 0) do begin
O:= FieldByName('OwnerGoals').AsInteger;
G:= FieldByName('GuestGoals').AsInteger;
if(GuestS = FieldByName('OwnerTeam').AsString) then begin
LastGoals[2,1,j]:= O;
LastGoals[2,2,j]:= G;
end
else begin
LastGoals[2,2,j]:= O;
LastGoals[2,1,j]:= G;
end;
Prior;
dec(j);
end;
Active:= False;
end;
for j:= 1 to LAST_MATCHES do begin//заносим голы во входные образцы:
Ims[1, j]:= LastGoals[1,1,j];
Ims[1, j+LAST_MATCHES]:= LastGoals[1,2,j];
Ims[2, j]:= LastGoals[2,1,j];
Ims[2, j+LAST_MATCHES]:= LastGoals[2,2,j];
Ims[2, j+2*LAST_MATCHES]:= LastGoals[1,1,j];
Ims[2, j+3*LAST_MATCHES]:= LastGoals[1,2,j];
Ims[1, j+2*LAST_MATCHES]:= LastGoals[2,1,j];
Ims[1, j+3*LAST_MATCHES]:= LastGoals[2,2,j];
end;
Edit;
//расчитываем голы хозяев:
for j:= 1 to k0 do
X[j]:= Ims[1, j];
NeuronOuts;
FieldByName('OwnerGoals').AsInteger:= d;
//расчитываем голы гостей:
for j:= 1 to k0 do
X[j]:= Ims[2, j];
NeuronOuts;
FieldByName('GuestGoals').AsInteger:= d;
Post;
Next;
end;
end;
- Курсовой проект на тему:
- Содержание.
- Введение.
- 1. Исследовательская часть.
- 1.1. Исследования предметной области.
- 1.1.1. Многослойный персептрон.
- 1.1.2. Обучение методом обратного распространения ошибок.
- 1.2. Постановка задачи.
- 2. Конструкторская часть.
- 2.1. Основные этапы разработки.
- 2.2. Проектирование нейронной сети.
- 2.3. Структурная схема двухслойного персептрона с алгоритмом обратного распространения ошибки.
- 2.4. Описание основных модулей программы.
- 2.5. Проектирование графического интерфейса разрабатываемого по.
- 3. Технологическая часть.
- Список литературы.