Techniczne zastosowanie sieci neuronowych
PROJEKT I
Ernest Rogowski
Temat: Zaimplementować sieć neuronową MLP o zadanej strukturze z dwoma różnymi funkcjami aktywacji: liniową (y=ax+b) i sigmoidalną (y=1/(1+e^-βx).
Dane: a=1,1
b=0,5
β=1
ilość neuronów w pierwszej warstwie= 5
ilość neuronów w drugiej warstwie= 5
1. Opis zadania:
Sieć będzie składała się z dwóch wejść oraz jednego wyjścia:
Zadaniem Studenta jest stworzenie aplikacji okienkowej, która umożliwia wybór jednej z podanych funkcji aktywacji oraz umożliwi użytkownikowi zmianę wag przy każdym neuronie.
Aplikacja ma przyjmować na wejściu dane z zadanego zakresu oraz ilustrować zasadę działania sieci graficznie (na układzie współrzędnych zaznaczyć odpowiedź sieci neuronowej).
2. Wykonanie projektu
2.1. Wybieranie funkcji aktywacji
Rysunek 1. Wybieranie funkcji aktywacji
Użytkownik ma do wyboru dwie opcje: 1. Funkcja liniowa; 2. Funkcja sigmoidalna;
Potwierdzenie wybrania funkcji następuje po kliknięciu na przycisk „Ustaw funkcje”.
Czynność ta powoduje również wyczyszczenie i narysowanie układu współrzędnych na polu, na którym jest później rysowany wynik działania aplikacji.
Kod tej procedury jest następujący:
procedure TForm1.Button4Click(Sender: TObject);
begin
Case RadioGroup1.ItemIndex of //Wybieranie funkcji
0: fun:=true;
1: fun:=false;
end;
With Image1 do
begin
picture:=nil; //czyszczenie Image'a
Canvas.MoveTo(150,0); //Rysowanie ukladu wspolrzednych
Canvas.LineTo(150,300);
Canvas.MoveTo(0,150);
Canvas.LineTo(300,150);
end;
end;
Zmienna „fun” jest wykorzystywana dalej do rysowania punktów dla odpowiedniej funkcji:
if fun=true then begin
if (a*x+b)>y then
Image1.Canvas.Pixels[x1,y1]:= clBlue; //Rysowanie punktow
if (a*x+b)<y then //dla funkcji liniowej
Image1.Canvas.Pixels[x1,y1]:= clRed;
end else begin
x:=x*-1;
x:=Power(e,x);
if (1/(1+x))>y then
Image1.Canvas.Pixels[x1,y1]:= clBlue; //Rysowanie punktow
if (1/(1+x))<y then //dla funkcji sigmoidalnej
Image1.Canvas.Pixels[x1,y1]:= clRed;
end;
Jak widać w tym kawałku kodu sprawdzane jest jaka funkcja ma być rysowana oraz rysowane są punkty w odpowiednim kolorze w zależności od wyniku obliczeń.
2.2. Wagi i ich losowanie
Wagi w tej aplikacji można wpisywać ręcznie lub generować losowo. Po wylosowaniu możemy przed uruchomieniem obliczeń aplikacji zmieniać wagi.
Rysunek 2. Wagi
Wartości wag uszeregowane są w kilku kolumnach:
- pierwsza kolumna odpowiada pierwszej części obliczeń;
- druga, trzecia i czwarta kolumna odpowiada drugiej części obliczeń;
- piąta kolumna odpowiada trzeciej części obliczeń.
Oto fragment kodu przedstawiający losowanie wag, czyli to co dzieje się po kliknięciu na przycisk „Losuj wagi”:
randomize; //losowanie wag
los:=(random(2000)-1000)/1000;
edit5.Text:=FloatToStr(los);
randomize;
los:=(random(2000)-1000)/1000;
edit6.Text:=FloatToStr(los);
…
Zastosowanie polecenia “(random(2000)-1000)/1000” powoduje, że losowana jest liczba z przedziału od 0 do 2000, pomniejszana o 1000 i dzielona przez 1000. Co za tym idzie otrzymujemy liczbę z przedziału od -1 do 1.
Do zapamiętywania wag służą nam tablice zmiennych:
wag1: array [0..9] of Double;
wag2: array [0..4,0..4] of Double;
wag3: array [0..4] of Double;
Wagi zapamiętywane są w tablicach:
wag1[0]:=StrToFloat(edit5.Text);
wag1[1]:=StrToFloat(edit6.Text);
…
wag2[0,0]:=StrToFloat(edit15.Text);
wag2[1,0]:=StrToFloat(edit16.Text);
2.3. Wejścia i ich losowanie
Rysunek 3. Wejścia
Te wartości można wpisywać samodzielnie, losować przyciskiem „Losuj wejścia”, jednak gdy nie użyjemy żadnej z tych opcji wylosują się po wciśnięciu przycisku „START”.
Losowane liczby (podobnie jak w przypadku wag) są liczbami rzeczywistymi, a przedział losowania jest od -3 do 3.
2.4. Wykonywanie obliczeń
Rysunek 4. Wygląd aplikacji
Przycisk „START” służy do wykonywania działań i rysowania punktów. Procedura w nim zawarta wczytuje wartości wejściowe oraz wagi do odpowiednich zmiennych. Gdy zachodzi potrzeba losuje wartości wejściowe. Wykonuje obliczenia dla poszczególnych warstw neuronów:
for k := 0 to 1 do begin
j:=0; //pierwsze neurony
for i := 0 to 9 do begin
neur1[i,k]:=wej1[k]*wag1[j];
j:=j+1;
neur1[i,k]:=neur1[i,k]+(wej2[k]*wag1[j]);
j:=j+1;
end; end;
for i:=0 to 4 do neur2[i,0]:=0; //zerowanie drugiej warstwy
for i:=0 to 4 do neur2[i,1]:=0;
for k:=0 to 1 do begin //drugi neurony
for j:=0 to 4 do begin
for i:=0 to 4 do begin
neur2[j,k]:=neur2[j,k]+neur1[i,k]*wag2[i,j]
end;
end;
end;
W procedurze tej wykonywane jest również rysowanie punktów opisane w punkcie 2.1.1.
Jeśli w puste pole obok tego przycisku wpiszemy liczbę całkowitą i klikniemy na „START” zostanie narysowane tyle punktów (wygenerowanych losowo i przetworzonych przez procedurę) ile sobie zażyczymy:
Rysunek 5. Rysowanie wielu punktów
Jak widać na Rysunku 5. losowanie nie jest idealne, jednak na takim wykresie widać już wiele.
To wszystkie funkcje zawarte w moim programie.