Przenoszenie średniej sieci neuronowej


John Bullinarias Przewodnik krok po kroku dotyczący implementacji sieci neuronowej w C. Autor John A. Bullinaria ze Szkoły Informatyki Uniwersytetu w Birmingham w Wielkiej Brytanii. Niniejszy dokument zawiera przewodnik krok po kroku dotyczący implementacji prostej sieci neuronowej w C. Jest on skierowany głównie do studentów, którzy chcą (lub kazano im) włączyć element uczenia sieci neuronowej do większego systemu, który budują. Oczywiście istnieje wiele rodzajów sieci neuronowych, które można rozważyć - tutaj skoncentruję się na jednym szczególnie powszechnym i użytecznym typie, a mianowicie na prostej trójwarstwowej, równoległej sieci propagacji wstecznej (perceptron wielowarstwowy). Ten rodzaj sieci będzie przydatny, gdy mamy zestaw wektorów wejściowych i odpowiadający im zestaw wektorów wyjściowych, a nasz system musi wytworzyć odpowiednie wyjście dla każdego wprowadzonego sygnału wejściowego. Oczywiście, jeśli mamy już kompletny zestaw wektorów wejściowych i wyjściowych bez szumu, wystarczy prosty stolik przeglądowy. Jeśli jednak chcemy, aby system się uogólnił. tj. wytwarzają odpowiednie wyjścia dla danych wejściowych, których nigdy wcześniej nie widzieli, a następnie sieć neuronowa, która nauczyła się mapować między znanymi wejściami i wyjściami (to jest nasz zestaw treningowy) będzie często wykonywać całkiem dobrą pracę również dla nowych sygnałów wejściowych. Zakładam, że czytelnik jest już zaznajomiony z C, a po więcej informacji na temat sieci neuronowych w ogóle, po prostu odsyłaj czytelnika do grup dyskusyjnych comp. ai. neural-net i związanych z nimi FAQ sieci neuronowych. Zacznijmy więc. Pojedynczy neuron (to znaczy jednostka przetwarzająca) pobiera całkowite wejście i generuje wyjściowe wyjście aktywacyjne. Przyjmę, że jest to funkcja sigmoidalna, chociaż często wykorzystywane są inne funkcje aktywujące (np. Styczna liniowa lub hiperboliczna). Efektem tego jest zgniecenie nieskończonego zakresu In w zakresie od 0 do 1. Ma on również dogodną właściwość, że jego pochodna przyjmuje szczególnie prostą postać SigmoidDerivative Sigmoid (1.0 - Sigmoid). Zazwyczaj wejście do danego neuronu będzie ważoną sumą aktywacji wyjściowych zasilających z szeregu innych neuronów. Dogodnie jest myśleć o aktywacjach przepływających przez warstwy neuronów. Tak więc, jeśli w warstwie 1 znajdują się neurony NumUnits1, całkowita aktywacja wpływająca do neuronu warstwy 2 jest tylko sumą nad warstwą Layer1OutiWeighti. gdzie Weighti jest siłą ciężkości połączenia między jednostką i w warstwie 1 a naszą jednostką w warstwie 2. Każdy neuron będzie również miał stan uprzedzenia lub spoczynku, który jest dodawany do sumy wejść, i wygodnie jest wywoływać ten ciężar0 . Następnie możemy napisaćLayer2In Waga0 zacząć od odchylenia dla (i 1 i lt NumUnits1 i) Warstwa2In Layer1Outi Weighti dodać ważony wkład z warstwy 1 Layer2Out 1.0 (1.0 exp (-Layer2In)) wyliczyć sigmoid, aby dać aktywację Normalnie warstwa 2 będzie miała wiele jednostek jak również, więc należy napisać wagi między jednostką i w warstwie 1 i jednostką j w warstwie 2 jako tablicą Weightij. Tak więc, aby uzyskać wyjście jednostki j w warstwie 2, mamy Layer2Inj Weight0j dla (i 1 i lt NumUnits1 i) Layer2Inj Layer1Outi Weightij Layer2Outj 1.0 (1.0 exp (-Layer2Inj)) Pamiętaj, że w C indeksy tablicy zaczynają się od zera, a nie od 1 , więc zadeklarowalibyśmy nasze zmienne asdouble Layer1OutNumUnits11 double Layer2InNumUnits21 double Layer2OutNumUnits21 double WeightNumUnits11NumUnits21 (lub, bardziej prawdopodobne, zadeklaruj wskaźniki i użyj calloc lub malloc do przydzielenia pamięci). Oczywiście, potrzebujemy kolejnej pętli, aby uzyskać wszystkie wyjścia warstwy 2 (j 1 j lt NumUnits2 j) Layer2Inj Weight0j for (i 1 i lt NumUnits1 i) Layer2Inj Layer1Outi Weightij Layer2Outj 1.0 (1.0 exp (-Layer2Inj)) Konieczne są sieci trójwarstwowe i wystarczające dla większości celów, więc nasze wyjścia z warstwy 2 są wprowadzane do trzeciej warstwy w ten sam sposób, jak powyżej. Kod może się w tym momencie zacząć zagmatwać - uważam, że zachowanie osobnego indeksu i, j, k dla każdej warstwy pomaga, podobnie jak intuicyjna notacja dla rozróżnienia między różnymi warstwami wagi Weight12 i Weight23. Z oczywistych względów w przypadku sieci trójwarstwowych tradycyjne jest wywoływanie warstwy 1 jako warstwy wejściowej, warstwy 2 - warstwy ukrytej i warstwy 3 - warstwy wyjściowej. Nasza sieć przyjmuje więc znaną formę, której będziemy używać w dalszej części tego dokumentu. Również, aby zapisać pomyłki In i Out, możemy napisać LayerNIn jako SumN. Nasz kod może więc zostać zapisany Generalnie będziemy mieli cały zestaw wzorców treningowych NumPattern, tj. Pary wejściowych i docelowych wektorów wyjściowych, oznaczonych przez indeks p. Sieć uczy się, minimalizując pewną miarę błędu rzeczywistych mocy sieci w porównaniu z wyjściami docelowymi. Na przykład błąd sumy kwadratów dla wszystkich jednostek wyjściowych k i wszystkich wzorców trenowania p zostanie określony przez Błąd 0.0 dla (p 1 p lt NumPattern p) dla (k 1 k lt NumOutput k) Błąd 0.5 (Targetpk - Outputpk) (Targetpk - Outputpk) (Współczynnik 0,5 jest standardowo uwzględniany w celu uproszczenia algebry w tworzeniu algorytmu uczenia się.) Jeśli wstawimy powyższy kod do obliczenia wyjść sieciowych do pętli p tego, kończymy z Ill pozostawiając czytnik do dozowania z dowolnymi wskaźnikami, których nie potrzebują do celów własnego systemu (np. indeksy SumH i SumO). Następnym etapem jest iteracyjne dopasowanie wag w celu zminimalizowania błędu sieci. Standardowy sposób to zrobić przez nachylenie gradientu na funkcji błędu. Możemy obliczyć, jak bardzo błąd zmienia się przez niewielką zmianę w każdej wadze (tzn. Obliczyć częściowe pochodne d Błąd d Waga) i przesunąć ciężary o niewielką ilość w kierunku, który zmniejsza błąd. W literaturze jest mnóstwo wariacji na temat tego ogólnego podejścia - zacznę od standardowej propagacji wstecznej on-line z algorytmem pędu. To nie jest miejsce, w którym można przejść przez całą matematykę, ale dla powyższego błędu sumy kwadratów możemy obliczyć i zastosować jedną iterację (lub epokę) wymaganych zmian wagi DeltaWeightIH i DeltaWeightHO przy użyciu Error 0.0 dla (p 1 p lt NumPattern p) for (j 1 j lt NumHidden j) SumHpj WeightIH0j for (i 1 i lt NumInput i) SumHpj Inputpi WeightIHij Hiddenpj 1.0 (1.0 exp (-SumHpj)) for (k 1 k lt NumOutput k) SumOpk WeightHO0k for (j 1 j lt NumHidden j) SumOpk Hiddenpj WeightHOjk Outputpk 1.0 (1.0 exp (-SumOpk)) Błąd 0.5 (Targetpk - Outputpk) (Targetpk - Outputpk) DeltaOk (Targetpk - Outputpk) Outputpk (1.0 - Outputpk) dla (j 1 j lt NumHidden j) SumDOWj 0.0 dla (k 1 k lt NumOutput k) SumDOWj WeightHOjk DeltaOk DeltaHj SumDOWj Hiddenpj (1.0 - Hiddenpj) dla (j 1 j lt NumHidden j) DeltaWeightIH0j eta DeltaHj alfa DeltaWeightIH0j WeightIH0j DeltaWeightIH0j dla (i 1 i lt NumInput i) DeltaWeightIHij eta Inputpi DeltaHj alpha DeltaWeightIHij WeightIHij DeltaWeightIHij dla (k 1 k lt NumOutput k) DeltaWeightHO0k eta DeltaOk alfa DeltaWeightHO0k WeightHO0k DeltaWeightHO0k for (j 1 j lt NumHidden j) DeltaWeightHOjk eta Hiddenpj DeltaOk alfa DeltaWeightHOjk WeightHOjk DeltaWeightHOjk (Jest wyraźnie wiele możliwości ponownego uporządkowania, łącząc i upraszczając pętle - pozostawiam to do przeczytania, gdy zrozumieją, co robią oddzielne sekcje kodu.) Zmiany masy DeltaWeightIH i DeltaWeightHO składają się z dwóch komponentów. Po pierwsze, składnik eta, który jest wkładem gradientowego spadku. Po drugie, składnik alfa, który jest terminem dynamicznym, który skutecznie utrzymuje średnią ruchomą masę gradientową, wpływa na zmianę składu, a tym samym wygładza ogólne zmiany masy. Ustalanie dobrych wartości parametrów uczenia się eta i alfa jest zwykle kwestią próby i błędu. Z pewnością alfa musi należeć do zakresu od 0 do 1, a niezerowa wartość zwykle przyspiesza proces uczenia się. Znalezienie dobrej wartości dla eta zależy od problemu, a także od wartości wybranej dla alfa. Jeśli zostanie ustawiony zbyt nisko, trening będzie niepotrzebnie powolny. Ponieważ jest zbyt duży, spowoduje to gwałtowne wahania masy ciała i może spowolnić lub nawet całkowicie uniemożliwić naukę. (Zwykle zaczynam od wypróbowania eta 0.1 i zbadania efektów wielokrotnego podwojenia lub zmniejszenia o połowę.) Pełny proces treningowy będzie polegał na powtórzeniu powyższych aktualizacji wagi dla wielu epok (przy użyciu innej pętli), dopóki nie zostanie spełniony warunek błędu, na przykład błąd spada poniżej wybranej małej liczby. (Zauważ, że z sigmoidami na wyjściach, błąd może osiągnąć dokładnie zero, jeśli ciężary osiągną nieskończoność. Pamiętaj także, że czasami trening może utknąć w lokalnym minimum funkcji błędu i nigdy nie osiągać najmniejszego rzeczywistego minimum.) Tak więc, musimy zawinąć ostatni blok kodu w coś podobnego do (epok 1 epok lt LARGENUMBER epoka) POWYŻSZY KOD DO JEDNEJ ITERACJI, jeśli (Błąd lt SMALLNUMBER) przerwie Jeśli wzorce treningowe są prezentowane w tej samej systematycznej kolejności podczas każdej epoki, to możliwe do wystąpienia oscylacji wagi. Dlatego dobrym pomysłem jest użycie nowej kolejności losowej dla wzorców treningowych dla każdej epoki. Jeśli umieścimy wzorzec treningowy NumPattern p w losowej kolejności w macierz ranpat. to jest po prostu kwestia wymiany naszej pętli wzorców treningowych Generowanie losowej tablicy ranpat nie jest takie proste, ale poniższy kod wykona zadanie Naturalnie należy ustawić początkowe masy sieci, aby rozpocząć proces uczenia. Uruchamianie wszystkich wag o wartości zerowej zazwyczaj nie jest dobrym pomysłem, ponieważ jest to często lokalne minimum funkcji błędu. Normalne jest inicjowanie wszystkich wag za pomocą małych losowych wartości. Jeśli rando () jest twoją ulubioną funkcją generatora liczb losowych, która zwraca płaski rozkład liczb losowych z zakresu od 0 do 1, a smallwt to maksymalny bezwzględny rozmiar twoich początkowych wag, wtedy odpowiednią sekcją kodu inicjalizacji wagi będzie Uwaga, dobrym pomysłem jest ustawienie wszystkich początkowych wartości DeltaWeights na zero w tym samym czasie. Mamy teraz wystarczająco dużo kodu, aby stworzyć działający program sieci neuronowej. Wyciąłem i wkleiłem powyższy kod do pliku nn. c (który twoja przeglądarka powinna pozwolić ci na zapisanie do twojej własnej przestrzeni plików). Dodałem, że standardowe obejmuje, zadeklarowane wszystkie zmienne, zakodowane na stałe standardowe dane treningowe XOR i wartości dla eta. alpha i smallwt. zdefiniowane przez proste rando (). dodał kilka instrukcji drukowania, aby pokazać, co robi sieć, i zapakował całą partię w main (). Plik powinien zostać skompilowany i uruchomiony w normalny sposób (np. Przy użyciu poleceń systemu UNIX cc nn. c - O - lm - o nn i nn). Ive zostawił wiele dla czytelnika do zrobienia, aby przekształcić to w przydatny program, na przykład: Czytaj dane treningowe z pliku Zezwalaj na zmianę parametrów (np. Alfa, smallwt. NumHidden itp.) W czasie wykonywania. i przydzielać im pamięć podczas pracy Zapisywanie wag do pliku i ponowne ich wczytanie Wykreślanie błędów, aktywacji wyjścia itp. podczas szkolenia Istnieje również wiele odmian sieci, które można wdrożyć, na przykład: uczenie się w trybie wsadowym, a nie w trybie on-line. line learning Alternatywne funkcje aktywacji (liniowe, tanh, itp.) Rzeczywiste (a nie binarne) wartościowe wyjścia wymagają liniowych funkcji wyjściowych Outputpk SumOpk DeltaOk Targetpk - Outputpk Funkcja kosztu krzyża-entropii zamiast błędu sumy kwadratów błędu - (dziennik docelowy (Outputpk) ( 1.0 - Targetpk) log (1.0 - Outputpk)) DeltaOk Targetpk - Outputpk Oddzielne zestawy treningowe, walidacyjne i testowe Rozkład masy Regulacja Ale od tego momentu jesteś sam. Mam nadzieję, że ta strona była przydatna. Tę stronę prowadzi John Bullinaria. Ostatnia aktualizacja: 18 listopada 2002 r. Naukowiec i inżynier Przewodnik po cyfrowym przetwarzaniu sygnału Autor: Steven W. Smith, Ph. D. Rozdział 26: Sieci neuronowe (i nie tylko) Architektura sieci neuronowej Ludzie i inne zwierzęta przetwarzają informacje w sieciach neuronowych. Powstają one z trylionów neuronów (komórek nerwowych) wymieniających krótkie impulsy elektryczne zwane potencjałami czynnościowymi. Algorytmy komputerowe, które naśladują te struktury biologiczne, są formalnie nazywane sztucznymi sieciami neuronowymi, aby odróżnić je od gąbczastych rzeczy wewnątrz zwierząt. Jednak większość naukowców i inżynierów nie jest taka formalna i używa terminu sieć neuronowa, aby uwzględnić zarówno systemy biologiczne, jak i niebiologiczne. Badania sieci neuronowej są motywowane przez dwa pragnienia: uzyskanie lepszego zrozumienia ludzkiego mózgu i opracowanie komputerów, które mogą radzić sobie z abstrakcyjnymi i źle zdefiniowanymi problemami. Na przykład, konwencjonalne komputery mają problemy ze zrozumieniem mowy i rozpoznawania twarzy ludzi. Dla porównania ludzie wykonują bardzo dobrze te zadania. Wybrano wiele różnych struktur sieci neuronowych, niektóre oparte na naśladowaniu tego, co biolog widzi pod mikroskopem, inne oparte na matematycznej analizie problemu. Najczęściej stosowaną strukturę pokazano na rys. 26-5. Ta sieć neuronowa jest utworzona w trzech warstwach, nazywanych warstwą wejściową, warstwą ukrytą i warstwą wyjściową. Każda warstwa składa się z jednego lub więcej węzłów. reprezentowane w tym diagramie przez małe kółka. Linie między węzłami wskazują przepływ informacji z jednego węzła do drugiego. W tym szczególnym typie sieci neuronowej informacja przepływa tylko z wejścia na wyjście (czyli od lewej do prawej). Inne typy sieci neuronowych mają bardziej skomplikowane połączenia, takie jak ścieżki zwrotne. Węzły warstwy wejściowej są pasywne. co oznacza, że ​​nie modyfikują danych. Otrzymują pojedynczą wartość na swoim wejściu i duplikują wartość do swoich wielu wyjść. Dla porównania aktywne są węzły warstwy ukrytej i wyjściowej. Oznacza to, że modyfikują dane, jak pokazano na Rys. 26-6. Zmienne: X1 1, X1 2 8230 X1 15 przechowują dane do oceny (patrz: rys. 26-5). Na przykład mogą to być wartości pikseli z obrazu, próbki z sygnału audio, ceny giełdowe w kolejnych dniach itd. Mogą to być również wyniki innego algorytmu, takiego jak klasyfikatory w naszym przykładzie wykrywania raka: średnica, jasność, ostrość krawędzi itp. Każda wartość z warstwy wejściowej jest duplikowana i wysyłana do wszystkich ukrytych węzłów. Nazywa się to w pełni połączoną strukturą. Jak pokazano na rys. 26-6, wartości wchodzące do ukrytego węzła są mnożone przez wagi. zestaw wstępnie określonych numerów przechowywanych w programie. Ważone dane wejściowe są następnie dodawane, aby wytworzyć pojedynczą liczbę. Jest to pokazane na schemacie symbolem, sumą. Przed opuszczeniem węzła liczba ta jest przekazywana przez nieliniową funkcję matematyczną zwaną sigmoidą. Jest to krzywa w kształcie litery S, która ogranicza wydajność węzłów. Oznacza to, że wejście do sigmoidy jest wartością między - infin i infin, podczas gdy jej wyjście może wynosić tylko od 0 do 1. Wyjścia z ukrytej warstwy są reprezentowane na diagramie przepływu (rys. 26-5) przez zmienne: X2 1, X2 2, X2 3 i X2 4. Tak jak poprzednio, każda z tych wartości jest powielana i stosowana do następnej warstwy. Aktywne węzły warstwy wyjściowej łączą i modyfikują dane, aby wytworzyć dwie wartości wyjściowe tej sieci: X3 1 i X3 2. Sieci neuronowe mogą mieć dowolną liczbę warstw i dowolną liczbę węzłów na warstwę. Większość aplikacji korzysta z trójwarstwowej struktury z maksymalnie kilkoma wejściowymi węzłami. Ukryta warstwa ma zwykle około 10 rozmiaru warstwy wejściowej. W przypadku wykrywania celu warstwa wyjściowa wymaga tylko jednego węzła. Wyjście tego węzła jest progowane, aby zapewnić dodatnie lub ujemne wskazanie obecności celów lub nieobecności w danych wejściowych. Tabela 26-1 to program do przeprowadzenia schematu blokowego z rys. 26-5. Kluczową kwestią jest to, że ta architektura jest bardzo prosta i bardzo uogólniona. Ten sam schemat przepływu może być stosowany do wielu problemów, niezależnie od ich szczególnych cech. Zdolność sieci neuronowej do zapewnienia użytecznej manipulacji danymi polega na właściwym doborze wag. Jest to dramatyczne odejście od konwencjonalnego przetwarzania informacji, w którym rozwiązania opisano w procedurach krok po kroku. Jako przykład wyobraź sobie sieć neuronową do rozpoznawania obiektów w sygnale sonarowym. Załóżmy, że 1000 próbek z sygnału jest przechowywanych w komputerze. W jaki sposób komputer określa, czy dane te reprezentują łódź podwodną, ​​wieloryby, podmorskie góry, czy w ogóle nic Konwencjonalny procesor DSP podchodzi do tego problemu z matematyką i algorytmami, takimi jak analiza widm korelacji i częstotliwości. W sieci neuronowej 1000 próbek jest po prostu wprowadzanych do warstwy wejściowej, co powoduje, że wartości wychodzą z warstwy wyjściowej. Wybierając odpowiednie masy, dane wyjściowe można skonfigurować tak, aby przekazywały szeroki zakres informacji. Na przykład mogą być wyjścia dla: łodzi podwodnej (yesno), wieloryba (yesno), podmorskiej góry (yesno) itp. Przy innych wagach wyjścia mogą klasyfikować obiekty jako: metal lub niemetal, biologiczny lub niebiologiczny, wróg lub sojusznika, itp. Brak algorytmów, brak reguł, brak procedur tylko związek między wejściem i wyjściem dyktowane przez wartości wybranych wag. Rysunek 26-7a pokazuje bliżej funkcję sigmoidalną, opisaną matematycznie przez równanie: Dokładny kształt sigmoidy nie jest ważny, tylko że jest to gładki próg. Dla porównania prosta wartość progowa daje wartość 1, gdy x gt 0, a wartość zero, gdy x lt 0. Sigmoid wykonuje tę samą podstawową funkcję progowania, ale jest również różniczkowalna. jak pokazano na rys. 26-7b. Podczas gdy pochodna nie jest używana na schemacie przepływowym (ryc. 25-5), jest to kluczowa część znalezienia odpowiednich ciężarków do użycia. Więcej o tym wkrótce. Zaletą esicy jest to, że istnieje skrót do obliczania wartości jej pochodnej: Na przykład, jeśli x 0, to s (x) 0,5 (przez równanie 26-1) i pierwsza pochodna jest obliczana: s ( x) 0,5 (1 - 0,5) 0,25. To nie jest krytyczna koncepcja, tylko sztuczka, aby algebra była krótsza. Gdyby sieć neuronowa była bardziej elastyczna, gdyby sigmoid mógł być regulowany w lewo lub w prawo, dzięki czemu byłby skoncentrowany na innej wartości niż x 0 Odpowiedź brzmi tak, a większość sieci neuronowych pozwala na to. Jest bardzo prosty w implementacji dodatkowy węzeł jest dodawany do warstwy wejściowej, z jej wejściem zawsze mającym wartość jeden. Gdy zostanie pomnożona przez ciężary ukrytej warstwy, zapewnia przesunięcie (przesunięcie DC) do każdego sigmoidu. Ten dodatek jest nazywany węzłem odchylenia. Jest traktowany tak samo jak inne węzły, z wyjątkiem stałego wejścia. Czy sieci neuronowe mogą być tworzone bez sigmoidalnej lub podobnej nieliniowości Aby odpowiedzieć na to, spójrz na trójwarstwową sieć z Rys. 26-5. Jeśli sigmoidy nie byłyby obecne, trzy warstwy zapadłyby się tylko w dwie warstwy. Innymi słowy, sumy i masy warstw ukrytych i wyjściowych można połączyć w jedną warstwę, co daje w rezultacie tylko dwuwarstwową sieć. Naukowiec i inżynier Przewodnik po cyfrowym przetwarzaniu sygnału Autor: Steven W. Smith, Ph. D. Rozdział 26: Sieci neuronowe (i nie tylko) Szkolenie sieci neuronowej Projektowanie sieci neuronowych najlepiej wyjaśnić na przykładzie. Rysunek 26-8 pokazuje problem, który będziemy atakować, identyfikując poszczególne litery w obrazie tekstu. To zadanie rozpoznawania wzorców zyskało dużą uwagę. Łatwo jest dojść do tego, że wiele podejść osiąga częściowy sukces, ale na tyle trudne, że nie ma doskonałych rozwiązań. Wiele udanych produktów komercyjnych opierało się na tym problemie, takich jak: czytanie adresów na literach do kierowania drogą pocztową, wprowadzanie dokumentów do edytorów tekstu itp. Pierwszym krokiem w rozwoju sieci neuronowej jest stworzenie bazy danych przykładów. W przypadku problemu z rozpoznawaniem tekstu można to zrobić, drukując 26 wielkich liter: A, B, C, D 8230 Y, Z, 50 razy na arkuszu papieru. Następnie, te 1300 liter są konwertowane na obraz cyfrowy za pomocą jednego z wielu urządzeń do skanowania dostępnych dla komputerów osobistych. Ten duży cyfrowy obraz jest następnie dzielony na małe obrazy o rozmiarach 10 X 10 pikseli, z których każdy zawiera pojedynczą literę. Ta informacja jest przechowywana jako baza danych o wielkości 1,3 megabajta: 1300 obrazów 100 pikseli na obrazie 8 bitów na piksel. Będziemy wykorzystywać pierwsze 260 obrazów w tej bazie danych do szkolenia sieci neuronowej (to znaczy określania masy), a resztę do testowania jej wydajności. Baza danych musi również zawierać sposób identyfikacji litery zawartej w każdym obrazie. Na przykład dodatkowy bajt można dodać do każdego obrazu 10x10, zawierającego kod ASCII liter. W innym schemacie położenie każdego obrazu 10x10 w bazie danych może wskazywać, czym jest ta litera. Na przykład, obrazy od 0 do 49 mogą być wszystkie A, obrazy 50-99 mogą być wszystkie B, itp. Dla tej demonstracji, sieć neuronowa będzie zaprojektowana dla dowolnego zadania: określić, które z 10 obrazów 10 zawiera samogłoskę. tj. A, E, I, O lub U. Może to nie mieć praktycznego zastosowania, ale ilustruje zdolność sieci neuronowej do uczenia się bardzo abstrakcyjnych problemów z rozpoznawaniem wzorców. Dzięki uwzględnieniu dziesięciu przykładów każdej litery w zbiorze treningowym, sieć (mam nadzieję) nauczy się kluczowych cech, które odróżniają cel od nieokreślonych obrazów. Sieć neuronowa użyta w tym przykładzie jest tradycyjną, trójwarstwową, w pełni połączoną architekturą, jak pokazano na Ryc. 26-5 i 26-6. W warstwie wejściowej znajduje się 101 węzłów (wartości 100 pikseli plus węzeł odchylenia), 10 węzłów w warstwie ukrytej i 1 węzeł w warstwie wyjściowej. Kiedy obraz o rozdzielczości 100 pikseli zostanie zastosowany na wejściu sieci, chcemy, aby wartość wyjściowa była zbliżona do jednej, jeśli występuje samogłoska, i bliska zeru, jeśli nie ma samogłoski. Nie martw się, że sygnał wejściowy został pozyskany jako dwuwymiarowa tablica (10 razy 10), podczas gdy wejście do sieci neuronowej jest tablicą jednowymiarową. To jest twoje zrozumienie, w jaki sposób wartości pikseli są ze sobą powiązane, sieć neuronowa znajdzie własne relacje. Tabela 26-2 pokazuje główny program do obliczania wag sieci neuronowej, z Tabelą 26-3 zawierającą trzy podprogramy wywoływane z programu głównego. Elementy tablicy: od X11 do X1100, trzymaj wartości warstwy wejściowej. Ponadto X1101 zawsze ma wartość 1, dostarczając dane wejściowe do węzła bias. Wartości wyjściowe z ukrytych węzłów są zawarte w elementach tablicy: od X21 do X210. Zmienna X3 zawiera wartość wyjściową sieci. Masy ukrytej warstwy są zawarte w tablicy WH. , gdzie pierwszy indeks identyfikuje ukryty węzeł (1 do 10), a drugi indeks jest węzłem warstwy wejściowej (od 1 do 101). Wagi warstwy wyjściowej są przechowywane w WO1 do WO10. To daje w sumie 1020 wartości wagi, które określają sposób działania sieci. Pierwszą akcją programu jest ustawienie każdej masy do dowolnej wartości początkowej za pomocą generatora liczb losowych. Jak pokazano w liniach od 190 do 240, wadze ukrytych warstw przypisywane są wartości początkowe od -0 0005 do 0,0005, a masy warstwy wyjściowej od -0,5 do 0,5. Zakresy te są wybierane tak, aby miały taki sam rząd wielkości, jaki muszą mieć końcowe wagi. Oparte jest to na: (1) zakresie wartości w sygnale wejściowym, (2) liczbie wejść sumowanych w każdym węźle, oraz (3) zakresie wartości, nad którymi sigmoid jest aktywny, wejściu około -5 lt x lt 5 i wyjście z 0 do 1. Na przykład, gdy 101 wejść o typowej wartości 100 zostanie pomnożonych przez typową wartość wagową 0,0002, suma produktów wynosi około 2, czyli w aktywnym zakresie wejścia sigmoidów. Gdybyśmy ocenili wydajność sieci neuronowej za pomocą tych losowych wag, oczekiwalibyśmy, że będzie to to samo, co przypadkowe zgadywanie. Algorytm uczenia się poprawia wydajność sieci, stopniowo zmieniając każdy ciężar we właściwym kierunku. Nazywa się to procedurą iteratywną i jest kontrolowane w programie przez pętlę FOR-NEXT w liniach 270-400. Każda iteracja sprawia, że ​​ciężary są nieco bardziej efektywne przy oddzielaniu celu od przykładów niezwiązanych. Pętla iteracji jest zwykle przeprowadzana, dopóki nie zostaną wprowadzone dalsze ulepszenia. W typowych sieciach neuronowych może to być od dziesięciu do dziesięciu tysięcy iteracji, ale kilkaset jest wspólnych. Ten przykład wykonuje 800 iteracji. Aby ta iteracyjna strategia działała, musi istnieć jeden parametr, który opisuje, jak dobrze obecnie działa system. Zmienna ESUM (suma błędów) obsługuje tę funkcję w programie. Pierwszą czynnością w pętli iteracji jest ustawienie wartości zerowej ESUM (linia 290), aby mogła być używana jako akumulator. Na końcu każdej iteracji wartość ESUM jest drukowana na ekranie wideo (linia 380), tak aby operator mógł zapewnić, że postęp jest wykonywany. Wartość ESUM zacznie się wysoka i stopniowo spadnie, gdy sieć neuronowa zostanie przeszkolona do rozpoznawania celów. Rysunek 26-9 pokazuje przykłady zmniejszania się ESUM w miarę postępu iteracji. Wszystkie 260 obrazów w zbiorze treningowym jest ocenianych podczas każdej iteracji kontrolowanej przez pętlę FOR-NEXT w liniach 310-360. Podprogram 1000 służy do wyszukiwania obrazów z bazy przykładów. Ponieważ nie jest to tutaj szczególnie interesujące, opiszemy tylko parametry przekazywane do tego podprogramu iz tego podprogramu. Podprogram 1000 jest wprowadzany z parametrem LETTER, będącym pomiędzy 1 a 260. Po powrocie wartości węzłów wejściowych, od X11 do X1100, zawierają wartości pikseli obrazu w bazie danych odpowiadającej LITOWI. Wartość węzła odchylenia, X1101, jest zawsze zwracana ze stałą wartością równą jeden. Podprogram 1000 również zwraca inny parametr, PRAWIDŁOWO. Zawiera pożądaną wartość wyjściową sieci dla tej konkretnej litery. Oznacza to, że jeśli litera na obrazku jest samogłoską, KOREKT zostanie zwrócony z wartością równą jeden. Jeśli litera na obrazku nie jest samogłoską, funkcja CORRECT zostanie zwrócona z wartością zero. Po przetworzeniu obrazu jest ładowany do X11 do X1100, podprogram 2000 przekazuje dane przez bieżącą sieć neuronową, aby wytworzyć wartość węzła wyjściowego, X3. Innymi słowy, podprogram 2000 jest taki sam jak program w Tabeli 26-1, z wyjątkiem innej liczby węzłów w każdej warstwie. Ta podprocedura oblicza również, jak dobrze obecna sieć identyfikuje literę jako cel lub niedocelową. W linii 2210 zmienna ELET (dla litery błędu) jest obliczana jako różnica między faktycznie wygenerowaną wartością wyjściową, X3, a pożądaną wartością, CORRECT. To sprawia, że ​​ELET ma wartość pomiędzy -1 a 1. Wszystkie 260 wartości dla ELET są połączone (linia 340), aby utworzyć ESUM, całkowity kwadrat błędu sieci dla całego zestawu treningowego. Wiersz 2220 pokazuje opcję, która jest często uwzględniana przy obliczaniu błędu: przypisywanie różnej ważności błędom w przypadku celów i niedokładności. Na przykład przywołaj przykład raka przedstawiony wcześniej w tym rozdziale i konsekwencje popełnienia błędu fałszywie dodatniego w porównaniu z błędem fałszywie ujemnym. W tym przykładzie arbitralnie zadeklarujemy, że błąd w wykryciu celu jest pięć razy mniejszy niż błąd w wykrywaniu niedokładności. W efekcie oznacza to, że sieć wykonuje lepszą pracę z celami, nawet jeśli szkodzi to działaniu nieukierunkowanych elementów. Podprogram 3000 jest sercem strategii sieci neuronowej, algorytmem zmiany wag w każdej iteracji. Użyjemy analogii do wyjaśnienia podstawowej matematyki. Rozważmy sytuację, w której wojskowy spadochroniarz spadł za liniami wroga. Spadł na ziemię w nieznanym terenie, ale okazało się, że jest tak ciemno, że nie widzi więcej niż kilka metrów od niego. Jego rozkazy mają iść na dno najbliższej doliny, aby rozpocząć pozostałą część jego misji. Problem polega na tym, że nie będąc w stanie dojrzeć więcej niż kilka stóp, jak trafia on na dno doliny Innymi słowy, potrzebuje algorytmu, aby dostosować swoje położenie xiy na powierzchni Ziemi, aby zminimalizować jego wysokość . Jest to analogiczne do problemu dostosowania sieci neuronowej, tak aby zminimalizować błąd sieci, ESUM. Przyjrzymy się dwóm algorytmom, aby rozwiązać ten problem: ewolucja i najbardziej strome zejście. W ewolucji spadochroniarz wykonuje lotny skok w przypadkowym kierunku. Jeśli nowa elewacja jest wyższa od poprzedniej, przeklina i wraca do swojej początkowej lokalizacji, gdzie próbuje ponownie. Jeśli nowa elewacja jest mniejsza. Czuje miarę sukcesu i powtarza proces z nowej lokalizacji. Ostatecznie dotrze do dna doliny, choć na bardzo nieefektywnej i przypadkowej ścieżce. Metoda ta nazywana jest ewolucją, ponieważ jest to ten sam rodzaj algorytmu, który stosuje natura w ewolucji biologicznej. Każda nowa generacja gatunku ma losowe odmiany. Jeżeli różnice te są korzystne dla gatunku, są bardziej prawdopodobne, że zostaną zatrzymane i przekazane następnemu pokoleniu. Jest to wynikiem ulepszenia pozwalającego zwierzęciu na otrzymywanie większej ilości pokarmu, ucieczkę przed wrogami, produkowanie większej ilości potomstwa itp. Jeśli nowa cecha jest szkodliwa, zwierzę znajdujące się w niekorzystnej sytuacji staje się obiadem dla jakiegoś drapieżnika, a odmiana jest odrzucana. W tym sensie każde nowe pokolenie jest iteracją ewolucyjnej procedury optymalizacji. Kiedy ewolucja jest używana jako algorytm treningowy, każda waga w sieci neuronowej jest nieznacznie zmieniana przez dodanie wartości z generatora liczb losowych. Jeżeli zmodyfikowane wagi tworzą lepszą sieć (tj. Niższą wartość dla ESUM), zmiany są zachowywane, w przeciwnym razie są odrzucane. Podczas gdy to działa, bardzo powoli się konwerguje. Jest to żargon używany do opisania ciągłego doskonalenia w kierunku optymalnego rozwiązania (dno doliny). W uproszczeniu program potrzebuje kilku dni na rozwiązanie, a nie minut czy godzin. Na szczęście najostrzejszy algorytm schodzenia jest znacznie szybszy. W ten sposób spadochroniarz naturalnie zareaguje: oceni, która droga jest z górki. i poruszaj się w tym kierunku. Pomyśl o tej sytuacji w ten sposób. Spadochroniarz może przesunąć się o jeden krok na północ i odnotować zmianę wysokości. Po powrocie do swojej pierwotnej pozycji może wykonać jeden krok na wschód i odnotować zmianę wysokości. Używając tych dwóch wartości, może określić, który kierunek jest z górki. Załóżmy, że spadochroniarz spadnie o 10 cm, gdy wykona jeden krok w kierunku północnym i spadnie o 20 cm, gdy wykona jeden krok w kierunku wschodnim. Aby podróżować bezpośrednio z góry, musi poruszać się wzdłuż każdej osi proporcjonalnie do nachylenia wzdłuż tej osi. W takim przypadku może przesunąć się na północ o 10 kroków i na wschód o 20 kroków. To przesuwa go w dół po najbardziej stromej części zbocza na odległość 10 2 20 kroków. Alternatywnie, mógł poruszać się w linii prostej do nowej lokalizacji, 22,4 kroków po przekątnej. Najważniejsze jest to, że najdalsze zejście osiąga się, przesuwając wzdłuż każdej osi odległość proporcjonalną do nachylenia wzdłuż tej osi. Subroutine 3000 implementuje ten sam najostrzejszy przyzwoity algorytm dla sieci. Before entering subroutine 3000, one of the example images has been applied to the input layer, and the information propagated to the output. This means that the values for: X1 , X2 and X3 are all specified, as well as the current weight values: WH. and WO . In addition, we know the error the network produces for this particular image, ELET. The hidden layer weights are updated in lines 3050 to 3120, while the output layer weights are modified in lines 3150 to 3190. This is done by calculating the slope for each weight, and then changing each weight by an amount proportional to that slope . In the paratrooper case, the slope along an axis is found by moving a small distance along the axis (say, Delta x ), measuring the change in elevation (say, Delta E ), and then dividing the two (Delta E Delta x ). The slope of a neural network weight can be found in this same way: add a small increment to the weight value (Delta w ), find the resulting change in the output signal (Delta X3 ), and divide the two (Delta X3 Delta w ). Later in this chapter we will look at an example that calculates the slope this way. However, in the present example we will use a more efficient method. Earlier we said that the nonlinearity (the sigmoid) needs to be differentiable . Here is where we will use this property. If we know the slope at each point on the nonlinearity, we can directly write an equation for the slope of each weight (Delta X3 Delta w) without actually having to perturb it. Consider a specific weight, for example, WO1, corresponding to the first input of the output node. Look at the structure in Figs. 26-5 and 26-6, and ask: how will the output ( X3 ) be affected if this particular weight ( w ) is changed slightly, but everything else is kept the same The answer is: where SLOPE O is the first derivative of the output layer sigmoid, evaluated where we are operating on its curve. In other words, SLOPE O describes how much the output of the sigmoid changes in response to a change in the input to the sigmoid. From Eq. 26-2, SLOPE O can be calculated from the current output value of the sigmoid, X3. This calculation is shown in line 3160. In line 3170, the slope for this weight is calculated via Eq. 26-3, and stored in the variable DX3DW (i. e. Delta X3 Delta w). Using a similar analysis, the slope for a weight on the hidden layer, such as WH1,1, can be found by: SLOPE H1 is the first derivative of the hidden layer sigmoid, evaluated where we are operating on its curve. The other values, X11 and WO1, are simply constants that the weight change sees as it makes its way to the output. In lines 3070 and 3080, the slopes of the sigmoids are calculated using Eq. 26-2. The slope of the hidden layer weight, DX3DW is calculated in line 3090 via Eq. 26-4. Now that we know the slope of each of the weights, we can look at how each weight is changed for the next iteration. The new value for each weight is found by taking the current weight, and adding an amount that is proportional to the slope: This calculation is carried out in line 3100 for the hidden layer, and line 3180 for the output layer. The proportionality constant consists of two factors, ELET, the error of the network for this particular input, and MU, a constant set at the beginning of the program. To understand the need for ELET in this calculation, imagine that an image placed on the input produces a small error in the output signal. Next, imagine that another image applied to the input produces a large output error. When adjusting the weights, we want to nudge the network more for the second image than the first. If something is working poorly, we want to change it if it is working well, we want to leave it alone. This is accomplished by changing each weight in proportion to the current error, ELET. To understand how MU affects the system, recall the example of the paratrooper. Once he determines the downhill direction, he must decide how far to proceed before reevaluating the slope of the terrain. By making this distance short, one meter for example, he will be able to precisely follow the contours of the terrain and always be moving in an optimal direction. The problem is that he spends most of his time evaluating the slope, rather than actually moving down the hill. In comparison, he could choose the distance to be large, say 1000 meters. While this would allow the paratrooper to move rapidly along the terrain, he might overshoot the downhill path. Too large of a distance makes him jump all over the country-side without making the desired progress. In the neural network, MU controls how much the weights are changed on each iteration. The value to use depends on the particular problem, being as low as 10 -6. or as high as 0.1. From the analogy of the paratrooper, it can be expected that too small of a value will cause the network to converge too slowly. In comparison, too large of a value will cause the convergence to be erratic, and will exhibit chaotic oscillation around the final solution. Unfortunately, the way neural networks react to various values of MU can be difficult to understand or predict. This makes it critical that the network error (i. e. ESUM) be monitored during the training, such as printing it to the video screen at the end of each iteration. If the system isnt converging properly, stop the program and try another value for MU.

Comments

Popular Posts