Лекция: Глава 7. Панели инструментов и меню MPLAB IDE
Індивідуальне завдання:
1. Розробити структуру елементарного персептрона, що здатний розпізнавати дві букви. При цьому обґрунтуйте вибір:
— кількості рецепторних нейронів
— кількості нейронів схованого шару
— розміру кроку в алгоритмі навчання персептрона
— вигляду функцій активації нейронів кожного шару
— розміру порогів нейронів кожного шару.
2. Навчіть нейронну мережу методом a- підкріплень та методом g-підкріплень. Порівняти роботу обох методів.
Робота з програмою:
1.
Для початку роботи необхідно запустити файл Project1_perc.exe
Вікно програми на початку роботи має вигляд:
2.Відразу треба визначити як персептрон повинен реагувати на кожне з еталонних зображень:
Якщо обрати перший (як зазначено на малюнку), то високий рівень вихідного сигналу буде ставитись у відповідність до першого еталонного зображення; якщо обрати другий – до другого.
3.Необхідно визначити еталонні зображення (тобто символи, на розпізнавання яких потрібно настроїти персептрон).
Вибрати еталони можна двома засобами:
— кликаючи лівою кнопкою миші зобразити еталони на спеціальних полях:
—
4.
Заповнення матриці може зайняти деякий час, оскільки вона заповнюється кілька разів, поки отримані значення не даватимуть більш-менше однакову кількість активних нейронів для обох символів.
При повторному натисканні кнопки процес повторюється і результати заповнення змінюються.
Про порог, з допомогою якого можна з’ясувати чи активний нейрон повідомляється в окремій матриці:
5.
6.
7.Після настройки можна провести тестування роботи персептрона: розпізнавання символа. Символ задається на спеціальному полі, під яким є кнопка активації процесу ідентифікації символа:
8.Можна ідентифікувати кілька символів. Перераховувати матриці зв’язків при цьому не треба.
9.Якщо є необхідність змінити еталонні зображення, це можна зробити використовуючи мишу. Але розпізнання в цьому випадку потребує перерахування матриці зв’язків і нової підстройки персептрона.
Текст програми:
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include<stdlib.h>
#include «Unit1_perc.h»
#include «About.h»
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
int M_2[6][5]={{1,0,0,0,1}, {0,1,0,1,0}, {0,0,1,0,0},
{0,0,1,0,0}, {0,1,0,1,0}, {1,0,0,0,1}};
int M_1[6][5]={{0,1,1,1,0}, {1,0,0,0,1}, {1,0,0,0,1},
{1,0,0,0,1}, {1,0,0,0,1}, {0,1,1,1,0}};
float M3[7][30];
int M1[6][5],M2[6][5];
float U1[8],U2[8];
float Sum1=0, Sum2=0;
float e1,e2;
float Ves_for_R[8];
float Unc[6][5];
float V_r[8];
float porog=0;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormCreate(TObject *Sender)
{
StringGrid3->Cells[0][1]=«A1»;StringGrid3->Cells[0][2]=«A2»;
StringGrid3->Cells[0][3]=«A3»;StringGrid3->Cells[0][4]=«A4»;
StringGrid3->Cells[0][5]=«A5»;StringGrid3->Cells[0][6]=«A6»;
StringGrid3->Cells[0][7]=«A7»;
for(int i=1; i<31; i++)
StringGrid3->Cells[i][0]=i;
StringGrid6->Cells[0][1]=«W1»;StringGrid6->Cells[0][2]=«W2»;
StringGrid6->Cells[0][3]=«W3»;StringGrid6->Cells[0][4]=«W4»;
StringGrid6->Cells[0][5]=«W5»;StringGrid6->Cells[0][6]=«W6»;
StringGrid6->Cells[0][7]=«W7»;StringGrid6->Cells[0][8]="--";
StringGrid6->Cells[0][9]=«Uвх1»;StringGrid6->Cells[0][10]=«Uвх2»;
StringGrid5->Cells[0][1]=«Wi»;StringGrid5->Cells[1][0]=«A1»;
StringGrid5->Cells[2][0]=«A2»;StringGrid5->Cells[3][0]=«A3»;
StringGrid5->Cells[4][0]=«A4»;StringGrid5->Cells[5][0]=«A5»;
StringGrid5->Cells[6][0]=«A6»;StringGrid5->Cells[7][0]=«A7»;
StringGrid4->Cells[1][0]=«UвA1»;StringGrid4->Cells[2][0]=«UвA2»;
StringGrid4->Cells[3][0]=«UвA3»;StringGrid4->Cells[4][0]=«UвA4»;
StringGrid4->Cells[5][0]=«UвA5»;StringGrid4->Cells[6][0]=«UвA6»;
StringGrid4->Cells[7][0]=«UвA7»;
StringGrid4->Cells[0][1]=«1»;StringGrid4->Cells[0][2]=«2»;
for(int i=0; i<5; i++)
for(int j=0; j<6; j++)
{
Unc[i][j]=0;
M1[i][j]=M2[i][j]=0;
}
}
//---------------------------------------------------------------------------
void __fastcall TForm1::N2Click(TObject *Sender)
{
StringGrid1->Color = clInactiveCaption; StringGrid2->Color = clInactiveCaption;
//эталоны по умолчанию
for(int i=0; i<6; i++)
for(int j=0; j<5; j++)
{
M1[i][j] = M_1[i][j]; M2[i][j] = M_2[i][j];
}
for(int i=1; i<6; i++)
for(int j=1; j<7; j++)
{
if(M2[j-1][i-1]==1) StringGrid2->Cells[i][j]="$";
else StringGrid2->Cells[i][j]="";
if(M1[j-1][i-1]==1) StringGrid1->Cells[i][j]="$";
else StringGrid1->Cells[i][j]="";
}
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
StringGrid1->Color = clInactiveCaption; StringGrid2->Color = clInactiveCaption;
// Гамма-подстройка
//количество активных связей для каждого изображения
int K_A1=0;int K_A2=0;
for(int i=0; i<8; i++)
{
if(U1[i]>0) K_A1++;
if(U2[i]>0) K_A2++;
}
//расчет приращений для 1-го и 2-го
float w1_a, w1_p;
float w2_a, w2_p;
w1_a = 2*(0.1-(K_A1*0.1)/7); Edit1->Text = w1_a;
w2_a = 2*(0.1-(K_A2*0.1)/7); Edit2->Text = w2_a;
w1_p = 2*(-(K_A1*0.1)/7); Edit3->Text = w1_p;
w2_p = 2*(-(K_A2*0.1)/7); Edit4->Text = w2_p;
Edit1->Visible = true; Edit2->Visible = true; Edit3->Visible = true; Edit4->Visible = true;
for(int i=2; i<40; i++)
for(int j=1; j<15; j++)
StringGrid6->Cells[i][j]="";
for(int i=1; i<8; i++)
StringGrid6->Cells[1][i]=Ves_for_R[i];
// Гамма-подстройка
float temp;
for(int i=1; i<8; i++)
V_r[i]=Ves_for_R[i];
int i=0, z=0;
if(RadioButton1->Checked==true)
{ Sum1=0;Sum2=10;
while(Sum1-Sum2<1)
{//2
i++;z++;
if(i>90)break;
while(z>1)
z=z-2;
if(z>0)
{//3
Sum1=0;
for(int j=1; j<8; j++)
{//4
if(U1[j]==1) V_r[j] = V_r[j]+w1_a;
else V_r[j] = V_r[j]+w1_p;
if(V_r[j]>=1) V_r[j]=1;
if(V_r[j]<0) V_r[j]=0;
Sum1 = Sum1+(V_r[j]*U1[j]);
StringGrid6->Cells[i+1][j]=V_r[j];
} //4
StringGrid6->Cells[i+1][9]= Sum1;
} //3
else//((i==2)||(i==4)||(i==6)||(i==8))
{//5
Sum2=0;
for(int j=1; j<8; j++)
{//6
if(U2[j]==1) V_r[j] = V_r[j]-w2_a;
else V_r[j] = V_r[j]-w2_p;
if(V_r[j]>=1) V_r[j]=1;
if(V_r[j]<0) V_r[j]=0;
Sum2 = Sum2+(V_r[j]*U2[j]);
StringGrid6->Cells[i+1][j]=V_r[j];
}//6
if(Sum2<0.01)Sum2=0;
StringGrid6->Cells[i+1][10]= Sum2;
} //5
} //2
}//1
else
{Sum2=0;Sum1=10;
while(Sum2-Sum1<1)
{
i++;z++;
if(i>90)break;
while(z>1)
z=z-2;
if(z>0)
{
Sum1=0;
for(int j=1; j<8; j++)
{
if(U1[j]==1) V_r[j] = V_r[j]-w1_a;
else V_r[j] = V_r[j]-w1_p;
if(V_r[j]>=1) V_r[j]=1;
if(V_r[j]<0) V_r[j]=0;
Sum1 = Sum1+(V_r[j]*U1[j]);
StringGrid6->Cells[i+1][j]=V_r[j];
}
StringGrid6->Cells[i+1][9]= Sum1;
}
else//((i==2)||(i==4)||(i==6)||(i==8))
{
Sum2=0;
for(int j=1; j<8; j++)
{
if(U2[j]==1) V_r[j] = V_r[j]+w2_a;
else V_r[j] = V_r[j]+w2_p;
if(V_r[j]>=1) V_r[j]=1;
if(V_r[j]<0) V_r[j]=0;
Sum2 = Sum2+(V_r[j]*U2[j]);
StringGrid6->Cells[i+1][j]=V_r[j];
}
if(Sum2<0.01)Sum2=0;
StringGrid6->Cells[i+1][10]= Sum2;
}
}
}// END Гамма-подстройка
}
//---------------------------------------------------------------------------
void __fastcall TForm1::StringGrid7SelectCell(TObject *Sender, int ACol,
int ARow, bool &CanSelect)
{
if(StringGrid7->Cells[ACol][ARow] == "$")
{ StringGrid7->Cells[ACol][ARow] = ""; Unc[ARow-1][ACol-1]= 0; }
else { StringGrid7->Cells[ACol][ARow] = '$'; Unc[ARow-1][ACol-1]= 1; }
}
//---------------------------------------------------------------------------
void __fastcall TForm1::StringGrid2SelectCell(TObject *Sender, int ACol,
int ARow, bool &CanSelect)
{
if(StringGrid2->Cells[ACol][ARow] == "$")
{ StringGrid2->Cells[ACol][ARow] = ""; M2[ARow-1][ACol-1]= 0; }
else { StringGrid2->Cells[ACol][ARow] = "$"; M2[ARow-1][ACol-1]= 1; }
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button2Click(TObject *Sender)
{
//идентификация символа
int k=0;
int Dop_mas[30],Dop_mas2[30];
for(int i=0; i<6; i++)
for(int j=0; j<5; j++)
{ Dop_mas[k]=M1[i][j]; Dop_mas2[k]=M2[i][j]; k++; }
for(int j=0; j<7; j++)
{
U1[j]=0; U2[j]=0;
for(int i=0; i<30; i++)
{
U1[j] = U1[j]+(Dop_mas[i]*M3[j][i]); U2[j] = U2[j]+(Dop_mas2[i]*M3[j][i]);
}
}
Sum1 = Sum2 = 0;
for(int i=0; i<7; i++)
{ Sum1 += U1[i]*V_r[i]; Sum2 += U2[i]*V_r[i]; }
int qq[30];
int q1[30];
k=0;
for(int i=0; i<6; i++)
for(int j=0; j<5; j++)
{ qq[k]=Unc[i][j]; k++; }
float sum[7]={0,0,0,0,0,0,0};
float sum2[7]={0,0,0,0,0,0,0};
for(k=0; k<7; k++)
for(int i=0; i<30; i++)
{
sum[k] = sum[k]+(qq[i]*M3[k][i]); sum2[k] = sum2[k]+(q1[i]*M3[k][i]);
}
float s=0;
for(int i=0; i<7; i++)
{ s += sum[i]*V_r[i]; }
if(RadioButton1->Checked==true)
{
if(s > ((Sum1+Sum2)/2))
{ StringGrid1->Color = clBlue; }
else { StringGrid2->Color = clBlue; }
}
else{
if(s < ((Sum1+Sum2)/2)) { StringGrid1->Color = clBlue; }
else { StringGrid2->Color = clBlue; }
}
}
//---------------------------------------------------------------------------
void __fastcall TForm1::BitBtn1Click(TObject *Sender)
{
for(int i=2; i<40; i++)
for(int j=1; j<15; j++)
StringGrid6->Cells[i][j]="";
// Альфа-подстройка
float temp;
for(int i=1; i<8; i++)
V_r[i]=Ves_for_R[i];
int i=0, z=0;
Sum1=Sum2=0;
if(RadioButton1->Checked==true)
{
//Первый высокий сигнал
while((Sum1-Sum2<1))
{
i++;z++;
if(i>90)break;
while(z>1)
z=z-2;
if(z>0)
{
Sum1=0;
for(int j=1; j<8; j++)
{
if(U1[j]==1)
{ V_r[j] = V_r[j]+0.1; StringGrid6->Cells[i+1][j]=V_r[j]; }
else V_r[j] = V_r[j]-0.1;
if(V_r[j]>=1) V_r[j]=1;
if(V_r[j]<0) V_r[j]=0;
Sum1 = Sum1+(V_r[j]*U1[j]);
}
StringGrid6->Cells[i+1][9]= Sum1;
}
else
{
Sum2=0;
for(int j=1; j<8; j++)
{
if(U2[j]==1) { V_r[j] = V_r[j]-0.1; StringGrid6->Cells[i+1][j]=V_r[j]; }
else V_r[j] = V_r[j]+0.1;
if(V_r[j]>=1) V_r[j]=1;
if(V_r[j]<0) V_r[j]=0;
Sum2 = Sum2+(V_r[j]*U2[j]);
}
if(Sum2<0.01)Sum2=0;
StringGrid6->Cells[i+1][10]= Sum2;
} }}
else
{
//Второй высокий сигнал
while((Sum2-Sum1<1))
{
i++;z++;
if(i>90)break;
while(z>1)
z=z-2;
if(z>0)
{
Sum1=0;
for(int j=1; j<8; j++)
{
if(U1[j]==1) { V_r[j] = V_r[j]-0.1; StringGrid6->Cells[i+1][j]=V_r[j]; }
else V_r[j] = V_r[j]+0.1;
if(V_r[j]>=1) V_r[j]=1;
if(V_r[j]<0) V_r[j]=0;
Sum1 = Sum1+(V_r[j]*U1[j]);
}
StringGrid6->Cells[i+1][9]= Sum1;
}
else
{
Sum2=0;
for(int j=1; j<8; j++)
{
if(U2[j]==1){ V_r[j] = V_r[j]+0.1; StringGrid6->Cells[i+1][j]=V_r[j]; }
else V_r[j] = V_r[j]-0.1;
if(V_r[j]>=1) V_r[j]=1;
if(V_r[j]<0) V_r[j]=0;
Sum2 = Sum2+(V_r[j]*U2[j]);
}
if(Sum2<0.01)Sum2=0;
StringGrid6->Cells[i+1][10]= Sum2;
} }} // END Альфа-подстройка
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button3Click(TObject *Sender)
{
//определение весов связей А-нейронов(случайным образом)
randomize();
int F[7][30];
for(int i=0; i<30; i++)
for(int j=0; j<7; j++)
F[j][i]=0;
int a, b, k=0;
int flagok=0;
int lich1=0, lich2=0;
int r=10;
while((flagok<3)||(lich1<2)||(lich2<2))
{//################################
flagok=0;lich1=0;lich2=0;a=0;b=0;k=0;
if(r>2)r--;
else r=10;
randomize();
while(k<210)
{
if(b<29) b++;
else {a++; b=0;}
M3[a][b] = (float)random(r)/10;
F[a][b]=1; k++;
StringGrid3->Cells[b+1][a+1]=M3[a][b];
} }
//определение порога срабатывания А-нейронов
int k=0;
Sum1=0; Sum2=0;
float Dop_mas[30],Dop_mas2[30];
for(int i=0; i<6; i++)
for(int j=0; j<5; j++)
{ Dop_mas[k]=M1[i][j]; Dop_mas2[k]=M2[i][j]; k++; }
for(int j=0; j<7; j++)
{
U1[j]=0; U2[j]=0;
for(int i=0; i<30; i++)
{ U1[j] = U1[j]+(Dop_mas[i]*M3[j][i]); U2[j] = U2[j]+(Dop_mas2[i]*M3[j][i]); }
StringGrid4->Cells[j+1][1]=U1[j]; StringGrid4->Cells[j+1][2]=U2[j];
Sum1 = Sum1 + U1[j]; Sum2 = Sum2 + U2[j];
}
Sum1 = (Sum1+Sum2)/14; porog = Sum1;
for(int i=0; i<7; i++)
{
if(U1[i]>porog) U1[i]=1;
else U1[i]=0;
if(U2[i]>porog) U2[i]=1;
else U2[i]=0;
}
Label4->Caption = porog;
Label3->Visible = true; Label4->Visible = true;
//проверка
for(int i=0; i<7; i++)
{
if(U1[i]!=U2[i]) { flagok++; }
if(U1[i]>0)lich1++; if(U2[i]>0)lich2++;
}}}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button4Click(TObject *Sender)
{
//определение случайным образом весов связей р-нейрона
Sum1=Sum2=0;
for(int i=1; i<8; i++)
{
Ves_for_R[i]=(float)(random(8)+1)/(float)10;
StringGrid5->Cells[i][1]=Ves_for_R[i]; StringGrid6->Cells[1][i]=Ves_for_R[i];
Sum1 = Sum1+U1[i-1]*Ves_for_R[i]; Sum2 = Sum2+U2[i-1]*Ves_for_R[i];
StringGrid6->Cells[1][9]=Sum1; StringGrid6->Cells[1][10]=Sum2;
}
}
//---------------------------------------------------------------------------
void __fastcall TForm1::N4Click(TObject *Sender)
{ Form1->Close(); }
//---------------------------------------------------------------------------
void __fastcall TForm1::N5Click(TObject *Sender)
{ AboutBox->ShowModal(); }
//---------------------------------------------------------------------------
void __fastcall TForm1::RadioButton2Click(TObject *Sender)
{ RadioButton2->Checked=true;}
//---------------------------------------------------------------------------
void __fastcall TForm1::RadioButton1Click(TObject *Sender)
{ RadioButton1->Checked=true;}
//---------------------------------------------------------------------------
Глава 7. Панели инструментов и меню MPLAB IDE