Techniczne zastosowanie sieci neuronowych
PROJEKT II
Ernest Rogowski
Temat: Zaimplementować sieć neuronową MLP, która ma umożliwić poprawne rozpoznanie zadanego wzorca. Dobrać odpowiednią funkcję aktywacji, oraz strukturę sieci.
Dane: Znak do rozpoznania - 6
1. Teoria
1.1. Struktura sieci
Struktura sieci jest następująca 70->7->1, co oznacza 70 wejść, 7 neuronów w warstwie ukrytej, 1 neuron na wyjściu.
1.2. Funkcja aktywacji
Zastosowano funkcję sigmoidalną unipolarną:
Parametr Beta wynosi 1.
1.3. Metoda uczenia
Zastosowałem do uczenia sieci algorytm wstecznej propagacji błędu, który jest jednym z najczęściej stosowanych, a jego zaimplementowanie jest stosunkowo łatwe.
Algorytm ten sprowadza wartość błędu sieci poniżej pewnemu założonemu progowi. Jako miarę błędu zastosowałem błąd średniokwadratowy na neuronie wyjściowym. Jako próg błędu podałem wartość mniejszą niż 0,05.
2. Wykonanie projektu
2.1. Interfejs
Po uruchomianiu programu ukazuje się okno przedstawione poniżej.
2.2. Nauczanie sieci
Po kliknięciu przycisku „Naucz” sieć zostanie nauczona. Do uczenia sieci używany jest plik `wzorce.txt' zapisany w folderze razem z projektem. W pliku tym zapisane są wzorce do nauki sieci, np.:
0111110100000110000001000000111111010000011000001100000110000010111110
1
0100000001000000010110000101000101100100010100001100000111111110000010
0
1111111100000010000001000000100000011111111000001100000110000011111111
1
Ciąg 70-ciu znaków binarnych w jednej linii odpowiada znakom na wejściu sieci, a znajdująca się pod nim cyfra odpowiada wynikowi jaki powinien być dla tego wejścia, odpowiednio 1 dla wzorca poprawnego, 0- niepoprawnego.
Znaki odpowiadające wejściu są przypisywane do tablicy tab_wzor[q,i], a wynik do tablicy T[q].
Jako, że wagi są losowane po uruchomieniu programu w trakcie uczenia sieci nie jest to konieczne.
Następnie, sieć przetwarza wejścia za pomocą wag i funkcji aktywacji oraz wykonuje uczenie czyli propagacje wstecz i poprawianie wag dopóki błąd nie jest mniejszy o zadanego, obrazuje to poniższy kod:
Ew:=1;
while Ew>0.05 do begin
Ew := 0;
for q:= 1 to P do begin
Y[q]:=0;
for i:=0 to 6 do
neur[i]:=0;
for j:=0 to 6 do begin
for i:=0 to 69 do begin
neur[j]:=neur[j]+wagi1[i,j]*tab_wzor[q,i];
end;
neur[j]:=neur[j]*(-1); //funkcja sigmoidalna dla warstwy ukrytej
neur[j]:= Power(e,neur[j]);
neur[j]:= 1/(1+neur[j]);
Y[q]:=Y[q]+ neur[j]* wagi2[j]; //obliczanie wyjscia
end;
Y[q]:= Y[q]*(-1); //funkcja sigmoidalna dla warstwy ukrytej
Y[q]:= Power(e,Y[q]);
Y[q]:= 1/(1+Y[q]);
Ewt:=Y[q]-T[q];
si:=Ewt*(Y[q]*(1-Y[q]));
for i:=0 to 6 do begin //propagacja wstecz
Et[i]:=si*wagi2[i];
tab_si[i]:=Et[i]*(neur[i]*(1-neur[i]));
end;
for i:=0 to 6 do begin //poprawienie wag
for j:=0 to 69 do
wagi1[j,i]:=wagi1[j,i]+(-1)*e*tab_si[i]*tab_wzor[q,j];
wagi2[i]:=wagi2[i]+(-1)*e*si*neur[i];
end;
Ew:=Ew+((Ewt*Ewt)/P);
end;
end;
Dla poprawienia wyników proces całego uczenia zaimplementowałem tak aby sieć uczyła się 5 razy. Nie zmienia to czasu wykonania uczenia, a wyniki są nieco lepsze.
2.3. Czyszczenie tablicy
Przyciski „Wyczysc” powoduje wyczyszczenie DrawGrid oraz tablicy wejścia.
2.4. Rozpoznawanie
Aby rozpoznać jakąś wartość należy ją wprowadzić w pola DrawGrida, klikając na odpowiednie komórki tego komponentu. Wszystkie kliknięcia są zapisywane do tablicy wejść (wej[i]). Następnie sieć wykonuje ciąg zadań, aby podać wynik wyjścia sieci, oto kod:
for i:=0 to 6 do
neur[i]:=0;
WYNIK:=0;
for j:=0 to 6 do begin
for i:=0 to 69 do begin
neur[j]:=neur[j]+wagi1[i,j]*wej[i];
end;
neur[j]:=neur[j]*(-1); //funkcja sigmoidalna dla warstwy ukrytej
neur[j]:= Power(e,neur[j]);
neur[j]:= 1/(1+neur[j]);
WYNIK:=WYNIK+ neur[j]* wagi2[j]; //obliczanie wyjscia
end;
WYNIK:= WYNIK*(-1); //funkcja sigmoidalna dla warstwy ukrytej
WYNIK:= Power(e,WYNIK);
WYNIK:= 1/(1+WYNIK);
Następnie `WYNIK' jest powiększany 100 razy i zaokrąglany do wartości całkowitych i jeżeli jest większy lub równy 80 zostaje przedstawiony następująco:
Jeżeli natomiast `WYNIK' zawiera się między 60 a 80 to następująco zostaje przedstawiony:
Każdy wartość poniżej 60 jest pokazana następująco:
2.5. Zapisywanie wzorców
Ta część okna programu:
odpowiada za dodawanie wzorców do pliku `wzorce.txt'. Aby dodać wzorzec należy wybrać jedną z opcji dodania, oznaczają one kolejno wzorce poprawne i niepoprawne.
UWAGA!
W pliku tekstowym może być maksymalnie 10 wszystkich wzorców. Oczywiście można to łatwo zmienić, jednak tyle wzorców zdecydowanie wystarczy.
Ważne jest również aby w pliku tym znajdowały się zarówno wzorce poprawne jak i niepoprawne, zdecydowanie poprawia to nauczanie sieci.