realizacja_sieci_neu.. - Serwer galera.ii.pw.edu.pl
Transkrypt
realizacja_sieci_neu.. - Serwer galera.ii.pw.edu.pl
Politechnika Warszawska Programowa realizacja sieci neuronowych Zbigniew Szymański, Stanisław Jankowski grudzień 2013 Instytut Informatyki Nowowiejska 15 / 19, 00-665 Warszawa 2 Programowa realizacja sieci neuronowych Zbigniew Szymański, Stanisław Jankowski ([email protected]) Streszczenie W dokumencie przedstawiono sposób realizacji sieci neuronowej w środowisku programu Matlab oraz darmowego programu Octave. Pokazano sposób odczytu wag wytrenowanej sieci oraz funkcję obliczającą jej jakobian. Słowa kluczowe: sieci neuronowe, MATLAB, Octave 3 Programowa realizacja sieci neuronowych Zbigniew Szymański, Stanisław Jankowski SPIS TREŚCI 1 WSTĘP .......................................................................................................................................................... 4 1.1 2 SIEĆ NEURONOWA W PROGRAMIE MATLAB ................................................................................. 6 2.1 2.2 3 DANE WEJŚCIOWE ...................................................................................................................................... 5 UCZENIE SIECI ............................................................................................................................................ 6 ODCZYT WAG SIECI NEURONOWEJ .............................................................................................................. 7 SIEĆ NEURONOWA W PROGRAMIE OCTAVE ................................................................................. 9 3.1 3.2 UCZENIE SIECI ............................................................................................................................................ 9 ODCZYT WAG SIECI NEURONOWEJ .............................................................................................................. 9 4 OBLICZANIE JAKOBIANU ................................................................................................................... 12 5 LITERATURA ........................................................................................................................................... 16 4 1 Wstęp W niniejszym dokumencie pokazano sposób realizacji sieci neuronowej w środowisku programów Matlab i Octave. Zakłada się, że uczona sieć będzie miała architekturę taką jak pokazano na rys. 1.1. Sieć składa się z warstwy wejść (oznaczonych jako x1...xinputCount), warstwy neuronów ukrytych oraz neuronu wyjściowego. Wagi na połączeniach pomiędzy wejściami, a neuronami ukrytymi oznaczone są jako wi,k. Indeks i odpowiada numerowi wejścia, zaś indeks k numerowi neuronu ukrytego. W każdym neuronie ukrytym uwzględniono przesunięcie (ang. bias) – wagi tego wejścia oznaczone są jako bin k, gdzie indeks k oznacza numer neuronu ukrytego. w 1,1 x1 w1,2 input no.1 w 2,1 w 2,2 x2 v1 hidden neuron no.1 v2 y hidden neuron no.2 1 bias 2,h n1 winpu bi input no.inputCount w w xinputCount 2 ... output ... input no.2 idd 1, hi dd en en C ou Co un nt t tCoun t,hidde nCoun b in t b in hiddenCoun v n de hid un Co t t t b ou hidden neuron no.hiddenCount 1 bias Inputs Hidden layer Output Rys 1.1. Schemat sieci neuronowej Wagi połączeń pomiędzy neuronami ukrytymi, a neuronem wyjściowym oznaczono jako vk, gdzie indeks k oznacza numer neuronu ukrytego. Waga dla wejścia bias neuronu wyjściowego oznaczona jest jako bout. Zakłada się, że funkcja aktywacji neuronów ukrytych to tangens hiperboliczny, zaś neuron wyjściowy jest liniowy. 5 Wzór opisujący wyjście y z sieci neuronowej: y = v1 ⋅ tanh (w1,1 ⋅ x1 + w2,1 ⋅ x 2 + L + winputCount,1 ⋅ xinputCount + bin1 ) + + v 2 ⋅ tanh (w1, 2 ⋅ x1 + w2, 2 ⋅ x 2 + L + winputCount, 2 ⋅ xinputCount + bin 2 ) + +L+ + v hiddenCount ⋅ tanh (w1,hiddenCount ⋅ x1 + w2,hiddenCount ⋅ x 2 + L + winputCount,hiddenCount ⋅ xinputCount + bin _ hiddenCount ) + + bout 1.1 Dane wejściowe Przykłady do uczenia sieci neuronowej znajdują się w pliku tekstowym w formacie przedstawionym na rys. 1.2. Wiersze pliku dane.txt zawierają kolejne przykłady zbioru uczącego. Kolumny (z wyjątkiem ostatniej) odpowiadają wejściom xk sieci neuronowej. Ostatnia kolumna to etykieta (klasa) przykładu w zadaniach klasyfikacji lub wartość funkcji w zadaniach regresji. 2.5521854e-001 2.3136276e-001 -1.0000000e+000 1.4959056e-001 -2.5963097e-001 -1.0000000e+000 4.5116481e-001 3.8727279e-001 -1.0000000e+000 2.4235371e-001 1.8173723e-001 1.0000000e+000 -1.4888028e-001 6.8272841e-002 1.0000000e+000 7.1628976e-001 -8.9239996e-001 -1.0000000e+000 2.5652776e-001 2.2778082e-001 -1.0000000e+000 3.6011490e-001 -7.7998340e-001 -1.0000000e+000 ... Rys 1.2. Przykładowe dane wejściowe – zwartość pliku dane.txt 6 2 Sieć neuronowa w programie Matlab 2.1 Uczenie sieci Listing 1.1 przedstawia skrypt główny przygotowujący dane oraz wywołujący funkcje odpowiedzialną za uczenie. Funkcja importdata wczytuje dane z pliku tekstowego w formacie przedstawionym na rys. 1.2. W przykładowym programie po wczytaniu danych tablica dane zawiera trzy kolumny – kol. 1 i 2 zawierają wartości wejść, zaś kol. 3 wartości etykiet. Funkcja train_net przyjmuje trzy parametry. Pierwszy to tablica zawierająca wartości wejść x dla przykładów ze zbioru uczącego. Wiersze tablicy odpowiadają kolejnym przykładom. Drugi parametr to tablica zawierająca etykiety lub watości funkcji. Zaś ostatni parametr oznacza liczbę neuronów w warstwie ukrytej. Funcja zwraca obiekt reprezentujący sieć neuronową. Obiekt ten może być wykorzystany np. do odczytu wag sieci. Listing 1.1. Uczenie sieci neuronowej – plik main.m % % % % % plik: opis: main.m przykładowy skrypt pokazujący użycie sieci neuronowych w programie MATLAB autor: Zbigniew Szymański <[email protected]> data: 2013-11-20 clc; clear; %wyczyszczenie okna komend Matlaba %czyści pamięć Matlaba % Import danych z pliku tekstowego dane=importdata('dane.txt'); % Opis tablicy 'dane': % kolumny 1,2 - współrzędne punktów do klasyfikacji % kolumna 3 - etykieta punktu {-1,1} % Uczenie sieci neuronowej liczba_neuronow_ukrytych=4; [net]=train_net(dane(:,1:2),dane(:,3),liczba_neuronow_ukrytych); Listing 1.2 przedstawia implementację funkcji train_net dokonującej uczenia sieci neuronowej. Funkcja newff tworzy nowy obiekt sieci typu feed-forward backpropagation network. Wywołanie funkcji init powoduje zainicjowanie wag sieci wartościami losowymi. W kolejnych liniach ustawiane są parametry algorytmu uczenia – wartość błędu przy której przerywany jest proces uczenia (zbyt niski poziom błędu może mieć niekorzystny wpływ na generalizację sieci), oraz maksymalna liczba epok uczenia. Ustawienie właściwości net.trainParam.showWindow na wartość false powoduje, że podczas uczenia nie będzie wyświetlane okno prezentujące jego przenbieg. Wywołanie funkcji train rozpoczyna pierwszą fazę proces uczenia (dobór wag metodą propagacji wstecznej błędu). Po jej zakończeniu zmieniana jest funkcja ucząca na Levenberg’a – 7 Marquard’a i uczenie jest kontynuowane, aż do osiągnięcia założonego poziomu błędu lub liczby epok. Listing 1.2. Funkcja ucząca sieć neuronową function [net]= train_net(train_set,labels,hidden_neurons_count) %Opis: funkcja tworząca i ucząca sieć neuronową %Parametry: % train_set: zbiór uczący - kolejne punkty w kolejnych wierszach % labels: etykiety punktów - {-1,1} % hidden_neurons_count: liczba neuronów w warstwie ukrytej %Wartość zwracana: % net - obiekt reprezentujący sieć neuronową %inicjalizacja obiektu reprezentującego sieć neuronową %funkcja aktywacji: neuronów z warstwy ukrytej - tangens hiperboliczny, % neuronu wyjściowego - liniowa %funkcja ucząca: gradient descent backpropagation - propagacja wsteczna % błędu net=newff(train_set',labels',hidden_neurons_count,... {'tansig', 'purelin'},'traingd'); rand('state',sum(100*clock)); net=init(net); net.trainParam.goal = 0.01; net.trainParam.epochs = 100; net.trainParam.showWindow = false; net=train(net,train_set',labels'); %inicjalizacja generatora liczb %pseudolosowych %inicjalizacja wag sieci %warunek stopu – poziom błędu %maksymalna liczba epok %nie pokazywać okna z wykresami %w trakcie uczenia %uczenie sieci %zmiana funkcji uczącej na: Levenberg-Marquardt backpropagation net.trainFcn = 'trainlm'; net.trainParam.goal = 0.01; %warunek stopu – poziom błędu net.trainParam.epochs = 200; %maksymalna liczba epok net.trainParam.showWindow = false; %nie pokazywać okna z wykresami %w trakcie uczenia net=train(net,train_set',labels'); %uczenie sieci 2.2 Odczyt wag sieci neuronowej Do analizy sieci neuronowej konieczna jest znajomość jej wag. Na listingu 2.1 pokazano w jaki sposób można je odczytać. Listing 2.1. Odczyt wag sieci neuronowej %NN weights w = net.IW{1}’; bin=net.b{1}; v = net.LW{2,1}'; bout = net.b{2}; %weights inputs->hidden neurons %input bias %weights hidden neurons->output %output bias Tablica zawierająca wagi połączeń wejść z neuronami ukrytymi zapisana jest w składowej IW{1} obiektu reprezentującego sieć neuronową. Tablica ta na potrzeby niniejszego przykładu została transponowana, aby oznaczenia były zgodne z rys. 1.1. Kolejne wiersze tablicy 8 odpowiadają kolejnym wejściom sieci, zaś kolumny neuronom ukrytym. Np. w(1,2) oznacza wagę połączenia pierwszego wejścia z drugim neuronem ukrytym. 1.9706 29.4974 -5.4645 5.1750 -14.0344 -18.2400 15.0942 -0.8127 Rys 2.1. Przykładowa zawartość zmiennej w z listingu 2.1 Bias neuronów ukrytych zapisany jest w składowej b{1} obiektu reprezentującego sieć neuronową. -5.6489 -2.7649 1.7265 -3.7166 Rys 2.2. Przykładowa zawartość zmiennej bin z listingu 2.1 Tablica zawierająca wagi połączeń pomiędzy neuronami ukrytymi, a neuronem wyjściowym zapisana jest w składowej LW{2,1} obiektu reprezentującego sieć neuronową. Tablica ta na potrzeby niniejszego przykładu została transponowana, aby oznaczenia były zgodne z rys. 1.1. 1.3092 -1.2772 -1.2576 -1.3243 Rys 2.3. Przykładowa zawartość zmiennej v z listingu 2.1 Bias neuronu wyjściowego zapisany jest w składowej b{2} obiektu reprezentującego sieć neuronową. 9 3 Sieć neuronowa w programie Octave Program Octave można pobrać ze strony [4]. Do realizacji sieci neuronowych (w sposób odpowiadający realizacji w programie Matlab) wymagane jest pobranie pakietu nnet[6] i zainstalowanie w programie Octave komendą pkg install nnet-0.1.13.tar.gz. 3.1 Uczenie sieci Listing 3.1 przedstawia skrypt główny przygotowujący dane oraz wywołujący funkcje odpowiedzialną za uczenie. Funkcja loaddata wczytuje dane z pliku tekstowego w formacie przedstawionym na rys. 1.2. W przykładowym programie po wczytaniu danych tablica dane zawiera trzy kolumny – kol. 1 i 2 zawierają wartości wejść, zaś kol. 3 wartości etykiet. Funkcja train_net przyjmuje trzy parametry. Pierwszy to tablica zawierająca wartości wejść x dla przykładów ze zbioru uczącego. Wiersze tablicy odpowiadają kolejnym przykładom. Drugi parametr to tablica zawierająca etykiety lub watości funkcji. Zaś ostatni parametr oznacza liczbę neuronów w warstwie ukrytej. Funcja zwraca obiekt reprezentujący sieć neuronową. Obiekt ten może być wykorzystany np. do odczytu wag sieci. 3.2 Odczyt wag sieci neuronowej Odczyt wag sieci neuronowej odbywa się tak samo jak w programie Matlab i jest opisany w pkt. 2.2. 10 Listing 3.1. Uczenie sieci neuronowej – plik main.m % % % % % plik: opis: main.m przykładowy skrypt pokazujący użycie sieci neuronowych w programie Octave autor: Zbigniew Szymański <[email protected]> data: 2013-12-16 clc; clear; %wyczyszczenie okna komend %usunięcie wszystkich zmiennych % Import danych z pliku tekstowego dane=load('dane.txt'); % Opis tablicy 'dane': % kolumny 1,2 - współrzędne punktów do klasyfikacji % kolumna 3 - etykieta punktu {-1,1} % Uczenie sieci neuronowej liczba_neuronow_ukrytych=4; [net]=train_net(dane(:,1:2),dane(:,3),liczba_neuronow_ukrytych); %klasyfikacja danych ze zbioru uczącego wyniki=sign(sim(net,dane(:,1:2)')'); %analiza wyników klasyfikacji TP=size(find(dane(idx_poz,3)==1),1) %liczba True Positives TN=size(find(dane(idx_neg,3)==-1),1) %liczba True Negatives FP=size(find(dane(idx_poz,3)==-1),1) %liczba False Positives FN=size(find(dane(idx_neg,3)==1),1) %liczba False Negatives %TP+TN+FP+FN == rozmiar zbioru %Wizualizacja wyników klasyfikacji idx_poz=find(wyniki(:)==1); idx_neg=find(wyniki(:)==-1); idx_blad=find(wyniki(:)~=dane(:,3)); %indeksy przykladow %zaklasyfikowanych jako pozytywne %indeksy przykladow %zaklasyfikowanych jako negatywne %indeksy błędnie zaklasyfikowanych %przykładów figure(100); plot(dane(idx_blad,1),dane(idx_blad,2),'ob'); %wykreślenie błędnie %zaklasyfikowanych próbek hold on; %wyniki klasyfikacji - klasa pozytywna plot(dane(idx_poz,1),dane(idx_poz,2),'.r'); %wyniki klasyfikacji - klasa negatywna plot(dane(idx_neg,1),dane(idx_neg,2),'.k'); hold off; 11 Listing 3.2. Funkcja ucząca sieć neuronową function [net]= train_net(train_set,labels,hidden_neurons_count) %Opis: funkcja tworząca i ucząca sieć neuronową %Parametry: % train_set: zbiór uczący - kolejne punkty w kolejnych wierszach % labels: etykiety punktów - {-1,1} % hidden_neurons_count: liczba neuronów w warstwie ukrytej %Wartość zwracana: % net - obiekt reprezentujący sieć neuronową %inicjalizacja obiektu reprezentującego sieć neuronową %funkcja aktywacji: neuronów z warstwy ukrytej - tangens hiperboliczny, % neuronu wyjściowego - liniowa %funkcja ucząca: Levenberg-Marquard input_count=size(train_set,2); pr=min_max(train_set'); %określenie minimalnych i %maksymalnych wartości dla %każdego wejścia net=newff(pr, [hidden_neurons_count 1],{'tansig', 'purelin'}, 'trainlm'); rand('state',sum(100*clock)); %inicjalizacja generatora liczb %pseudolosowych %inicjalizacja wag sieci net.IW{1} = (rand(hidden_neurons_count, input_count)-0.5)/(0.5/0.15); net.LW{2} = (rand(1, hidden_neurons_count) - 0.5) / (0.5 / 0.15); net.b{1} = (rand(hidden_neurons_count, 1) - 0.5) / (0.5 / 0.15); net.b{2} = (rand() - 0.5) / (0.5 / 0.15); net.trainParam.goal = 0.01; net.trainParam.epochs = 300; net=train(net,train_set',labels'); %warunek stopu - poziom błędu %maksymalna liczba epok %uczenie sieci 12 4 Obliczanie Jakobianu Jakobian jest macierzą, której kolejne kolumny zawierającą pochodne wyjścia sieci względem jej parametrów. Kolejne wiersze odnoszą się do kolejnych próbek zbioru uczącego. parametry (wagi) próbki Rys 3.1. Struktura Jakobianu Wzór na wartość y wyjścia sieci neuronowej przedstawiono w pkt. 1. Wzory na pochodne wyjścia sieci względem kolejnych wag przedstawione są na kolejnej stronie. Do obliczenia pochodnych wykorzystano poniższe wzory: • Pochodna funkcji złożonej: [f(g(x))]’=f’(g(x))⋅g’(x) • Pochodna funkcji tangens hiperboliczny: tanh’(x)=1-tanh2(x) Funkcja realizująca obliczanie Jakobianu sieci neuronowej została przedstawiona na listingu 3.1 (kod funkcji jest taki sam zarówno dla środowiska Matlab jak i Octave). Parametrami funkcji są obiekt reprezentujący sieć neuronową i tablica zawierająca w kolejnych wierszach próbki zbioru uczącego (kolumny tablicy odpowiadają wejściom sieci neuronowej). 13 Pochodne po wagach 1-szego neuronu ukrytego: ∂y = v1 ⋅ (1 − tanh 2 (w1,1 ⋅ x1 + w2,1 ⋅ x 2 + L + winputCount ,1 ⋅ xinputCount + bin1 )) ⋅ x1 ∂w1,1 ... ∂y = v1 ⋅ (1 − tanh 2 (w1,1 ⋅ x1 + w2,1 ⋅ x 2 + L + winputCount ,1 ⋅ xinputCount + bin1 )) ⋅ xinputCount ∂winputCount ,1 [ ] [ ] Pochodna po bias’ie 1-szego neuronu ukrytego: ∂y = v1 ⋅ (1 − tanh 2 (w1,1 ⋅ x1 + w2,1 ⋅ x 2 + L + winputCount ,1 ⋅ xinputCount + bin1 )) ∂bin1 [ ] ... Pochodne po wagach ostatniego neuronu ukrytego: ∂y = ∂w1,hiddenCount [( ) ] v hiddenCount ⋅ 1 − tanh 2 (w1, hiddenCount ⋅ x1 + w2, hiddenCount ⋅ x 2 + L + winputCount , hiddenCount ⋅ xinputCount + bin _ hiddenCount ) ⋅ x1 ... ∂y ∂winputCount , hiddenCount = [( ) v hiddenCount ⋅ 1 − tanh 2 (w1, hiddenCount ⋅ x1 + w2, hiddenCount ⋅ x 2 + L + winputCount , hiddenCount ⋅ xinputCount + bin _ hiddenCount ) ⋅ xinputCount Pochodna po bias’ie ostatniego neuronu ukrytego: ∂y = ∂bin _ hiddenCount [( )] v hiddenCount ⋅ 1 − tanh 2 (w1, hiddenCount ⋅ x1 + w2, hiddenCount ⋅ x 2 + L + winputCount , hiddenCount ⋅ xinputCount + bin _ hiddenCount ) Pochodne po wagach neuronu wyjściowego: ∂y = tanh(w1,1 ⋅ x1 + w2,1 ⋅ x 2 + L + winputCount ,1 ⋅ xinputCount + bin1 ) ∂v1 ... ∂y = tanh(w1, hiddenCount ⋅ x1 + w2 ,hiddenCount ⋅ x 2 + L + winputCount , hiddenCount ⋅ xinputCount + bin _ hiddenCount ) ∂v hiddenCount Pochodna po bias’ie neuronu wyjściowego: ∂y =1 ∂bout ] 14 Listing 3.1. Funkcja obliczająca Jakobian sieci neuronowej function Z = calc_jacobian(net, trainSet) %calc_jacobian calculates jacobian for a NN with: % 1 hidden tansig layer ('hiddenCount' neurons) % 1 output linear neuron % 1 input layer ('inputCount' inputs) % author: Zbigniew Szymański <[email protected]> hiddenCount = net.layers{1}.dimensions; %NN weights w = net.IW{1}'; %weights inputs->hidden neurons bin=net.b{1}; %input bias v = net.LW{2,1}'; %weights hidden neurons->output bout = net.b{2}; %output bias inputCount= net.inputs{1}.size; paramsCount = numel(w)+numel(bin)+numel(v)+numel(bout); samplesCount = size(trainSet, 1); Z = zeros(samplesCount,paramsCount); for sample_no=1:samplesCount param_no=1; %partial derivatives of the output with respect to %hidden neuron weights for hidden_no=1:hiddenCount tanh_param=0; for i=1:inputCount tanh_param=tanh_param+w(i,hidden_no)*... trainSet(sample_no,i); end tanh_param=tanh_param+bin(hidden_no); for input_no=1:inputCount Z(sample_no,param_no)=... v(hidden_no)*(1-tanh(tanh_param).^2)*... trainSet(sample_no,input_no); param_no=param_no+1; end end %partial derivatives of the output with respect to %hidden neuron biases for hidden_no=1:hiddenCount tanh_param=0; for i=1:inputCount tanh_param=tanh_param+w(i,hidden_no)*... trainSet(sample_no,i); end tanh_param=tanh_param+bin(hidden_no); Z(sample_no,param_no)=... v(hidden_no)*(1-tanh(tanh_param).^2); param_no=param_no+1; end kontynuacja na następnej stronie 15 kontynuacja z poprzedniej strony %partial derivatives of the output with respect to %output neuron weights for hidden_no=1:hiddenCount tanh_param=0; for i=1:inputCount tanh_param=tanh_param+w(i,hidden_no)*... trainSet(sample_no,i); end tanh_param=tanh_param+bin(hidden_no); Z(sample_no,param_no)=tanh(tanh_param); param_no=param_no+1; end %partial derivatives of the output with respect to %output neuron bias Z(sample_no,param_no)=1; end 16 5 Literatura 1. Dokumentacja „Neural Network Toolbox”, Matlab, 2013 http://www.mathworks.com/help/nnet/index.html 2. Dokumentacja funkcji z „Neural Network Toolbox”, Matlab, 2013 http://www.mathworks.com/help/nnet/functionlist.html 3. Stanisław Jankowski, „Statystyczne systemy uczące się – modelowanie i klasyfikacja; Materiały do wykładu i projektu”, Instytut Systemów Elektronicznych PW, 2013 4. Strona projectu „GNU - Octave” http://www.gnu.org/software/octave/ 5. Pakiety do programu Octave - “Octave-Forge - Extra packages for GNU Octave” http://octave.sourceforge.net/ 6. Pakiet nnet programu Octave http://octave.sourceforge.net/nnet/index.html Najaktualniejsza wersja niniejszego opracowania wraz z plikami przykładowymi jest do pobrania ze strony: http://galera.ii.pw.edu.pl/~zsz/sieci_neuronowe