Implementace vícevrstvé neuronové sítě
a metody učení backpropagation.

Lukáš Zapletal, PřF UP v Olomouci

Abstrakt:

I was assigned to implement multilayer neural network with back-propagation learning algorithm. The input was standardized text file (two examples) and one of my tasks was to create one additional example, learn the net and make some conclusions. I used Python language for the implementation.

Úvod

Mým úkolem bylo naimplementovat vícevrstvou neuronovu síť v libovolném programovacím jazyce, vyzkoušet program na dvou příkladech a vymyslet příklad vlastní. 

Implementace

Zvolil jsem objektově-orientovaný jazyk Python, který je dostupný pro všechny systémy na platformě x86 (kromě jiných). Celý program sestává z dvou tříd a několika pomocných funkcí, spouští a nastavuje se z příkazové řádky: 

python mbpnn.py konfigurační_soubor.txt [počet_kroků], 

kde prvním parametrem je konfigurační soubor a druhým nepovinným parametrem je počet opakování (standardně nastaven na 40 tisíc kroků). 

Výstupem programu je přehled výstupních parametrů a všechny spočtené výstupy testovacích vstupů. Ukázka: 

Testovaci vzorky ['xor_result']:

['+0.000', '+0.000'] -> ['+0.007']

['+0.000', '+1.000'] -> ['+0.988']

['+1.000', '+0.000'] -> ['+0.988']

['+1.000', '+1.000'] -> ['+0.009']

Popis tříd je dostupný v podobě jednoho HTML souboru. Hlavní algoritmus je ve třídě NN reprezentující vlastní neuronovou síť. V konstruktoru se vytvoří základní struktury, což je seznam počtu elementů v jednotlivých vrstvách (n), matice aktivačních hodnot (a), matice vah (w) a matice posledních změn (c). Poslední matice se používá k výpočtu vlivu z předchozího kroku. 

Metoda update provádí šíření signálu, metoda backPropagate pak zpětné šíření, výpočet chyby a úpravy vah. Obě na vstupu očekávají vektory (v případě jazyka Python konkrétně seznamy nebo n-tice), metoda backPropagate navíc obě konstanty ovlivňující proces učení. Metoda train pak provádí vlastní učení. Vstupem je jí počet kroků a zmíněné konstanty. Poslední metoda je metoda test, která provede otestování nad dodaným vzorkem (opět vektor) a výstup na obrazovku. 

Třída ConfigFile je zodpovědná za korektní načtení textového souboru s konfigurací sítě a vzorky. Provádí také interpolaci vstupů a třídu lze reprezentovat textově pro informativní účely. 

Formální popis všech metod a funkcí je pro přehlednost uveden na samostatné stránce.

Testovací data

Dva základní příklady (lekar.txt a pr_ob.txt) jsem doplnil o známý problém funkce XOR (xor.txt). Všechny tři soubory zpracuje program do několika tisíc kroků (tedy v řádech sekund), poslední problém (XOR) však vyžadoval odlišný přístup, který se nyní pokusím popsat. 

Topologie 1 - základní

Základní topologie je jednoduchá. Síť je vytvořena podle nastavení, přičemž ke vstupní a ke všem skrytým vrstvám je přidán jeden neuron navíc, jako práh. Jako aktivační funkce je brán sigmoid, váhy jsou nastaveny náhodně v intervalu [-1, 1] a hodnoty jsou interpolovány na interval [0, 1]. Již toto nastavení stačilo k velmi rychlému učení u obou zadaných příkladů, ale můj problém XORu konvergoval (resp. chyba konvergovala) velmi pomalu (nebo vůbec), v některých případech až za několik desítek minut. (Obvykle klesala chyba velmi pomalu až k nějakému prahu - tzv. brakepoint - po kterém již probíhala konvergence rychleji). 

Topologie 2 - úprava prahových hodnot

O mnoho lepšího výsledku jsem dosahoval po odstranění prahového neuronu z poslední skryté vrstvy. Topologie neuronové sítě se pak redukovala na pouhé 3-2-1 neurony (počty neuronů v jednotlivých vrstvách). To už byla konvergence lepší, velmi často i úspěšná (zhruba do 50 tisíc kroků). Stále jsem však nebyl spokojen. 

Topologie 3 - použití jiné aktivační funkce

Řešení jsem posléze nalezl v použití jiné aktivační funkce, která se hodila jak pro řešení zadaných testovacích dat, tak i na problém XOR. Hyberbolický tangens mi zredukoval počet kroků až na několik tisíc. Úspěšnost při řešení všech zadání byla 100%. 

Zajímavé bylo, že nebylo nutné interpolovat vstup do jiného intervalu, než [0, 1]. Nejdříve jsem si myslel, že bude nutné použít interval jiný, jinak že nebude funkce tahn úspěšně konvergovat. Nebylo to však vůbec nutné. 

Kompletní ukázka - řešení problému XOR

$ python mbpnn.py xor.txt  

NEURONOVA SIT: 

        Pocet vrstev: 2

        Pocet vstupu: 2

        Vstupy: [['x', '0', '1'], ['y', '0', '1']]

        Pocty neuronu: [2, 1]

        Koef. uceni: 0.500000

        Koef. vlivu pr. kroku: 0.150000

        Trenovaci mnozina: [[[0.0, 0.0], [0.0]], [[0.0, 1.0], [1.0]], [[1.0, 0.0], [1.0]], [[1.0, 1.0], [0.0]]]

        Testovaci mnozina: [[0.0, 0.0], [0.0, 1.0], [1.0, 0.0], [1.0, 1.0]]

       

Trenuji sit [3, 2, 1] 

Chyba = 1.604523      

Chyba = 0.016659      

Chyba = 0.002823      

Chyba = 0.001405      

Chyba = 0.000924      

...vynecháno... 

Chyba = 0.000077      

Chyba = 0.000074      

Chyba = 0.000071      

Chyba = 0.000069      

Testovaci vzorky ['xor_result']: 

['+0.000', '+0.000'] -> ['+0.000'] 

['+0.000', '+1.000'] -> ['+0.992'] 

['+1.000', '+0.000'] -> ['+0.992'] 

['+1.000', '+1.000'] -> ['-0.000'] 

Reference:

Hyberbolický tangens: http://de.wikipedia.org/wiki/Tanh