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