Algorytm wstecznej propagacji błędu (backpropagation) jest obecnie podstawowym (i jednym z najskuteczniejszych) algorytmem nadzorowanego uczenia wielowarstwowych jednokierunkowych sieci neuronowych.
Nazwa tego algorytmu wynika z kolejności obliczania sygnałów błędu , która przebiega w kierunku odwrotnym niż przechodzenie sygnałów przez sieć, to znaczy od warstwy wyjściowej poprzez warstwy ukryte w kierunku warstwy wejściowej.
Ogólnie algorytm propagacji wstecznej wymaga dla każdego wzorca uczącego wykonania następujących czynności:
Założenia: dana jest sieć o M warstwach, oraz zestaw danych uczących E = {E1, E2...EN}, gdzie każdy z przykładów składa się z wektora danych wejściowych X i z wektora wyjść D.
Przypisz wszystkim wagom wartości losowe bliskie 0. Wybierz wzorzec uczący EK.
Podaj wektor uczący EK na wejście sieci
Wyznacz wartości wyjść każdego elementu dla kolejnych warstw przetwarzania, od pierwszej warstwy ukrytej do warstwy wyjściowej
Oblicz wartość Mi błędów dla warstwy wyjściowej
Mi = f (xil-1 (t)) [di - yiM(t)]
Wyznacz kolejno błędy w warstwach l = M., M.-1, ...2 według postępowania
l-1i (t) = f (xil-1 (t) ) i wlji (t) li (t)
Wyznacz zmianę wartości wag
wlij (t) = li (t) xil-1 (t)
Modyfikuj wszystkie wagi
wlji (t+1) = wlji (t) + wlij (t)
Wybierz kolejny wzorzec (o ile istnieje) i przejdź do punktu 2 (wczytanie wzorca)
W trakcie uczenia sieci można zaprezentować dowolną liczbę wzorców uczących. Jeśli sieć ma pracować z danymi zakłóconymi to część wektorów uczących powinna również zawierać zakłócenie. Jest to związane ze zdolnością sieci do uogólniania - niewielkie zaburzenie sygnałów wzorcowych może spowodować przyspieszenie zbieżności procesu uczenia ( choć sygnał zaburzony nigdy może się nie pojawić w rzeczywistej pracy sieci ).
Inne zasady obowiązujące przy konstruowaniu ciągów uczących zostały przedstawione w punkcie Projektowanie zbioru uczącego.
Pierwszą operacją w procesie uczeni jest inicjalizacja początkowego układu wag. Należy unikać symetrii w warstwach wag początkowych (mogłoby to spowodować nie nauczenie się sieci ). Najskuteczniejszym rozwiązaniem wydaje się być losowy wybór wag początkowych.
Istotnym problemem jest wybór współczynnika uczenia . Parametr ten decyduje o szybkości i stabilności procesu uczenia. Przy zbyt małej wielkości tego współczynnika uczenie postępuje w bardzo wolnym tempie, i sieć potrzebuje b. dużej liczby operacji, by się nauczyć. W przypadku zbyt dużej wartości tego współczynnika algorytm może stać się niestabilny.
Wartość współczynnika dobiera się zazwyczaj z przedziału [0.05 , 0.25].
obliczenia przejścia sygnału w sieci - struktury danych algorytmu:
iKrok – zmienna kontrolna programu – pokazująca, na którym kroku jest sieć
RN1, RN2, RN3, RN4 – obiekty typu neuron, przy czym RN1 i RN2 stanowią warstwę ukrytą, RN3 i RN4 – warstwę wyjściową.
begin
if (iKrok1 < 1) or (iKrok1 > 5) then
iKrok1 := 1;
case iKrok1 of
1: begin
Tytul1(‘OBLICZENIE SUMY ILOCZYNÓW SYGNAŁÓW
WEJŚCIOWYCH ORAZ’,0);
Tytul1(‘WAG WARSTWY UKRYTEJ’,1);
RN1.Krok1(We1.Value,We2.Value,Bias.Value);
RN2.Krok1(We1.Value,We2.Value,Bias.Value);
{przerysowanie ekranu, uwzględnienie zmian}
end;
2: begin
Tytul1(‘OBLICZENIE ODPOWIEDZI NEURONÓW WARSTWY
UKRYTEJ’,0);
Tytul1(‘’,1);
RN1.Krok2;
RN2.Krok2;
end;
3: begin
Tytul1(‘OBLICZENIE SUMY ILOCZYNÓW WYJŚĆ
WARSTWY UKRYTEJ ORAZ’,0);
Tytul1(‘WAG WARSTWY WYJŚCIOWEJ’,1);
RN3.Krok1(RN1.Odp.Value,RN2.Odp.Value,
Bias.Value);
RN4.Krok1(RN1.Odp.Value,RN2.Odp.Value,
Bias.Value);
{przerysowanie ekranu, uwzględnienie zmian}
end;
4: begin
Tytul1(‘OBLICZENIE ODPOWIEDZI NEURONÓW WARSTWY
WYJŚCIOWEJ’,0);
Tytul1(‘’,1);
RN3.Krok2;
RN4.Krok2;
end;
5: begin
Czysc;
Tytul1(‘PARAMETRY SIEĆ NEURONOWEJ ZOSTAŁY
OKREŚLONE’,0)
end;
end;
{przerysowanie ekranu – uwzględnienie zmian}
Inc(iKrok1);
end;
Procedury wywoływane w algorytmie głównym:
procedure TRN.Krok2;
begin
Odp.Value := 1.0/(1.0+exp(-SumWe.Value));
Odp.Text := FloatToStrF(Odp.Value,ffFixed,18,4);
end;
procedure TRN.Krok1(x1,x2,x3: Extended);
begin
Wej[1] := x1;
Wej[2] := x2;
Wej[3] := x3;
SumWe.Value := W[1].Value*x1 + W[2].Value*x2 + W[3].Value*x3;
SumWe.Text := FloatToStrF(SumWe.Value,ffFixed,18,4);
end;
uczenie sieci - struktury danych algorytmu:
RN21, RN22, RN23, RN24, RN25, RN26 – obiekty typu neuron, przy czym RN21 i RN22 stanowią warstwę wejściową, RN23 i RN24 – warstwę ukrytą, RN25 i RN26 – warstwę wyjściową.
Wyznaczenie błędów dla warstwy wyjściowej
begin
Tytul2('SIEĆ WYZNACZA BŁĘDY NEURONÓW WARSTWY
WYJŚCIOWEJ');
RN21.SetEtaAlfa(eta.Value,alfa.Value);
RN22.SetEtaAlfa(eta.Value,alfa.Value);
RN23.SetEtaAlfa(eta.Value,alfa.Value);
RN24.SetEtaAlfa(eta.Value,alfa.Value);
RN25.SetEtaAlfa(eta.Value,alfa.Value);
RN26.SetEtaAlfa(eta.Value,alfa.Value);
RN25.SetBlad(z1.Value);
RN26.SetBlad(z2.Value);
end;
Wsteczne rzutowanie błędu
begin
Tytul2('SIEĆ RZUTUJE WSTECZNIE BŁĘDY DO WARSTW
UKRYTYCH');
{ wylicznie sigmy dla neuronu }
RN25.ClcSigma;
RN26.ClcSigma;
{ proagacja wsteczna błędu }
RN23.ClcBladBP(RN25,RN26,1);
RN24.ClcBladBP(RN25,RN26,2);
RN23.PokazBlad(True);
RN24.PokazBlad(True);
{ wylicznie sigmy dla neuronu }
RN23.ClcSigma;
RN24.ClcSigma;
end;
Modyfikacja wag :
begin
Tytul2('SIEĆ USTALA NOWE WARTOŚCI
WSPÓŁCZYNNIKÓW WAG NEURONÓW');
RN23.ObliczNoweWagi(alfa.Value,eta.Value);
RN23.PokazNoweWagi(True);
RN24.ObliczNoweWagi(alfa.Value,eta.Value);
RN24.PokazNoweWagi(True);
RN25.ObliczNoweWagi(alfa.Value,eta.Value);
RN25.PokazNoweWagi(True);
RN26.ObliczNoweWagi(alfa.Value,eta.Value);
RN26.PokazNoweWagi(True);
end;
Kluczowe procedury wywoływane w algorytmie głównym:
procedure TRN.ObliczNoweWagi(pAlfa,pEta: Extended);
var
zm,W2: Extended;
i: integer;
begin
for i := 1 to 3 do begin
W2 := W[i].Value;
zm := pAlfa * (W[i].Value-W1[i]);
zm := pEta * Sigma*Wej[i] - zm;
WNew[i].Value := W[i].Value + zm;
W1[i] := W2;
end;
end;
procedure TRN.ClcSigma;
begin
Sigma := Blad.Value * Odp.Value * (1.0 - Odp.Value);
{ funckcja odwrotna dla funkcji aktywacji neurony }
end;
procedure TRN.ClcBladBP(pRN1,pRN2: TRN; nrWagi: integer);
begin
Blad.Value := pRN1.Sigma*pRN1.W[nrWagi].Value +
pRN2.Sigma*pRN2.W[nrWagi].Value;
end;
procedure TRN.SetBlad(pZadana: extended);
begin
Blad.Value := Odp.Value - pZadana;
PokazBlad(True);
end;
Backpropagation to najpopularniejsza metoda uczenia sieci wielowarstwowych. Umożliwia ona w takich oszacowanie błędów warstw pośrednich, oraz uczenie tych warstw poprzez rzutowanie błędów poszczególnych warstw sieci na warstwy poprzednie.
Program pokazuje szczegółowo działanie sieci złożonej z czterech neuronów tworzących trzy warstwy - wejściową, nie podlegającą uczeniu (w dolnej części ekranu), wyjściową, której sygnały będą podlegały uczeniu (w górnej części ekranu) oraz warstwę ukrytą, w centralnej części ekranu.
Użytkownik ma do dyspozycji 2 ekrany, znajdujące się pod dwiema zakładkami – “Działanie sieci” oraz “Uczenie sieci””
Działanie sieci wielowarstwowych
Wybierając zakładkę “Działanie sieci” użytkownik programu ma możliwość zapoznać się z działaniem sieci warstwowej składającej się z 2 wejść, 2 neuronów w warstwie ukrytej i 2 neuronów w warstwie wyjściowej.
Program ustala współczynniki wagowe dla wszystkich neuronów w całej sieci. Użytkownik ma możliwość modyfikacji parametrów sieci, ale tylko gdy przełącznik “ustaw parametry sieci” na ekranie pokazującym uczenie sieci nie jest zaznaczony.
Po prawidłowym określeniu parametrów (i zaznaczeniu przełącznika) sieci użytkownik może zacząć prezentację. Kolejne kroki prezentacji są uruchamiane poprzez wybranie myszką przycisku “Krok”.
Pierwszym krokiem jest obliczenie iloczynów sygnałów wejściowych oraz wag warstwy ukrytej, drugim obliczenie odpowiedzi warstwy ukrytej, a kolejnym. Wszystkie wyliczane w tych krokach parametry są kolejno umieszczane na oknie programu.
Poniżej prezentujemy zrzut ekranu z tego etapu pracy programu.
Ostatnim etapem prezentacji jest wyliczenie odpowiedzi warstwy wyjściowej. Po zakończeniu prezentacji użytkownik może przystąpić do uczenia sieci metodą backpropagation.
Uczenia sieci wielowarstwowych – Backpropagation
W tym celu należy wybrać zakładkę “Uczenie sieci – BACKPROPAGATION”. Na pierwszym ekranie tego przykładu pokazana jest struktura sieci (analogiczna jak w poprzedniej prezentacji) oraz początkowe (zainicjowane losowo) wartości wag neuronów warstwy ukrytej i wyjściowej.
Użytkownik może modyfikować współczynnik (learning rate) oraz momentum.
Współczynnik uczenia musi być wybierany z dużą rozwagą, gdyż zarówno zbyt duża, jak i zbyt mała jego wartość źle wpływa na przebieg procesu uczenia. Zbyt mała wartość tego współczynnika powoduje, że uzcenie się sieci jest bardzo długotrwałe (wagi są poprawiane w każdym kroku bardzo słabo, żeby więc osiągnęły pożądane wartości trzeba wykonać bardzo dużo takich kroków). Z kolei wybór za dużego współczynnika uczenia powoduje bardzo gwałtowne zmiany parametrów sieci, które w krańcowym przypadku prowadzić mogą nawet do niestabilności procesu uczenia
Drugi współczynnik - momentum - określa stopień "konserwatyzmu" procesu uczenia. Określa on stopień zależności zmian wag od zmian stosowanych w procesie uczenia na poprzednim wzorcu. Im większa wartość współczynnika momentum, tym bardziej stabilny i bezpieczny jest proces uczenia - chociaż zbyt duża wartość może prowadzić do trudności z wykryciem przez sieć najlepszych (optymalnych) wartości współczynników wagowych dla wszystkich wchodzących w grę neuronów.
Po podaniu współczynników oraz wartości obydwu sygnałów wejściowych, jakie sieć ma otrzymać na swoich wejściach program zaczyna demonstrację. Na początku pokazuje on tylko strukturę sieci (miejsca, gdzie znajdują się poszczególne neurony oraz miejsca, gdzie wyświetlone będą poszczególne sygnały). W górnej części okna wyświetlany jest tytuł “Prezentacja struktury sieci z wagami”.
Po naciśnięciu przycisku Krok, sieć pokazuje wartości sygnałów wejściowych (podawane z zewnątrz przez neurony wejściowe), a także wartości współczynników wagowych - dla wszystkich wejść wszystkich neuronów (wyświetlane w kolorze fioletowym).
Następnie jest wczytywany kolejny element ciągu uczącego (o czym informuje zmiana tytułu w oknie – na “Nauczyciel podał sygnały wejściowe i wyjściowe”).
Kolejne naciśniecie klawisza “Krok” rozpoczyna proces symulacji przetwarzania sygnałów w sieci. Początkowo obliczane są odpowiedzi warstwy wejściowej. W każdej kolejnej warstwie obliczane są i wyświetlane (na niebiesko) sumy wartości przemnażanych przez odpowiednie wagi sygnałów wejściowych (wraz ze składnikiem BIAS). Drogi przesyłania tych sygnałów oznaczone są w postaci niebieskich linii.
Po kolejnym naciśnięciu przycisku “Krok” uruchamiany jest proces symulacji procesu przesyłania i przetwarzania sygnałów w modelowanej sieci. Początkowo wyliczane są odpowiedzi warstwy wejściowej (tytuł okna zmienia się na “Obliczanie odpowiedzi warstwy wejściowej”).W każdej kolejnej warstwie obliczane są i wyświetlane (na niebiesko) sumy wartości przemnażanych przez odpowiednie wagi sygnałów wejściowych (wraz ze składnikiem BIAS). Drogi przesyłania tych sygnałów oznaczone są w postaci niebieskich linii.
Następnie pokazywane są obliczone wartości sygnałów wyjściowych poszczególnych neuronów, powstałych po przepuszczeniu zsumowanych sygnałów wejściowych przez funkcję przejścia neurony. Potem odpowiedzi neuronów niższej warstwy stają się wejściami dla neuronów wyższej warstwy.
W momencie, gdy sieć (jako całość) popełni błąd - obliczane są błędy poszczególnych neuronów. Najpierw wyznaczane są wartości błędów dla wyjściowych neuronów sieci. Potem błędy te przeliczane są na odpowiadające im wartości na wejściach neuronów.
Po wyznaczeniu wartości błędów dla wszystkich neuronów w sieci - kolejny krok programu prowadzi do wyznaczenia nowych (poprawionych) wartości współczynników wag w całej sieci. (patrz rysunek poniżej). Potem następuje kolejna iteracja procesu uczenia.
Zaprezentowany moduł przedstawia w szczegółowy i czytelny dla użytkownika sposób przebieg sygnałów w sieciach neuronowych.
# C_M7
K backpropagation
$ Backpropagation – popularna metoda uczenia