Zadanie 2.: Perceptron wielowarstwowy

Transkrypt

Zadanie 2.: Perceptron wielowarstwowy
Informatyka, studia dzienne, inż. I st.
semestr VI
Inteligentna Analiza Danych
2010/2011
Prowadzący: dr inż. Arkadiusz Tomczyk
Data oddania:
wtotek, 8:30
Ocena:
Marek Rogalski 150982
Paweł Tarasiuk 151021
Zadanie 2.: Perceptron wielowarstwowy∗
1. Cel
Zadanie polegało na przygotowaniu własnej implementacji perceptronu
wielowarstwowego przy wykorzystaniu metody wstecznej propagacji jako metody nauki. Istotną własnością przygotowanego projektu jest jego elastyczność - wszystkie konfigurowalne własności sieci neuronowej, czyli liczba oraz
liczność warstw, współczynnik nauki, momenetum oraz obecność neuronów
obciążających są przekazywane w postaci argumentów, dzięki czemu po jednorazowym skompilowaniu projektu można badać zachowanie różnych konfiguracji.
Sieć neuronowa może być trenowana zapisanymi w pliku tekstowym wzorcami, a wyniki treningu (ukształtowane wagi) mogą być zapisywane do postaci tekstowej, aby później nauka mogła zostać wznowiona od zapamiętanej
postaci. Po ukończonym treningu lub po wczytaniu wag z pliku, można także
zbadać zachowanie sieci dla wczytanych z pliku testów (bez nauki). Wszystkie
tryby pracy umożliwiają tworzenie logów umożliwiających analizę działania
perceptronu, a nawet (po prostym przetworzeniu) sporządzenie wykresów.
2. Wprowadzenie
Implementowana sieć neuronowa posiada jedną warstwę neuronów kopiujących, dowolną (w sensie możliwości sprzętu symulującego sieć neuronową;
może to być także liczba 0) liczbę warstw ukrytych, oraz warstwę wyjściową.
∗
SVN: https://serce.ics.p.lodz.pl/svn/labs/iad/atmp_sr0830/MarPab@586
1
Neurony warstw ukrytych oraz warstwy wyjściowej są neuronami nieliniowymi - w naszym przypadku zawsze oznacza to zastosowanie logistycznej
funkcji aktywacji. Oznacza to, że dla neuronu mającego n wejść:
s=
n
X
wk · ik
k=1
o = logsig(s)
Gdzie s - suma ważona wejść, ik - wartość k-tego wejścia, wk - waga k-tego
wejścia, ∀x ∈ logsig(x) = 1+e1−x - logistyczna funkcja aktywacji, o - wyjście
neuronu. Istotną zaletą logistycznej funkcji aktywacji jest łatwość obliczania
jej pochodnej, jeżeli w pamięci przechowuje się jedynie jej wartość (nawet nie
dysponując argumentem dla którego została ona obliczona) - okazuje się, że:
R
logsig0 (x) = logsig(x) · (1 − logsig(x))
Powyższe wzory wyjaśniają sposób generowania wyjść poszczególnych
warstw, czyli proces pozwalający obliczyć wyjścia wszystkich warstw oraz
samo wyjście sieci na podstawie zadanego wejścia. Ciekawszym procesem
jest przebieg metody propagacji wstecznej. Na początku dla każdego neuronu obliczany jest błąd, począwszy od warstwy wyjściowej. Dla neuronów
warstwy wyjściowej błąd definiuje się jako różnicę między wyjściem otrzymanym, a wyjściem oczekiwanym dla danego wejścia pomnożoną przez wartość
pochodnej funkcji aktywacji dla wyjścia otrzymanego. Dla neuronów warstw
ukrytych można obliczać błędy, gdy dysponuje się obliczonymi błędami dla
całej warstwy następującej po nim (bliższej warstwie wyjściowej). Niech warstwa następna (dla której obliczyliśmy wszystkie błędy) ma m neuronów, vj
oznacza wagę jaką ma wyjście bieżącego neuronu w j-tym neuronie warstwy
następnej, tj - błąd obliczony dla j-tego neurony warstwy następnej, zaś o wyjście bieżącego neuronu. Wówczas błąd dla bieżącego neuronu wynosi:
!
m
X
err = logsig0 (o) ·
vj · tj
j=0
Gdy mamy już obliczone wartości błędów dla wszystkich neuronów nieliniowych w sieci, dla każdego neuronu możemy dokonać dostosowania wag.
Dla neuronu mającego n wejść, wagi zmienią się w następujący sposób (dla
k = 1 . . . n):
∆wk ← η · err · ik
wk ← wk + ∆wk
Gdzie ik - wyjście k−-tego neuronu warstwy poprzedniej, err - błąd
wyznaczony dla bieżącego neuronu, η - współczynnik nauki. Jeżeli chcemy
wykorzystać człon momentum, algorytm zmieni się nieznacznie - wówczas
potrzebne nam będzie zapamiętywanie wartości ∆wk na potrzeby kolejnych
iteracji (przy inicjalizacji sieci zostaną one ustawione jako 0). Zmiana wag
z wykorzystaniem członu momentum przebiega w następujący sposób:
2
wk ← wk + η · err · ik + µ · ∆wk
∆wk ← η · err · ik
Gdzie µ - współczynnik momentum.
Nauka sieci odbywa się poprzez wielokrotnego obliczenia wyjść dla wejścia
ze zbioru uczącego, a następnie porównania wyjścia z wyjściem oczekiwanym,
propagacji błędu i aktualizacji wag. Sieć uczona jest w oparciu o wszystkie
testy z zestawu, jednak kolejność może być losowana. Zastosowanym przez
nas rozwiązaniem jest opcjonalne losowanie permutacji testów ze zbioru uczącego, tak aby każdy z nich był używany jednakowo często. Użycie do nauki
całej permutacji elementów zbioru testowego nazywamy epoką. Dla każdego
testu obliczany jest globalny błąd sieci, jako połowa sumy kwadratów między
wejściami oczekiwanymi a otrzymanymi. Za wartość miarodajną w kwestii
postępów w nauce sieci uznajemy maksymalny globalny błąd sieci dla pojedynczego testu w danej epoce. Warunkiem zakończenia nauki jest zatem
dla nas osiągnięcie odpowiedniej epoki lub maksymalnego globalnego błędu
w epoce poniżej zadanej wartości.
Aby zniwelować problemy z różnicami w rzędach wielkości danych na wejściu oraz na wyjściu sieci (drugi z problemów jest istotny, gdyż duże liczby
miałyby bez porównania większy wpływ na obliczane błędy i sieć uczyłaby
się głównie dostosowania do wyjść o dużych nominałach), zastosowaliśmy
prostą optymalizację. Dla całego zbioru testowego obliczane są minimalne
oraz maksymalne wartości danych otrzymywanych na poszczególnych wejściach oraz oczekiwanych na poszczególnych wyjściach, a następnie budowane
są funkcje liniowe będące bijekcjami [min, max] → [0, 1]. Dzięki temu sieć
operuje na wejściach i oczekiwanych wyjściach z przedziału [0, 1], wszystkie wejścia/wyjścia są tak samo ważne, a wskazywany błąd ma charakter
względny. Na potrzeby wyświetlania wyników działania sieci tworzone są odwrotne funkcje liniowe, pozwalające wrócić do skali stosowanej w zestawie
treningowym/testowym. Gdy stan sieci jest zapamiętywany po treningu, zapamiętywane są także te współczynniki, pozwalające później testować sieć
na ograniczonych zestawach testowych, w których wartości wejść i wyjść wyrażone są w tych samych jednostkach, co w zestawie treningowym.
3. Opis implementacji
Implementacja została wykonana w języku C++, z wykorzystaniem biblioteki getopt do przetwarzania listy argumentów uruchomienia. Znaczenie
argumentów jest przeważnie takie samo jak w schemacie proponowanym w instrukcji do ćwiczenia. Jedyne różnice to:
— Dodanie argumentu -u/--uklad, w którym musi zostać podany napis
składający się z rozdzielonych spacjami liczb oznaczających liczności kolejnych warstw budowanej sieci neuronowej (np. -u"4 2 4").
3
— Argumenty --lt oraz --ln odnoszą się do ostatecznego przetworzenia
nie poddanego permutacji zestawu treningowego, bez nauki. Pozwala to
odczytać ostateczny błąd, oraz poszczególne błędy na różnych zestawach
treningowych (oraz wyjścia poszczególnych warstw). W przypadku zestawu testowego, dane o wyjściach warstw wypisywane są zawsze (nie widzimy innego sensu używania zestawów testowych), natomiast stan sieci po
uczeniu wypisany przy wykorzystaniu opcji --ln jest prawidłowy, gdyż
i tak później już nie następuje nauka.
Stworzona implementacja stanowi kompromis pomiędzy czytelnością kodu a wydajnością zastosowanego rozwiązania. Istnieje klasa Layer, co stanowi pewną wygodę w operowaniu na poszczególnych warstwach, jednakże
za wszystkie obliczenia związane z działaniem sieci neuronowej odpowiada
klasa Network. Poszczególne neurony nie są wyróżnione (gdyż według założeń tego konkretnego ćwiczenia, wszystkie neurony mają być takie same zatem przechowywanie informacji o funkcji aktywacji, bądź wskaźników do
warstw poprzedniej/następnej byłoby zbędną nadmiarowością), lecz zastosowane struktury danych pozwalają z łatwością odczytać informację o stanie
każdego z nich (na potrzeby logowania komplet informacji na temat sieci wypisuje metoda describe klasy Network). W projekcie obecne są klasy pomocnicze, takie jak klasa Logger pozwalająca formułować komunikaty w sposób
znany z funkcji printf przy dodatkowej możliwości jednoczesnego wypisywanie ich do pliku oraz na standardowe wyjście oraz klasa DataManager odpowiedzialna za normalizację danych, dostęp do znormalizowanych testów,
oraz powrót do pierwotnej skali przy podawaniu wyznaczonych wyjść sieci.
4. Materiały i metody
Pierwsza część badań dotyczyła uczenia sieci tożsamościowego przekształcania wierszy macierzy jednostkowej o wymiarze 4. Przeprowadzone testy 1.
i 2. miały za zadanie rozstrzygnąć wpływ stosowania obciążenia na zdolność
sieci do nauki. Zostały one wykonane przy losowaniu kolejności wprowadzania
testów do sieci w danej epoce. Zastosowano współczynnik uczenia o wartości
0, 6 i pominięto człon momentum (jak wynika ze wzorów z poprzedniej sekcji,
jest to po prostu równoważne przyjęciu współczynnika momentum równego
0).
5. Wyniki
Test 1. - identyczność bez biasu
../project/bin/app -u"4 2 4" -n0.6 -e2500 -s10 -d ../data/data1.in
-r --lt --ln -z identity1.weights -l identity1.log
W teście 1. otrzymaliśmy następującą zależność błędu sieci od liczby epok:
4
0.45
Maksymalny błąd sieci
0.4
0.35
0.3
0.25
0.2
0.15
0.1
0.05
0
0
500
1000
1500
2000
2500
Epoka
Otrzymana w wyniku nauki sieć miała następujące wagi:
Warstwa 2.:
( -1.69 -3.69 +4.98 -1.69 ) # Neuron 2.1
( -1.69 +4.99 -3.81 -1.69 ) # Neuron 2.2
Warstwa 3.:
( -1.73 -1.73 ) # Neuron 3.1
( -13.31 +2.66 ) # Neuron 3.2
( +2.61 -13.28 ) # Neuron 3.3
( -1.73 -1.73 ) # Neuron 3.4
Zaś przebieg zestawu treningowego w wykształconej sieci (bez uczenia) został zamieszczony poniżej. Kolejne linie oznaczają: wejście, oczekiwane wyjście, obliczone wyjście, oraz przebieg generowania wyjść w sieci operującej
na danych znormalizowanych.
( +1.00 +0.00 +0.00 +0.00 ) ->
( +1.00 +0.00 +0.00 +0.00 ) # oczekiwano
( +0.34 +0.09 +0.10 +0.34 ) # otrzymano
( ( +0.94 +0.06 +0.06 +0.06 ) ( +0.17 +0.17 ) ( +0.36 +0.15 +0.15 +0.36 ) )
Globalny błąd sieci: 0.21786
( +0.00 +1.00 +0.00 +0.00 ) ->
( +0.00 +1.00 +0.00 +0.00 ) # oczekiwano
( +0.10 +0.96 -0.07 +0.10 ) # otrzymano
( ( +0.06 +0.94 +0.06 +0.06 ) ( +0.03 +0.99 ) ( +0.15 +0.90 +0.00 +0.15 ) )
Globalny błąd sieci: 0.00986
( +0.00 +0.00 +1.00 +0.00 ) ->
( +0.00 +0.00 +1.00 +0.00 ) # oczekiwano
( +0.10 -0.07 +0.95 +0.10 ) # otrzymano
( ( +0.06 +0.06 +0.94 +0.06 ) ( +0.99 +0.03 ) ( +0.15 +0.00 +0.90 +0.15 ) )
Globalny błąd sieci: 0.00985
( +0.00 +0.00 +0.00 +1.00 ) ->
( +0.00 +0.00 +0.00 +1.00 ) # oczekiwano
5
( +0.34 +0.09 +0.10 +0.34 ) # otrzymano
( ( +0.06 +0.06 +0.06 +0.94 ) ( +0.17 +0.17 ) ( +0.36 +0.15 +0.15 +0.36 ) )
Globalny błąd sieci: 0.21780
Test 2. - identyczność z biasem
../project/bin/app -u"4 2 4" -n0.6 -b -e2500 -s10 -d ../data/data1.in
-r --lt --ln -z identity2.weights -l identity2.log
W teście 2. otrzymaliśmy następującą zależność błędu sieci od liczby epok:
0.45
Maksymalny błąd sieci
0.4
0.35
0.3
0.25
0.2
0.15
0.1
0.05
0
0
500
1000
1500
2000
2500
Epoka
Otrzymana w wyniku nauki sieć miała następujące wagi (pierwsza waga
w każdej liście oznacza wagę biasu):
Warstwa 2.:
( -0.21 +1.77 -2.73 +4.66 -4.85 ) # Neuron 2.1
( +0.30 -4.79 +4.46 +2.55 -2.58 ) # Neuron 2.2
Warstwa
( -1.70
( -3.33
( -6.94
( +3.15
3.:
+5.57
-5.21
+5.66
-7.24
-6.93
+6.30
+4.12
-5.31
)
)
)
)
#
#
#
#
Neuron
Neuron
Neuron
Neuron
3.1
3.2
3.3
3.4
Zaś przebieg zestawu treningowego w wykształconej sieci (bez uczenia)
wyglądał następująco:
( +1.00 +0.00 +0.00 +0.00 ) ->
( +1.00 +0.00 +0.00 +0.00 ) # oczekiwano
( +0.99 -0.07 +0.02 +0.01 ) # otrzymano
( ( +0.94 +0.06 +0.06 +0.06 ) ( +0.78 +0.02 ) ( +0.92 +0.00 +0.08 +0.07 ) )
Globalny błąd sieci: 0.00217
( +0.00 +1.00 +0.00 +0.00 ) ->
( +0.00 +1.00 +0.00 +0.00 ) # oczekiwano
( -0.07 +0.99 +0.01 +0.01 ) # otrzymano
6
( ( +0.06 +0.94 +0.06 +0.06 ) ( +0.06 +0.98 ) ( +0.00 +0.93 +0.08 +0.07 ) )
Globalny błąd sieci: 0.00212
( +0.00 +0.00 +1.00 +0.00 ) ->
( +0.00 +0.00 +1.00 +0.00 ) # oczekiwano
( +0.00 +0.01 +0.98 -0.07 ) # otrzymano
( ( +0.06 +0.06 +0.94 +0.06 ) ( +0.98 +0.92 ) ( +0.06 +0.07 +0.92 +0.00 ) )
Globalny błąd sieci: 0.00216
( +0.00 +0.00 +0.00 +1.00 ) ->
( +0.00 +0.00 +0.00 +1.00 ) # oczekiwano
( +0.02 +0.01 -0.07 +0.98 ) # otrzymano
( ( +0.06 +0.06 +0.06 +0.94 ) ( +0.01 +0.12 ) ( +0.08 +0.07 +0.00 +0.92 ) )
Globalny błąd sieci: 0.00214
Test 3. - identyczność z biasem, uczenie: 0, 9, bez momentum
../project/bin/app -u"4 2 4" -n0.9 -m0.0 -b -e2500 -s10 -d ../data/data1.in
-r --lt --ln -z identity3.weights -l identity3.log
W teście 3. otrzymaliśmy następującą zależność błędu sieci od liczby epok:
0.45
Maksymalny błąd sieci
0.4
0.35
0.3
0.25
0.2
0.15
0.1
0.05
0
0
500
1000
1500
2000
2500
Epoka
Otrzymana w wyniku nauki sieć miała następujące wagi (pierwsza waga
w każdej liście oznacza wagę biasu):
Warstwa 2.:
( -0.22 +1.77 -2.76 +4.75 -4.93 ) # Neuron 2.1
( +0.31 -4.89 +4.51 +2.62 -2.60 ) # Neuron 2.2
Warstwa
( -1.80
( -3.39
( -7.24
( +3.30
3.:
+5.82
-5.38
+5.89
-7.51
-7.10
+6.46
+4.33
-5.54
)
)
)
)
#
#
#
#
Neuron
Neuron
Neuron
Neuron
3.1
3.2
3.3
3.4
7
Zaś przebieg zestawu treningowego w wykształconej sieci (bez uczenia)
wyglądał następująco:
( +1.00 +0.00 +0.00 +0.00 ) ->
( +1.00 +0.00 +0.00 +0.00 ) # oczekiwano
( +0.99 -0.07 +0.01 +0.00 ) # otrzymano
( ( +0.94 +0.06 +0.06 +0.06 ) ( +0.78 +0.02 ) ( +0.93 +0.00 +0.07 +0.07 ) )
Globalny błąd sieci: 0.00198
( +0.00 +1.00 +0.00 +0.00 ) ->
( +0.00 +1.00 +0.00 +0.00 ) # oczekiwano
( -0.07 +1.00 +0.01 +0.01 ) # otrzymano
( ( +0.06 +0.94 +0.06 +0.06 ) ( +0.06 +0.99 ) ( +0.00 +0.93 +0.07 +0.07 ) )
Globalny błąd sieci: 0.00198
( +0.00 +0.00 +1.00 +0.00 ) ->
( +0.00 +0.00 +1.00 +0.00 ) # oczekiwano
( +0.00 +0.00 +0.99 -0.07 ) # otrzymano
( ( +0.06 +0.06 +0.94 +0.06 ) ( +0.98 +0.93 ) ( +0.06 +0.07 +0.93 +0.00 ) )
Globalny błąd sieci: 0.00200
( +0.00 +0.00 +0.00 +1.00 ) ->
( +0.00 +0.00 +0.00 +1.00 ) # oczekiwano
( +0.01 +0.00 -0.07 +0.99 ) # otrzymano
( ( +0.06 +0.06 +0.06 +0.94 ) ( +0.01 +0.12 ) ( +0.07 +0.06 +0.00 +0.93 ) )
Globalny błąd sieci: 0.00194
Test 4. - identyczność z biasem, uczenie: 0, 2, bez momentum
../project/bin/app -u"4 2 4" -n0.2 -m0.0 -b -e2500 -s10 -d ../data/data1.in
-r --lt --ln -z identity4.weights -l identity4.log
W teście 4. otrzymaliśmy następującą zależność błędu sieci od liczby epok:
0.45
Maksymalny błąd sieci
0.4
0.35
0.3
0.25
0.2
0.15
0.1
0.05
0
0
500
1000
1500
Epoka
8
2000
2500
Otrzymana w wyniku nauki sieć miała następujące wagi (pierwsza waga
w każdej liście oznacza wagę biasu):
Warstwa 2.:
( -0.19 +1.46 -2.19 +4.06 -4.46 ) # Neuron 2.1
( +0.30 -4.26 +4.25 +1.89 -2.24 ) # Neuron 2.2
Warstwa
( -1.03
( -3.16
( -5.18
( +2.44
3.:
+4.17
-3.94
+4.57
-6.12
-6.02
+5.62
+2.82
-3.91
)
)
)
)
#
#
#
#
Neuron
Neuron
Neuron
Neuron
3.1
3.2
3.3
3.4
Zaś przebieg zestawu treningowego w wykształconej sieci (bez uczenia)
wyglądał następująco:
( +1.00 +0.00 +0.00 +0.00 ) ->
( +1.00 +0.00 +0.00 +0.00 ) # oczekiwano
( +0.92 -0.07 +0.10 +0.04 ) # otrzymano
( ( +0.94 +0.06 +0.06 +0.06 ) ( +0.74 +0.03 ) ( +0.86 +0.00 +0.15 +0.10 ) )
Globalny błąd sieci: 0.00907
( +0.00 +1.00 +0.00 +0.00 ) ->
( +0.00 +1.00 +0.00 +0.00 ) # oczekiwano
( -0.07 +0.93 +0.07 +0.06 ) # otrzymano
( ( +0.06 +0.94 +0.06 +0.06 ) ( +0.10 +0.98 ) ( +0.00 +0.88 +0.12 +0.12 ) )
Globalny błąd sieci: 0.00722
( +0.00 +0.00 +1.00 +0.00 ) ->
( +0.00 +0.00 +1.00 +0.00 ) # oczekiwano
( +0.04 +0.06 +0.89 -0.07 ) # otrzymano
( ( +0.06 +0.06 +0.94 +0.06 ) ( +0.96 +0.87 ) ( +0.09 +0.11 +0.84 +0.00 ) )
Globalny błąd sieci: 0.00809
( +0.00 +0.00 +0.00 +1.00 ) ->
( +0.00 +0.00 +0.00 +1.00 ) # oczekiwano
( +0.08 +0.03 -0.06 +0.90 ) # otrzymano
( ( +0.06 +0.06 +0.06 +0.94 ) ( +0.02 +0.16 ) ( +0.13 +0.09 +0.01 +0.85 ) )
Globalny błąd sieci: 0.00775
Test 5. - identyczność z biasem, uczenie: 0, 9, momentum: 0, 6
../project/bin/app -u"4 2 4" -n0.9 -m0.6 -b -e2500 -s10 -d ../data/data1.in
-r --lt --ln -z identity5.weights -l identity5.log
W teście 5. otrzymaliśmy następującą zależność błędu sieci od liczby epok:
9
0.5
Maksymalny błąd sieci
0.45
0.4
0.35
0.3
0.25
0.2
0.15
0.1
0.05
0
0
500
1000
1500
2000
2500
Epoka
Otrzymana w wyniku nauki sieć miała następujące wagi (pierwsza waga
w każdej liście oznacza wagę biasu):
Warstwa 2.:
( -0.05 +4.91 -2.64 -5.07 +1.56 ) # Neuron 2.1
( -0.11 +2.91 +4.91 -2.03 -4.59 ) # Neuron 2.2
Warstwa
( -7.53
( -3.59
( +3.52
( -1.70
3.:
+6.18
-5.48
-7.89
+5.80
+4.42
+6.81
-5.65
-7.25
)
)
)
)
#
#
#
#
Neuron
Neuron
Neuron
Neuron
3.1
3.2
3.3
3.4
Zaś przebieg zestawu treningowego w wykształconej sieci (bez uczenia)
wyglądał następująco:
( +1.00 +0.00 +0.00 +0.00 ) ->
( +1.00 +0.00 +0.00 +0.00 ) # oczekiwano
( +1.00 +0.00 -0.07 +0.00 ) # otrzymano
( ( +0.94 +0.06 +0.06 +0.06 ) ( +0.98 +0.93 ) ( +0.93 +0.06 +0.00 +0.06 ) )
Globalny błąd sieci: 0.00195
( +0.00 +1.00 +0.00 +0.00 ) ->
( +0.00 +1.00 +0.00 +0.00 ) # oczekiwano
( +0.00 +1.00 +0.00 -0.07 ) # otrzymano
( ( +0.06 +0.94 +0.06 +0.06 ) ( +0.08 +0.99 ) ( +0.06 +0.94 +0.06 +0.00 ) )
Globalny błąd sieci: 0.00194
( +0.00 +0.00 +1.00 +0.00 ) ->
( +0.00 +0.00 +1.00 +0.00 ) # oczekiwano
( -0.07 +0.00 +1.00 +0.00 ) # otrzymano
( ( +0.06 +0.06 +0.94 +0.06 ) ( +0.01 +0.14 ) ( +0.00 +0.06 +0.93 +0.07 ) )
Globalny błąd sieci: 0.00190
( +0.00 +0.00 +0.00 +1.00 ) ->
( +0.00 +0.00 +0.00 +1.00 ) # oczekiwano
( +0.00 -0.07 +0.00 +1.00 ) # otrzymano
10
( ( +0.06 +0.06 +0.06 +0.94 ) ( +0.78 +0.02 ) ( +0.07 +0.00 +0.06 +0.94 ) )
Globalny błąd sieci: 0.00193
Test 6. - identyczność z biasem, uczenie: 0, 2, momentum: 0, 9
../project/bin/app -u"4 2 4" -n0.2 -m0.9 -b -e2500 -s10 -d ../data/data1.in
-r --lt --ln -z identity6.weights -l identity6.log
W teście 6. otrzymaliśmy następującą zależność błędu sieci od liczby epok:
0.5
Maksymalny błąd sieci
0.45
0.4
0.35
0.3
0.25
0.2
0.15
0.1
0.05
0
0
500
1000
1500
2000
2500
Epoka
Otrzymana w wyniku nauki sieć miała następujące wagi (pierwsza waga
w każdej liście oznacza wagę biasu):
Warstwa 2.:
( +0.04 +4.68 -2.24 -4.82 +1.25 ) # Neuron 2.1
( -0.11 +2.47 +4.74 -1.76 -4.25 ) # Neuron 2.2
Warstwa
( -6.60
( -3.39
( +3.08
( -1.11
3.:
+5.84
-4.69
-7.36
+4.61
+3.46
+6.29
-4.62
-6.61
)
)
)
)
#
#
#
#
Neuron
Neuron
Neuron
Neuron
3.1
3.2
3.3
3.4
Zaś przebieg zestawu treningowego w wykształconej sieci (bez uczenia)
wyglądał następująco:
( +1.00 +0.00 +0.00 +0.00 ) ->
( +1.00 +0.00 +0.00 +0.00 ) # oczekiwano
( +0.96 +0.03 -0.07 +0.02 ) # otrzymano
( ( +0.94 +0.06 +0.06 +0.06 ) ( +0.98 +0.89 ) ( +0.90 +0.08 +0.00 +0.08 ) )
Globalny błąd sieci: 0.00289
(
(
(
(
+0.00 +1.00 +0.00 +0.00 )
+0.00 +1.00 +0.00 +0.00 )
+0.02 +0.96 +0.03 -0.07 )
( +0.06 +0.94 +0.06 +0.06
->
# oczekiwano
# otrzymano
) ( +0.12 +0.98 ) ( +0.08 +0.90 +0.09 +0.00 ) )
11
Globalny błąd sieci: 0.00287
( +0.00 +0.00 +1.00 +0.00 ) ->
( +0.00 +0.00 +1.00 +0.00 ) # oczekiwano
( -0.07 +0.03 +0.96 +0.05 ) # otrzymano
( ( +0.06 +0.06 +0.94 +0.06 ) ( +0.01 +0.17 ) ( +0.00 +0.08 +0.90 +0.10 ) )
Globalny błąd sieci: 0.00354
( +0.00 +0.00 +0.00 +1.00 ) ->
( +0.00 +0.00 +0.00 +1.00 ) # oczekiwano
( +0.04 -0.07 +0.02 +0.95 ) # otrzymano
( ( +0.06 +0.06 +0.06 +0.94 ) ( +0.74 +0.02 ) ( +0.10 +0.00 +0.08 +0.90 ) )
Globalny błąd sieci: 0.00357
Test 7. - zestaw irysów, sieć 4-3-3
../project/bin/app -u"4 3 3" -n0.2 -m0.9 -b -e200000 -s1000 -d
../data/iris.in -r --lt --ln -z iris1.weights -l iris1.log
W teście 7. otrzymaliśmy następującą zależność błędu sieci od liczby epok:
0.8
Maksymalny błąd sieci
0.7
0.6
0.5
0.4
0.3
0.2
0.1
0
0
20000
40000
60000
80000 100000 120000 140000 160000 180000 200000
Epoka
Otrzymana w wyniku nauki sieć miała następujące wagi (pierwsza waga
w każdej liście oznacza wagę biasu):
Warstwa 2.:
( -3.35 +1.59 -2.21 -9.02 -4.71 ) # Neuron 2.1
( -6.86 +5.40 -8.79 +16.77 +15.55 ) # Neuron 2.2
( -93.96 -10.41 -27.90 +79.75 +89.94 ) # Neuron 2.3
Warstwa
( +2.72
( -2.73
( -2.68
3.:
+0.95 -5.43 +0.00 ) # Neuron 3.1
-0.28 +5.22 -5.34 ) # Neuron 3.2
-7.37 +0.19 +5.34 ) # Neuron 3.3
12
Przebieg zestawu treningowego był ciekawy, lecz zbyt długi, aby go tutaj
w całości przytoczyć. Błąd sieci często był wypisywany jako 0 i był bliski
błędowi obliczeń zmiennoprzecinkowych - poniżej zamieszczam dwa testy generujące największy błąd:
( +6.30 +2.80 +5.10 +1.50 ) ->
( +0.00 +0.00 +1.00 ) # oczekiwano
( -0.00 +0.98 +0.02 ) # otrzymano
( ( +0.55 +0.35 +0.67 +0.57 ) ( +0.00 +1.00 +0.01 ) ( +0.06 +0.92 +0.08 ) )
Globalny błąd sieci: 0.73471
( +6.00 +3.00 +4.80 +1.80 ) ->
( +0.00 +0.00 +1.00 ) # oczekiwano
( -0.00 +0.29 +0.71 ) # otrzymano
( ( +0.48 +0.43 +0.63 +0.68 ) ( +0.00 +1.00 +0.61 ) ( +0.06 +0.31 +0.69 ) )
Globalny błąd sieci: 0.06279
Test 8. - zestaw irysów, sieć 4-4-3
../project/bin/app -u"4 4 3" -n0.2 -m0.9 -b -e200000 -s1000 -d
../data/iris.in -r --lt --ln -z iris2.weights -l iris2.log
W teście 8. otrzymaliśmy następującą zależność błędu sieci od liczby epok:
0.8
Maksymalny błąd sieci
0.7
0.6
0.5
0.4
0.3
0.2
0.1
0
0
20000
40000
60000
80000 100000 120000 140000 160000 180000 200000
Epoka
Otrzymana w wyniku nauki sieć miała następujące wagi (pierwsza waga
w każdej liście oznacza wagę biasu):
Warstwa 2.:
( -6.61 +3.95 -7.90 +14.84 +14.13 ) # Neuron 2.1
( +67.80 +4.94 +34.10 -14.59 -113.26 ) # Neuron 2.2
( -31.28 -11.13 -15.74 +19.20 +47.42 ) # Neuron 2.3
( +38.77 +0.56 +5.78 -81.64 +25.62 ) # Neuron 2.4
Warstwa 3.:
( +2.71 -5.44 +0.01 +0.02 -0.00 ) # Neuron 3.1
( -36.66 +5.50 +13.04 +7.72 +20.90 ) # Neuron 3.2
( +31.19 -0.06 -13.04 -7.73 -20.86 ) # Neuron 3.3
13
Przebieg zestawu treningowego nie był ciekawy. Poniżej zamieszczam przebieg dla testu, który sprawił największy „problem”:
( +6.10 +2.80 +4.70 +1.20 ) ->
( +0.00 +1.00 +0.00 ) # oczekiwano
( -0.00 +0.92 +0.08 ) # otrzymano
( ( +0.50 +0.35 +0.61 +0.46 ) ( +1.00 +1.00 +0.00 +0.96 ) ( +0.06 +0.86 +0.14 ) )
Globalny błąd sieci: 0.00533
Test 9. - zestaw irysów, sieć 4-3-4-3
../project/bin/app -u"4 3 4 3" -n0.2 -m0.9 -b -e80000 -s400 -d
../data/iris.in -r --lt --ln -z iris3.weights -l iris3.log
W teście 9. otrzymaliśmy następującą zależność błędu sieci od liczby epok:
0.8
Maksymalny błąd sieci
0.7
0.6
0.5
0.4
0.3
0.2
0.1
0
0
10000
20000
30000
40000
50000
60000
70000
80000
Epoka
Otrzymana w wyniku nauki sieć miała następujące wagi (pierwsza waga
w każdej liście oznacza wagę biasu):
Warstwa 2.:
( -1.63 +9.69 -16.40 +16.03 -9.44 ) # Neuron 2.1
( +20.55 +3.19 +2.93 -23.78 -11.02 ) # Neuron 2.2
( +8.08 +29.86 -9.03 -19.00 -13.98 ) # Neuron 2.3
Warstwa 3.:
( +18.66 -15.29 -11.70 +15.18 ) # Neuron 3.1
( -5.36 -6.29 -0.70 -0.05 ) # Neuron 3.2
( -8.77 -17.32 +1.90 +10.29 ) # Neuron 3.3
( +6.07 +22.59 -15.67 -21.07 ) # Neuron 3.4
Warstwa 4.:
( -2.72 -0.00 +3.11 +5.63 +0.01 ) # Neuron 4.1
( +11.37 -8.62 -3.09 -5.65 -5.54 ) # Neuron 4.2
( -11.36 +8.63 -1.33 +0.02 +5.53 ) # Neuron 4.3
Przebieg zestawu treningowego nie był ciekawy. Poniżej zamieszczam przebieg dla testu, który sprawił największy „problem”:
( +5.50 +2.60 +4.40 +1.20 ) ->
( +0.00 +1.00 +0.00 ) # oczekiwano
14
( +0.00 +1.06 -0.06 ) # otrzymano
( ( +0.35 +0.28 +0.57 +0.46 ) ( +0.87 +0.98 +0.24 ) ( +0.08 +0.00 +0.00 +0.99 )
( +0.06 +0.99 +0.01 ) )
Globalny błąd sieci: 0.00321
Test 10. - zestaw irysów, sieć 4-6-3
../project/bin/app -u"4 6 3" -n0.2 -m0.9 -b -e80000 -s400 -d ../data/iris.in
-r --lt --ln -z iris4.weights -l iris4.log
W teście 10. otrzymaliśmy następującą zależność błędu sieci od liczby
epok:
0.9
Maksymalny błąd sieci
0.8
0.7
0.6
0.5
0.4
0.3
0.2
0.1
0
0
10000
20000
30000
40000
50000
60000
70000
80000
Epoka
Otrzymana w wyniku nauki sieć miała następujące wagi (pierwsza waga
w każdej liście oznacza wagę biasu):
Warstwa 2.:
( -3.33 -11.90 +26.21 -0.49 -3.08 ) # Neuron 2.1
( -38.09 -2.26 -17.38 +7.57 +63.77 ) # Neuron 2.2
( +4.08 +14.61 -30.01 -1.47 +3.57 ) # Neuron 2.3
( +25.33 +12.06 +4.74 -16.09 -37.78 ) # Neuron 2.4
( +5.43 -2.81 +7.41 -12.93 -12.74 ) # Neuron 2.5
( +46.90 +26.72 +1.28 -63.98 -34.95 ) # Neuron 2.6
Warstwa
( -2.55
( +2.78
( -2.90
3.:
-0.11 -0.07 -0.08 -0.11 +5.48 +0.02 ) # Neuron 3.1
+10.88 -15.31 +9.90 -24.89 -6.40 +14.90 ) # Neuron 3.2
-10.77 +15.34 -9.80 +24.93 +0.91 -14.89 ) # Neuron 3.3
Przebieg zestawu treningowego nie był ciekawy. Poniżej zamieszczam przebieg dla testu, który sprawił największy „problem”:
( +7.20 +3.00 +5.80 +1.60 ) ->
( +0.00 +0.00 +1.00 ) # oczekiwano
( -0.00 -0.07 +1.07 ) # otrzymano
( ( +0.77 +0.43 +0.77 +0.61 ) ( +0.03 +0.07 +0.97 +0.75 +0.00 +0.05 ) ( +0.06 +0.00 +1.00 ) )
Globalny błąd sieci: 0.00371
15
Test 11. - zestaw irysów, sieć 4-4-4-4-4-3
../project/bin/app -u"4 4 4 4 4 3" -n0.2 -m0.9 -b -e200000 -s1000
-d ../data/iris.in -r --lt --ln -z iris5.weights -l iris5.log
W teście 11. otrzymaliśmy następującą zależność błędu sieci od liczby
epok:
0.8
Maksymalny błąd sieci
0.7
0.6
0.5
0.4
0.3
0.2
0.1
0
0
20000
40000
60000
80000 100000 120000 140000 160000 180000 200000
Epoka
Otrzymana w wyniku nauki sieć miała następujące wagi (pierwsza waga
w każdej liście oznacza wagę biasu):
Warstwa 2.:
( -19.51 -5.22 -9.79 +24.05 +15.45 ) # Neuron 2.1
( +12.84 +17.14 -9.29 -22.29 -10.24 ) # Neuron 2.2
( -7.36 +9.36 +9.52 -18.87 +8.59 ) # Neuron 2.3
( +3.89 -5.98 +17.96 -11.21 -5.75 ) # Neuron 2.4
Warstwa
( +7.55
( -0.13
( +1.76
( +0.01
3.:
+3.17
-6.05
+4.98
-9.23
-2.80 -0.92 -7.05 ) # Neuron 3.1
+5.66 +1.82 +6.30 ) # Neuron 3.2
-6.07 -13.01 -8.34 ) # Neuron 3.3
+10.41 +0.04 +9.15 ) # Neuron 3.4
Warstwa
( +0.09
( -4.18
( +1.35
( -1.33
4.:
+3.20
-0.01
+4.58
+9.90
-5.04
-4.92
-4.17
-1.52
Warstwa
( +1.02
( +1.90
( +4.31
( +5.77
5.:
-1.58
-2.59
-5.02
-4.20
-12.08 -1.24 +2.29 ) # Neuron 5.1
-2.21 -2.72 -9.87 ) # Neuron 5.2
-5.12 -3.89 +4.27 ) # Neuron 5.3
-5.13 -4.79 +1.96 ) # Neuron 5.4
Warstwa
( -2.71
( -2.47
( +2.47
6.:
+0.03 +6.28 +0.06 -0.09 ) # Neuron 6.1
-2.00 -6.74 +2.59 +4.51 ) # Neuron 6.2
+1.98 +0.46 -2.64 -4.44 ) # Neuron 6.3
+4.56 -8.56 ) # Neuron 4.1
+11.80 -5.68 ) # Neuron 4.2
+5.83 -6.77 ) # Neuron 4.3
+3.76 -3.05 ) # Neuron 4.4
16
Przebieg zestawu treningowego był ciekawy, lecz zbyt długi, aby go tutaj
w całości przytoczyć. Błąd sieci często był wypisywany jako 0 i był bliski
błędowi obliczeń zmiennoprzecinkowych. Poniżej zamieszczam dwa testy generujące największy błąd - jak zatem widać, tylko w jednym z testów błąd
miał znaczenie i oznaczał nieprawidłową klasyfikację.
(
(
(
(
+6.00 +2.70 +5.10 +1.60 ) ->
+0.00 +1.00 +0.00 ) # oczekiwano
+0.00 +0.02 +0.98 ) # otrzymano
( +0.48 +0.32 +0.67 +0.61 ) ( +0.61 +0.04 +0.00 +0.01 ) ( +1.00 +0.03 +0.99 +0.01 )
( +1.00 +1.00 +1.00 +1.00 ) ( +0.00 +0.00 +0.00 +0.00 ) ( +0.06 +0.08 +0.92 ) )
Globalny błąd sieci: 0.73632
(
(
(
(
+6.30 +2.80 +5.10 +1.50 ) ->
+0.00 +0.00 +1.00 ) # oczekiwano
+0.00 +0.02 +0.98 ) # otrzymano
( +0.55 +0.35 +0.67 +0.57 ) ( +0.30 +0.13 +0.00 +0.02 ) ( +1.00 +0.26 +0.90 +0.24 )
( +0.98 +0.98 +1.00 +1.00 ) ( +0.00 +0.00 +0.01 +0.00 ) ( +0.06 +0.08 +0.92 ) )
Globalny błąd sieci: 0.00030
6. Dyskusja
Testy 1. i 2. miały na celu badanie wpływu obecności biasu na możliwości nauki sieci. Okazało się, że w przypadku braku obciążenia (test 1.)
sieć o strukturze 4-2-4 nie pozwala na dokonanie nauki wierszy macierzy
jednostkowej o rozmiarze 4. Klarowne są w tym wypadku wnioski, jakie można wyciągnąć badając uzyskane wagi oraz wyjścia poszczególnych neuronów
sieci po ukończonej (trwającej 2500 epok). Otóż okazuje się, że w teście 1.
nauczona sieć nie rozróżnia wejścia ( 1 0 0 0 ) od ( 0 0 0 1 ). Łatwo to
uzasadnić, patrząc na możliwe konfiguracje wyjść warstwy ukrytej - jeden
z dwóch neuronów może być wzbudzony bardziej od drugiego, lub oba mogą
być wzbudzone w porównywalnym stopniu. Wygaszenie obu neuronów warstwy ukrytej nie jest sensowną rozróżnialną konfiguracją w przypadku sieci
bez biasu, gdyż same przybliżone ”zera” w całej pewnej warstwie dla sieci bez
biasu oznacza także zera we wszystkich następnych (idąc w stronę wyjścia
sieci) warstw.
Powyższe rozumowanie znajduje odzwierciedlenie w teście 2. - tam nauka
sieci powiodła się i w zależności od wyjść warstwy drugiej (jeden z neuronów
wzbudzony i drugi wygaszony, oba wzbudzone lub oba wygaszone) możemy
osiągnąć cztery różne wejścia. Dzięki obecności biasu, nawet przy małych
wartościach bezwzględnych wyjść warstwy ukrytej, możemy zinterpretować
taki wynik jako unikalny, niezerowy wektor wartości wyjściowych.
W testach 2. - 6. badany był wpływ współczynników uczenia oraz momentum na przebieg procesu nauki sieci. Łatwym do przewidzenia wnioskiem
jest to, że zwiększanie każdego ze współczynników (oczywiście, o ile nie osiągniemy ani nie przekroczymy wartości 1) powoduje wzrost szybkości procesu
nauki. Najlepszą konfiguracją okazała się ta, w której wartości obu współczynników były wysokie - w teście 5. współczynnik nauki wynosił 0, 6, zaś
17
współczynnik momentum - 0, 9. Jak można odczytać z wykresu, już przeprowadzenie 500 do 1000 epok nauki pozwalało osiągnąć zadowalająco niski
współczynnik globalnego błędu sieci (czyli globalny błąd sieci uczącej się
w oparciu o znormalizowane do przedziału [0, 1] wyjścia oczekiwane).
Należy jednakże pamiętać, że wniosek ten opisuje bardzo mały i prosty zestaw treningowy. Intuicja oraz literatura sugerują, że oparcie nauki na
niewielkim współczynniku uczenia oraz dużym momentum pozwala uczynić
naukę bardziej elastyczną, szczególnie w przypadku kiedy ważne jest dopasowanie się do dokładnie wszystkich testów z nieco liczniejszego zbioru treningowego (czyli jeżeli interesuje nas maksymalny globalny błąd sieci w danej
epoce, nie zaś przeciętny). Jednocześnie, zgodnie z przytoczonymi we wprowadzeniu wzorami, jeżeli współczynnik nauki wyniesie 0, to niezależnie od
wartości współczynnika momentum żadna nauka nie będzie miała miejsca.
Ostatecznie, zdecydowaliśmy się używać współczynnika nauki o wartości 0, 2
oraz współczynnika momentum wynoszącego 0, 9. W przypadku uczenia sieci wierszy macierzy jednostkowej o wymiarze 4, konfiguracja ta nie wypada
rewelacyjnie (test 6.), ale oczywiście bez porównania lepiej niż test 4., gdzie
przy tym samym współczynniku uczenia nie jest wykorzystywany mechanizm
momentum. Ważny jest jednak właśnie wpływ momentum na końcowy etap
nauki, gdy chce się zminimalizować błąd bądź dostosować sieć do ostatnich
problematycznych testów - dlatego uważamy momentum za bardzo przydatne
przy testach wymagających większej liczby epok. Pozostawienie współczynnika uczenia na poziomie 0, 2 co prawda spowalnia początkowy proces nauki,
ale chroni przed przedwczesnym przeuczeniem sieci (prawdopodobnie właśnie
z tego powodu w przeprowadzonych 200000-epokowych testach na zestawie
iris nie doczekaliśmy się zjawiska przeuczenia).
Testy 7. - 11. dotyczą zestawu Iris, w którym zbiór treningowy składa
się ze 150 testów. Oczekiwanym wyjściem były odpowiednie wiersze macierzy jednostkowej o wymiarze 3, przyporządkowane poszczególnym wartością
cechy nominalnej (gatunku irysa). W przypadkach, w których wystąpił problem, dotyczył on tego samego, co mogłoby być problemem dla człowieka
rysującego krzywe podziału w zbiorze Iris - czyli odróżnianie specyficznych
osobników gatunku virginica od versicolor.
18
Na powyższym wykresie zaznaczony na żółto przypadek verisacolor został
zakwalifikowany jako virginica w teście 7., zaś zaznaczony na żółto przypadek
virginica został zakwalifikowany w teście 11. jako verisacolor. Ponadto, przypadek verisacolor zaznaczony na szaro stanowił w teście 7. pewien problem,
niepewność klasyfikacji (wynik znacząco różny do wektora jednostkowego,
z zauważalną składową wskazującą na virginica) - jednakże został zaklasyfikowany poprawnie, gdyż składowa wskazująca na verisacolor była największa.
Poza wnioskiem tak ogólnym jak powyższy, dotyczącym tego, co może
sprawić problem sieci neuronowej dokonującej zadania klasyfikacji, przeprowadzenie aż pięciu testów służyło oczywiście porównaniu skuteczności i szybkości otrzymywania zadowalająco małych błędów globalnych sieci dla różnych
liczebności warstw. Wszystkie próby były wykonywane z wykorzystaniem
neuronów obciążających, przy losowym podawaniu testów w poszczególnych
epokach. Aby uczynić wykresy porównywalnymi, różne konfiguracje testowano przez 200000 epok, lub - jeżeli konfiguracja składała się z wielu neuronów
i dawała dobre wyniki istotnie szybciej - 80000 epok.
Test 7. był próbą rozwiązania problemu za pomocą sieci o konfiguracji 4-3-3. Mimo obecności neuronów obciążających, sieć ta okazała się zbyt
uboga aby dokonać poprawnej klasyfikacji. Po 200000 epokach nauki, jeden
z irysów pozostał klasyfikowany błędnie, zaś inny - był klasyfikowany zauważalnie mało zdecydowanie.
Dodanie czwartego neuronu do warstwy ukrytej znacząco poprawiło szybkość nauki - dzięki temu w w teście 8. przy stosowanej metodzie przeprowadzania eksperymentów udało się nauczyć sieć klasyfikacji irysów już w nieco
poniżej 120000 epok. Patrząc na wagi drugiej i trzeciej warstwy można zaobserwować, że dla ostatnich trzech wyjść warstwy drugiej wagi w pierwszym
neuronie warstwy trzeciej są bliskie zeru, a w warstwie drugiej są liczbami
19
przeciwnymi do wag w warstwie trzeciej. Neurony 2-4 różnią się między sobą,
lecz z punktu widzenia warstwy wyjściowej wystarczyłoby rozważać pewną
sumę ważoną ich wyjść i korzystać z pojedynczej liczby wspólnej dla wszystkich neuronów warstwy wyjściowej. Poza tą liczbą oczywiście potrzebny jest
neuron 2.1 oraz bias. Może zatem konfiguracja 4-2-3 z biasem byłaby wystarczająca? Otóż jak pokazuje test 7., cztery neurony warstwy ukrytej są
jednak potrzebne aby proces nauki mógł się odbyć, nawet jeśli w końcowym
procesie nauczania znaczenie faktu, że neurony 2-4 są różne zostaje zatarte.
Test 9. pokazuje sprawność naszej implementacji w przypadku dodania
kolejnych warstw. Pomimo, że dane już w pierwszej warstwie ukrytej muszą być przepuszczone przez zaledwie trzy neurony, ze względu na rozmiar
drugiej warstwy ukrytej proces uczenia nie sprawia problemu, an nawet trwa
prawie dwa razy mniej epok niż w teście 8 (czyli niecałe 70000 epok). Zatem
dane przechodzące przez 3 neurony w pewnej warstwie ukrytej bez problemu
mogą posłużyć do klasyfikacji irysów, mimo że nie udało się to w teście 7.
Mimo znacznego zmniejszenia liczby epok w porównaniu do testu 8., należy
pamiętać, że czas obliczeń potrzebnych do przebiegu epoki wzrósł ze względu
na dodanie kolejnej warstwy neuronów.
Aby osiągnąć przyspieszenie nauki sieci, zamiast dodawać kolejne warstwy, można także dodać nadmiarowe neurony w warstwie ukrytej. Sieć 4-6-3
(test 10.) nauczyła się klasyfikować irysy w mniej niż 40000 epok, co stanowi
najlepszy z uzyskanych wyników. Duża liczba neuronów nie pozostaje jednak bez wpływu na czas obliczeń, więc nadal można się zastanawiać, która
ze struktur - niniejsza, zastosowana w teście 8., czy może w teście 9. - jest
najlepszym rozwiązaniem problemu. Może to zależeć na przykład od tego, czy
chcemy skoncentrować się na minimalizacji czasu obliczeń, czy może liczby
neuronów i związanego z nią zużycia pamięci. Dla tak małych sieci znaczenie
tego jest znikome, ale gdyby dwie liczne warstwy sąsiadowały ze sobą, zużycie
pamięci wzrosłoby znacznie - wtedy może opłacić się rozważanie utworzenia
dwóch warstw ukrytych.
Test 11. stanowi eksperyment na temat tego, do czego może doprowadzić znaczna przesada z liczbą warstw ukrytych. Mimo upływu 200000 epok
i chwilowego zmniejszenia maksymalnego błędu globalnego w epoce, sieć ta
nie zdołała nauczyć się całego zbioru danych - jeden z irysów pozostał klasyfikowany błędnie. Chwilowy spadek, a później - ponowny wzrost maksimum
błędu (czyli błędu na problematycznym irysie) jest zjawiskiem podobnym
do przeuczenia - jednakże w tym przypadku całkowite nauczenie sieci zbioru
treningowego nie nastąpiło wcale.
7. Wnioski
Podsumowując, na podstawie wyników i przedstawionej powyżej ich interpretacji wyciągnęliśmy następujące wnioski:
20
— Jeżeli w sieci występują warstwy składające się z niewielkiej liczby neuronów, użycie obciążenia jest nie tylko ułatwieniem, ale wręcz koniecznością.
— Umiarkowane podwyższanie współczynnika nauki oraz momentum pozwala przyspieszać proces nauczania.
— W przypadku spodziewanej dużej liczby epok, dobrze sprawdza się umiarkowany współczynnik nauki i duży współczynnik momentum (np. nauka
0, 2 i momentum 0, 9) - właśnie przy takich współczynnikach udało nam
się dokonać klasyfikacji zbioru Iris.
— Zastosowanie współczynnika momentum pozwala uniknąć występowania
lokalnych minimów, oraz wygładza przebieg nauki dla dużych zbiorów
testowych. Jego zastosowanie jest korzystne zwłaszcza podczas treningu
sieci on-line, oraz w sytuacjach w których mogłoby dojść do przeuczenia sieci. Ze względu na charakter wpływu momentum na zmiany wag
neuronu, często określa się je jako bezwładność wagi.
— Dla skomplikowanego zbioru treningowego często problemem może się
okazać pewien pojedynczy test - nie jest to za każdym razem ten sam
test, ale zawsze znajduje się on blisko płaszczyzn separacji, które można
by sobie próbować wyobrazić.
— Nawet jeżeli stosowane jest obciążenie, to jeżeli któraś warstwa ukryta będzie zawierała zbyt mało neuronów, rozróżnienie wymaganej liczby
unikalnych wyjść może okazać się niemożliwe.
— Odmienny od powyższego problem polega na tym, że sieć po prostu może
być zbyt uboga, aby proces nauki przebiegał skutecznie. Nawet jeżeli po
ukończonej nauce część neuronów okazuje się być nadmiarowa, są one
potrzebne do prawidłowego przebiegu procesu nauki.
— Dodanie dodatkowej warstwy ukrytej może poprawić szybkość uczenia,
ale jeszcze lepiej jest dodać równoległe neurony do istniejącej warstwy.
Jedynym argumentem za dodatkowymi warstwami może być zużycie pamięci, które maleje gdy rozległa warstwa zostaje rozbita na dwie mniejsze
(o ile nie okażą się one z kolei zbyt ubogie, aby rozróżnić wymaganą liczbę
różnorodnych wyjść).
— Utworzenie zbyt wielu warstw ukrytych uniemożliwia dostosowanie sieci
do kłopotliwych testów ze zbioru treningowego.
Literatura
[1] Ryszard Tadeusiewicz - Sieci neuronowe, Wyd. 2., Warszawa 1993
[2] “Learning and neural networks” [http://en.wikiversity.org/wiki/
Learning_and_neural_networks]
[3] UCI Machine Learning Repository Iris Data Set
21