System rozpoznawania znaków drogowych SSN (back propagation)

0

Witam

Obecnie pracuję nad systemem do rozpoznawania znaków drogowych. Do jego ukończenia pozostała mi tylko implementacja wielowarstwowej sieci neuronowej i napisanie interfejsu graficznego. Kilka dni temu skończyłem pisać sieć neuronową lecz niestety gdzieś mam błąd którego nie potrafię wychwycić i sieć neuronowa źle się uczy :( Program jest napisany w javie a kod mojego programu (część odpowiedzialna za sieć neuronową i metodę wstecznej propagacji błędu) można zobaczyć na: http://svn.xp-dev.com/svn/RSR/trunk/src/neuralNetwork/

Kilka informacji odnośnie mojej sieci neuronowej:
Jako funkcję aktywacji wykorzystuję funkcję sigmoidalną bipolarną:

y = 2/(1+exp(-beta*x)-1
f'(y) = (1 - Math.pow(x, 2)) / 2

W systemie do rozpoznawania znaków drogowych sieć będzie miała następującą struktórę:
-warstwa wejściowa: 43 neurony, a każdy będzie miał 2500 wejść ( jako sygnał wejściowy będzie przekazywany ciąg 0 i 1 reprezentujący zbinaryzowany obraz o rozmiarze 50x50 pixeli)

  • warstwa ukryta: tutaj jeszcze nie wiem jaka będzie dokładna ilość neuronów, jak sieć zacznie działać na prostych przykładach to rozmiar tej warstwy będzie dobrany drogą testową (ok 20-60 neuronów).
  • warstwa wyjściowa: 43 neurony (tyle ile jest znaków ostrzegawczych)

Neurony w sieci nie zawierają "biasu". W pliku test.java znajduje się niewielki przykład w którym próbuję nauczyć moją sieć dwóch prostych sygnałów.

Z góry bardzo dziękuję tym którzy będą mieli chwilę aby spojrzeć na mój kod i na wszelkie uwagi. Jeśli ktoś będzie miał jakieś niejasności dotyczące mojego kodu to proszę pytać. Mam nadzieję, że ktoś mi pomoże ponieważ ja od kilku dni stoję w miejscu..

Wiem, że pewnie nikomu się nie będzie chciało przeglądać mojego kodu w poszukiwaniu błędu.. Poniżej zamieszczam link do wzorów z których korzystałem do napisania metody wstecznej propagacji błędów. We wzorach znajduje się sporo indeksów dlatego wzory napisałem ręcznie i zrobiłem zdjęcie kartki z wzorami. Jeśli w którymś wzorze jest błąd lub coś jest nieczytelne to proszę pisać

http://img145.imageshack.us/img145/350/dscf0771l.jpg

Są jeszcze dwie rzeczy co do których nie jestem pewien:

  1. We wzorze przy obliczaniu błędu w ostatniej warstwie: F'(net) * (z-y) występuje zmienna "z" która jest wzorcem dla sieci. Moje pytanie dotyczy o sposób wyznaczania tych wzorców "z". Jeżeli by to przedstawić na moim problemie to ja obliczam je w następujący sposób:
  • ustawiam wagi w sieci na maksymalne wartości (na 1)
  • jako sygnał wejściowy dla sieci wrzucam dla każdego neuronu wejściowego ten sam sygnał reprezentujący dany znak drogowy (jego binarna reprezentacja - ciąg 0 i 1)
    . Odpowiedź sieci na taki sygnał wejściowy przy ustawionych wagach na maksymalne wartości traktuję jako wzorzec dla sieci (z).
  1. Czy podczas uczenia się sieci neuronowej z zastosowaną sigmoidalną bipolarną funkcją aktywajci wagi mogą wyjść poza zakres <-1,1>?
0

O raju :), Nie jestem w tym specjalistą ale interesuję się SSN (niestety w nieco innych zagadnieniach) więc spróbuję pomóc :P.
Po pierwsze zacznę może od tego, czy na pewno wybrałeś dobry rodzaj sieci? Z tego co mi się wydaje do rozpoznawania wzorców lepsze wydają się sieci np. Hopfilda.

W kod się nie wgryzałem więc odniosę się jedynie do Twojego postu.

warstwa wejściowa: 43 neurony, a każdy będzie miał 2500 wejść ( jako sygnał wejściowy będzie przekazywany ciąg 0 i 1 reprezentujący zbinaryzowany obraz o rozmiarze 50x50 pixeli)

Tak się raczej nie robi...
hmm... Nie wiem jak Ci to wytłumaczyć, może lepiej będzie jak zacznę od początku (jak się gdzieś rąbnąłem -> lub nie o to Ci chodziło to daj znać). tzn. napiszę, jak ja bym spróbował do tego podejść i wyjaśnię przy okazji co i jak.

  1. Na początku musisz sobie przygotować wektor ucząc tj. np 1000 zdjęć różnych znaków (tzn. jeśli masz 43 znaki to masz 1000/43 = około 23 zdjęcia każdego znaku -> w różnych warunkach)

  2. każde zdjęcie składa się z 2500 pikseli, które są Twoimi zmiennymi wejściowymi

  3. Struktura Twojej sieci to np. 2500-100-43 (2500 zmiennych wejściowych, 100 neuronów ukrytych i 43 neurony wyjściowe

  4. powyższy zapis można przedstawić w tablicy 3 wymiarowej chociaż ja preferuję rozbić to na max dwu-wymiarowe tablice ale nvm

Teraz omówimy co i jak w środku sieci zaczynając od neuronów ukrytych (zahaczając o zmienne wejściowe :P)

  1. mamy 100 neuronów ukrytych, a każdy z nich ma 2500 zmiennych wejściowych (binarnych)

  2. losujemy wstępne wagi z zakresu (-1,1) stojące przy tych zmiennych (łącznie będzie ich: 2500 x 100 = 25 000 -> bez biasa chociaż nie wiem czemu z niego zrezygnowałeś)

  3. Tak samo można to przedstawić analizując neurony wyjściowe: jest 43 neurony a każdy z nich ma 100 zmiennych wejściowych (neurony ukryte)

  4. losujemy wstępne wagi dla zmiennych do neuronów wyjściowych (tj. stojące przy neuronach ukrytych -> trochę namieszałem :( ). Łącznie będzie ich 43 x 100 = 4300 wag, które odnoszą się do neuronów wyjściowych

To było przypomnienie :)

A teraz jak to organizujemy (nauka etc.):

Gdy mamy nasze wspaniałe zdjęcia znaków (np. wspomnianą ilość 1000 szt.) to idziemy po kolei tj.

Załóżmy, że neuron wyjściowy nr 1 będzie odpowiedzialny za znak STOP-u, nr 2 za znak Zakaz wjazdu... itd.

  1. wrzucamy pierwsze zdjęcie np. znaku STOP, -> tj. 2500 zmiennych wejściowych wchodzi do sieci

  2. wszystko ładnie mnożymy zgodnie ze wzorami ("problem" pojawi się w neuronach wyjściowych) dlatego po kolei:
    a) dla każdego neuronu ukrytego wykonujemy mnożenie zmiennych z wagami a sumę tych iloczynów wrzucamy do funkcji aktywacji (tworząc zmienną wejściową dla neuronów wyjściowych)
    b) mamy 43 neurony wyjściowe, a każdy z nich podobnie jak poprzednio otrzymuje te wyniki, które wychodzą z neuronów ukrytych
    c) każdy neuron wyjściowy zwraca jakąś wartość (suma iloczynów sygnałów wyjściowych z warstwy ukrytej i wag stojących przy tych neuronach)

  3. Reasumując sieć zwróciła nam jakieś 43 wartości z zakresu (-1,1) -> każdy neuron wyjściowy tj. masz double wynik[43] a sieć zwróciła:
    wynik[0] = 0.14; //to nie jest przypisanie tylko wynik!!! ^^ -> żeby lepiej zobrazować
    wynik[1] = 0.21;
    wynik[2] = -0.31... itd

  4. Jeśli używasz funkcji bipolarnej to w klasyfikacji chyba również powinieneś używać liczby -1 gdy czegoś "nie ma" i 1 gdy coś "jest" -> taki odpowiednik liczb binarnych z tym, że zamiast 0 jest -1

Teraz nauka:

Nauka najszybszego spadku polega na obliczeniu pochodnej funkcji celu po każdej wadze (zmiennej) i odjęciu jej od bieżącej wagi -> minimalizacja. Funkcją celu jest zaś:
E(k) = (suma dla każdego wyjścia (od 1 do 43): 1/2*(Ykm-Dkm)^2)

gdzie Ykm to nasz wynik sieci w k-tym okresie nauki (w tym przykładzie to będzie k = 1,2...1000) i dla m-tego neuronu wyjściowego tj. m = 1,2...43

Dk to nasz wzorzec -> w tym przypadku będzie to liczba albo 1 (dla znaku, który obecnie uczymy -> np. dla STOP-u) albo -1 dla pozostałych znaków. W związku z powyższym musisz obliczyć sobie wszystkie pochodne dla każdego wyjścia, zsumować je i jakąś część odjąć od obecnej wagi.
Jak już to opanujesz to zastanów się lepiej nad zmianą formy nauki tj. w najgorszym przypadku możesz dać naukę z momentum ale znacznie lepsze są ze zmiennym krokiem uczenia, nie wspominając już o innych algorytmach typu LM lub algorytmów genetycznych :).
Dla ciebie kluczowe powinny być te ostatnie akapity. Niestety piszę strasznie chaotycznie więc mogłem coś namieszać lub o czymś nie wspomnieć... :/ Gdybyś czegoś nie wiedział to daj znać :).

Aha i taka kolejna mała dygresja: możesz wywalić ze wzoru Bete (tj. B=1) a pochodną Y' nie dziel przez 2 -> są to zbędne dodatki, które w niczym nie polepszają/pogarszają nauki i wyników.

Czy podczas uczenia się sieci neuronowej z zastosowaną sigmoidalną bipolarną funkcją aktywajci wagi mogą wyjść poza zakres <-1,1>?

Wagi jak najbardziej mogą chociaż przy tak dużej ilości zmiennych wejściowych nie może do tego nie dojść.

Gdybyś miał jakieś pytania lub coś to pytaj :)

P.S.
Nie chce mi się czytać tego co napisałem więc mam nadzieję, że nie ma tam byków :P</quote>

0

Dzięki W.S. za odpowiedź.

Zaraz szukam mojego zeszytu z notatkami z metod szutcznych inteligencji i analizuję to co napisałeś :) Z tego co przeczytałem w Twoim poście to w zły sposób chciałem się do tego zabrać..

Jeśli chodzi o dobór sieci to na wykładach nie mieliśmy omówionych sieci rekurencyjnych. Na laborkach pisaliśmy prosty programik do rozpoznawania literek wykorzystujący sieć jednowarstwową uczoną regułą Delta. O metodzie backpropagation tylko trochę usłyszałem na wykładzie i trochę też poczytałem na necie. Dlatego wybrałem ten rodzaj sieci.

Co do wektora uczącego to na początek będę to tylko zdjęcia znaków "idealnych" (śćiągnięte z wikipedi), a później jak znajdę trochę czasu to postaram się w jakimś programie graficznym stowrzyć dodatkowe znaki drogowe przedstawione pod różnym kątem nachylenia.

Mam kilka pytań dotyczących Twojego postu :)

  1. Co do struktóry którą opisałeś to nie widzę w niej warstwy wejściowej?? Wspomniałeś tylko o ilości neuronów w warstwie ukrytej i warstwie wyjściowej Jaka powinna być ilość neuronów dla pierwszej warstwy??

"wrzucamy pierwsze zdjęcie np. znaku STOP, -> tj. 2500 zmiennych wejściowych wchodzi do sieci"

Mam wrzucić taki sam sygnał (2500 zmiennych reprezentujących dany znak) dla każdego neuronu w pierwszej warstwie?? Jeśli nie to co mam ustawić na wejściach pozostałych neuronów w pierwszej warstwie??

"Jeśli używasz funkcji bipolarnej to w klasyfikacji chyba również powinieneś używać liczby -1 gdy czegoś "nie ma" i 1 gdy coś "jest" -> taki odpowiednik liczb binarnych z tym, że zamiast 0 jest -1"

Ok dzięki za uwagę, będę musiał jeszcze raz wygenerować moje pliki txt zaiwerające zbinaryzowane ciągi reprezentujące moje znaki, lub użyję funkcji sigmoidalnej unipolarnej. A jeśli będę używał funkcji unipolarnej (0,1) to wtedy wagi dla całej sieci neuronowej muszę równiejż losować z zakresu (0,1) ??

  1. Porces nauki
    Poniżej zamieszczam link do moich obliczeń (pochodna funkcji celu) - w ostatnim wzorze brakuje minusika:
    http://img718.imageshack.us/img718/7722/dscf0772.jpg

4.1.

gdzie Ykm to nasz wynik sieci w k-tym okresie nauki (w tym przykładzie to będzie k = 1,2...1000)

więc jeśli wykonam 1000 razy naukę, za każdym razem podstawiając kolejny znak z ciągu uczącego to czy wykonanie tych 1000 kroków jest wykonaniem jednej epoki?? A nauczanie kończymy po wykonaniu określonej ilości epok lub jeśli błąd jest dostatecznie mały?

4.2.

W związku z powyższym musisz obliczyć sobie wszystkie pochodne dla każdego wyjścia, zsumować je i jakąś część odjąć od obecnej wagi
Nie bardzo wiem w którym miejscu mi będzie potrzebna suma wszystkich pochodnych. Co masz na myśli że mam odjąć "jakąś" jej część??

4.3. Jeżeli skupimy się na wyliczaniu błędu w warstwie ostatniej dla m-tego neuronu to wykonujemy następujące obliczenia?:

  • Błąd_m = Y'_m * (Y_m - Z_m)
    czyli błąd dla m-tego neuronu to iloczyn: pochodnej m-tego neuronu z różnicą odpowiedzi neuronu z wzorcem (1 jeśli neuron rozpoznaje prawidłowy znak lub -1 jeśli to nie jest znak rozpoznawany przez dany neuron)

Jeżeli już uda mi się ogarnąć podstawową metodę back propagation to później tak jak mówiłeś pomyślę nad naukę z momentum lub zmiennym krokiem uczenia. Miałem już trochę do czynienia z algorytmami genetycznymi i ewolucyjnymi, ale powoli małymi kroczkami może uda mi się to wszystko połączyć i zrozumieć

Z góry dzięki za cierpliwość i wszystkie odpowiedzi

0

Dzięki W.S. za odpowiedź.

Nie ma za co :)

Na laborkach pisaliśmy prosty programik do rozpoznawania literek wykorzystujący sieć jednowarstwową uczoną regułą Delta. O metodzie backpropagation tylko trochę usłyszałem na wykładzie i trochę też poczytałem na necie.

Nie myl reguły z metodą... Reguła delta odnosi się do pewnego sposobu uczenia sieci natomiast metoda po prostu uczy :). Zauważ skąd się bierze ta delta w tych wzorach... Funkcję błędu masz: E(k) = 1/2(y-z)2 (wole oznaczenie d zamiast z ale niech będzie :P). Z jest pewną stałą tj. naszym celem, natomiast y jest tym co zwraca sieć tj. Y = f(suma Wjf(suma WjiXi)) -> idąc dalej mamy: E(k) = 1/2(f(suma Wjf(suma WjiXi)) - z)2 -> jeśli obliczysz sobie stąd pochodną po Wj lub Wji to wyjdzie Ci Twoja delta itd. Chodzi mi o to, że metoda backpropagation jest zwykłą metodą gradientową (np. najszybszego spadku) natomiast reguła delta jest w nią tak jakby "wpisana"...

Co do wektora uczącego to na początek będę to tylko zdjęcia znaków "idealnych" (śćiągnięte z wikipedi)

W sumie O.k. -> jak na jakąś pracę szkolną. Pamiętaj, że w takim wypadku Twoja próba wynosić będzie jedynie 43 dane

stowrzyć dodatkowe znaki drogowe przedstawione pod różnym kątem nachylenia.

Tak jak napisałem wcześniej ja się zajmuję SSN pod innym kontem i rozpoznawanie wzorców mnie raczej nie interesuje jednak zastanawiam się co Ty chcesz stworzyć? tzn. jak to ma wyglądać i do czego służyć? Bo jeśli zadaniem programu będzie jedynie próba rozpoznania znaku, który sam jej podasz w odpowiedniej wielkości to w sumie chyba będzie O.k. ale takie podejście jest chyba mało praktyczne ^^

Co do struktóry którą opisałeś to nie widzę w niej warstwy wejściowej??

A co uważasz za "warstwę wejściową"? Bo chyba masz jakąś inną definicję od mojej :). Sieć ma 3 rodzaje warstw: wejściową (zmienne wejściowe), ukrytą (Twoja funkcja aktywacji) oraz wyjściową (to co zwraca) tj. warstwa wejściowa to są te twoje 2500 zmiennych; ukryta 100 neuronów i wyjściowa 43 wyjścia.

Wspomniałeś tylko o ilości neuronów w warstwie ukrytej i warstwie wyjściowej Jaka powinna być ilość neuronów dla pierwszej warstwy??

to zależy od problemu i możliwości dojścia do tych zmiennych :) -> w dodatku ty masz zmienne binarne...

Mam wrzucić taki sam sygnał (2500 zmiennych reprezentujących dany znak) dla każdego neuronu w pierwszej warstwie?? Jeśli nie to co mam ustawić na wejściach pozostałych neuronów w pierwszej warstwie??

Jeśli dobrze zrozumiałem to tak.
Żeby uprościć powiedzmy, że masz 9 zmiennych, które przyjęły następującą wartość: Z = [0,0,1,0,1,1,1,0,1]^T (T - od transponowana ^^). Teraz gdy masz powiedzmy 3 neurony to do każdego wrzucasz ten sam wektor ze zmiennymi. Pamiętaj, że w każdym neuronie są inne wagi dlatego każdy neuron zwróci inną wartość.

Ja to rozwiązuję w ten sposób, że tworzę tablicę dwuwymiarową z wagami z tym, że jeden wymiar jest dla j-neuronu a drugi dla i-zmiennej np. double zmienne[3][9]; :)

Ok dzięki za uwagę, będę musiał jeszcze raz wygenerować moje pliki txt zaiwerające zbinaryzowane ciągi reprezentujące moje znaki, lub użyję funkcji sigmoidalnej unipolarnej. A jeśli będę używał funkcji unipolarnej (0,1) to wtedy wagi dla całej sieci neuronowej muszę równiejż losować z zakresu (0,1) ??

Zacznę od końca: Nie, wagi zawsze powinny być ujemne i dodatnie! najlepiej właśnie z przedziału (-1,1).
Chyba funkcja sigmoidalna unipolarna byłaby lepsza w tym wypadku.
Zastanawiam się również czy rzeczywiście konieczne jest zmienianie tych zmiennych na -1 i 1... Moje obawy dot. tego, że jak na wyjściu sieć wskaże Ci -1 a powinno być 1 to błąd wyjdzie Ci 4 (y-z)2 -> (-1-1)2 = 4 Natomiast jak sieć zwróci Ci 1 a powinno być 0 to błąd wyniesie 1 a także gdy sieć zwróci Ci -1 to błąd również będzie 1 (-1/1 - 0)^2 = 1 => dlatego chyba jednak powinieneś właśnie albo zmienić funkcję albo dane wzorcowe wprowadzać w postaci -1 i 1...
Właśnie sobie uświadomiłem, że źle się zrozumieliśmy: zmienne możesz wprowadzać w zakresie 0,1 nawet przy funkcji bipolarnej natomiast w wektorze z danymi powinieneś używać liczb -1 i 1 - znowu namieszałem ^^. Może jeszcze inaczej załóżmy, że w k-próbie uczysz sieć np. znaku STOP dlatego twoje z w funkcji celu (E(k) = 1/2(y-z)2) dla STOP-u wynosi 1 i -1 dla reszty znaków tj. gdy założymy, że pierwszy neuron wyjściowy odpowiada za znak stopu, drugi za zakaz wjazdu a trzeci za "nie parkować" a twoje neurony zwróciły wynik w postaci: Y1 = 0,23, Y2 = -0,12, Y3 = 0,43 (Y1,2,3 odpowiadają wyjściom neuronów pierwszego drugiego i trzeciego) to twój błąd policzysz następująco: E(k1) = (0,23 - 1)2, E(k2) = (-0,12-(-1))2 i E(k3) = (0,23 - (-1))2 -> mam nadzieję, że jest to zrozumiałe :)

więc jeśli wykonam 1000 razy naukę, za każdym razem podstawiając kolejny znak z ciągu uczącego to czy wykonanie tych 1000 kroków jest wykonaniem jednej epoki?? A nauczanie kończymy po wykonaniu określonej ilości epok lub jeśli błąd jest dostatecznie mały?

Tak, jeśli masz próbę np. 1000 zdjęć to przeanalizowanie wszystkich to jedna "epoka" tzn. musisz uczyć sieć wiele razy na tej samej próbie aż się nauczy.
Zazwyczaj naukę kończy się po określonej liczbie iteracji - w zadaniach praktycznych nie wiesz jaki błąd jest wystarczający, żeby przerwać naukę. Zazwyczaj daje się również ograniczenia czasowe do nauki (pamiętaj, że im większa sieć (również im więcej zmiennych) tym proces nauki trwa dłużej - a przy tylu zmiennych co Ty masz (2500) może on trwać latami ^^ -> dlatego nie wiem, czy nie powinieneś skorzystać z jakiejś liniowej sieci np. RBF lub SVM chociaż z tą drugą nie miałem do czynienia :/).

Nie bardzo wiem w którym miejscu mi będzie potrzebna suma wszystkich pochodnych. Co masz na myśli że mam odjąć "jakąś" jej część??

zobacz swoje zdjęcie ze wzorami ^^. Ten dziwny znaczek (eta) przed deltą to jest właśnie ta "część" :)
Może jeszcze inaczej: (niestety nie ma tu LaTeXa :/) wzór na naukę masz taki: Wij(k+1) = Wij(k)+ep(k) (e -> to siła zmiany (właśnie ta eta) natomiast p to kierunek (pochodna) :P)). Teraz mamy wzór na błąd (funkcja celu): E(k) = suma(dla każdego wyjścia od i=1 do M=np.43) 1/2(Ykm-Zk)^2. Ykm (dla okresu k i neuronu wyjściowego m) wynosi: Ykm = f(suma Wjmf(suma WijXi))
gdzie f to oczywiście funkcja np. bipolarna. Zauważ, że obliczając pochodną po Wjm będziesz "ignorował" pozostałe wagi Wj (traktując je jako stałe) natomiast inaczej jest przy obliczaniu wag Wji, gdyż one mają wpływ na każdy neuron warstwy wyjściowej - dlatego obliczając pochodną po Wij z w/w funkcji będziesz musiał w rzeczywistości z sumować pochodne z każdego neuronu wyjściowego (mam nadzieję, że się nie rąbnąłem w tych dywagacjach :D)

4.3. Jeżeli skupimy się na wyliczaniu błędu w warstwie ostatniej dla m-tego neuronu to wykonujemy następujące obliczenia?:

  • Błąd_m = Y'_m * (Y_m - Z_m)
    czyli błąd dla m-tego neuronu to iloczyn: pochodnej m-tego neuronu z różnicą odpowiedzi neuronu z wzorcem (1 jeśli neuron rozpoznaje prawidłowy znak lub -1 jeśli to nie jest znak rozpoznawany przez dany neuron)

Nie myl obliczania błędu z tą regułą delta i całą nauką sieci. Błąd to zwyczajna różnica między wartością zadaną a wynikiem naszej sieci (najczęściej podniesiony do kwadratu -> co wynika z rozkładu normalnego ale to już inna bajka :) ). Może lepiej powtórzę to co napisałem wcześniej tj. rozwinę przykład:
załóżmy, że uczymy sieć 3 znaków. Do sieci wrzucamy 4 zmiennych boolowskich (0 lub 1). sieć ma 2 neurony ukryte i 3 wyjściowe. Znaki, których uczymy to: STOP-u (za który będzie odpowiedzialny pierwszy neuron wyjściowy), zakaz wjazdu (2 neuron) i nakaz jazdy prosto (3 neuron). Powiedzmy, że mamy 5 zdjęć znaków (2 stopu, 2 zakazu i 1 nakazu). W związku z powyższym nasz wektor uczący będzie wyglądał np. tak: dane_uczące = {STOP,ZAKAZ,STOP, ZAKAZ, NAKAZ} -> celowo zmieniłem kolejność bo nie musi być taka sama ale tak będzie łatwiej zrozumieć :].
Dlatego, że mamy tylko 5 danych (zdjęć) sieć będzie się uczyć tylko na ich podstawie.
teraz tak:
rozpatrujemy pierwsze zdjęcie:
nasz wektor wejściowy wygląda np. tak: [1,0,0,1]

  1. Wrzucamy ten wektor do każdego (czyli do dwóch) neuronu (tj. mnożymy każdą zmienną przez wagę w każdym neuronie (łącznie będzie ich 8 -> (2x4)
  2. sumy tych iloczynów w każdym neuronie wrzucamy do funkcji aktywacji
  3. funkcja zwraca nam jak jakąś liczbę (w bipolarnej będzie to liczba z zakresu (-1,1)
  4. załóżmy, że pierwszy neuron zwrócił wynik 0.37 a drugi -0.12
  5. wyniki z tych wyjść wrzucamy do neuronów wyjściowych mnożąc je wcześniej przez wagi (ukryte) stojące przy każdym neuronie (łącznie będzie ich 6 -> 2x3 = 6
  6. sumy przemnożonych sygnałów przez wagi wrzucamy do funkcji aktywacji w każdym neuronie. Sieć zwraca nam powiedzmy następujące wyniki: Y1 = 0.12, Y2 = -0.65, Y3 = 0.77
  7. Liczymy nasz błąd (pomijam 1/2 przed błędem) tj. E(k) = suma: (0.12-1)2 + (-0.65-(-1))2 + (0.77-(-1))^2 = ...
    Uwagi do pkt-u 7:
    przy liczeniu błędu w pierwszym neuronie wartość Y1 odejmujemy od 1 tj. nasze Z = 1 (gdyż ten neuron jest odpowiedzialny za znak STOP-u, który teraz rozpatrujemy)
    W pozostałych neuronach od Y2 i Y3 odejmujemy wartość -1 -> zauważ, że gdybyśmy odjęli te wartości od zera (0) to wynik błędu dla Y2, który jest bliski poprawnej odpowiedzi (-0.77 znaczy, że na pewno nie jest to znak ZAKAZ-u) byłby większy od Y3, a który jest znacznie dalej od poprawnej odpowiedzi (tj. stwierdzenia, że nie jest to znak NAKAZ-u)
  8. Obliczamy pochodne i zmieniamy wagi Wj i Wji w każdym neuronie
  9. ze zmienionymi wagami rozpatrujemy kolejne zdjęcie tj. znak ZAKAZ-u
  10. nasze nowe zmienne wejściowe wynoszą powiedzmy: [0,1,1,1]
    reszta jest identyczna poza liczeniem błędu tj. załóżmy, że nasze wyniki w tej iteracji wyniosły: Y1 = 0.45, Y2 = -0.9, Y3 = -0.15
    to licząc błąd będziemy mieli: E(k) = suma: (0.45 - (-1))2 + (-0.9-1)2 + (-0.15 - (-1))^2
    Jak zauważyłeś teraz rozważając wynik z pierwszego neuronu tj. Y1 odejmujemy od niego -1 (a nie 1 jak poprzednio gdyż teraz rozważamy inne zdjęcie) a dopiero w drugim mamy różnicę między wynikiem a 1

Mam nadzieję, że jest będzie to już jasna - trochę się rozpisałem (mam nadzieję, że nie za bardzo chaotycznie :)
Pozdrawiam,
S.W.

P.S.
Na którym roku i na jakim kierunku jesteś?</quote>

0

Małe sprostowanie,
właśnie doszło do mnie, że jednak nie musisz niczego zmieniać tj. możesz śmiało zostawić wektor uczący z liczbami binarnymi (bez zmieniania 0 na -1) -> W sumie to wynika również z tego co napisałem wyżej - tylko już nie myślę dzisiaj O_o (w końcu mamy weekend i nie trzeba :D)

0

Jestem na 4 roku - informatyka (inżynieria oprogramowania)

Na początek program będzie miał rozpoznawać znaki drogowe z obrazków które mu podam. Część odpowiedzialną za wydobycie obrazu ze znaku mam już prawie skończoną. Wydobywa framgęt obrazu ze znakiem, następnie go binaryzuję i skaluję do odpowiednich rozmiarów (50x50) i przesyłam do sieci. Później myślę nad wczytywaniem jakiegoś pliku video lub wczytywanie obrazu z kamerki. Ale najpierw będę musiał wykonać kilka testów wydajnościowych aby sprawdzić, czy mój program będzie w stanie rozpoznawać znaki w czasie rzeczywistym.

Myślę, że powoli zaczynam rozumieć działanie metody wstecznej propagacji błędów :-)
Jutro dokładnie przeanalizuję dokładnie to co napisałeś powyżej (zrobiło się już późno i mógłbym coś źle zinterpretować.. ) Jeśli coś jeszcze będzie dla mnie niezrozumiałe to będę pytał dalej :-)

pozdrawiam
Mateusz L

0

Może wymontuj gotowy system z jakiegoś nowego Opla :) (W Insignii debiutował ten system).

0

W Oplu Insignii z tego co się orientuję to system rozpoznaje tylko znaki zakazu (ograniczenia prędkości). Ja rozpoznaję znaki ostrzegawcze + znaki nakazu.

Problem już rozwiązałem i program jest już skończony i działa :) - znaki ostrzegawcze rozpoznaje poprawnie w ok 70% a znaki nakazu niestety gorzej bo w ok 30%.

0

Twoja sieć nie nauczy się rozpoznawania kształtów 2D. Bardzo małe zmiany, zniekształcenia, czy choćby przesunięcia całkowicie wypaczą wyniki.

Musisz zastosować inny rodzaj sieci. Sam to przechodziłem.

Tutaj masz przykład takiej sieci: http://www.codeproject.com/KB/library/NeuralNetRecognition.aspx#ConvolutionalStructure

Ta sieć jest odporna na zmiany kształtów, rozmiarów i wszelkie inne zniekształcenia.

0

Ja mam takie pytanie,bo implementuje podobną sieć na zajęcia, czy to normalne zaproponowana tu sieć neuronowa wielowarstwowa po nauczeniu nie zawsze rozpoznaje poprawnie wzorce z których się uczyła?

0

pamiętam taką historyjkę
sieć działała bezbłędnie pÓÓÓÓki, pÓÓÓÓki nie pokazało się jej nowych zdjęć
wcześniej na 100% odróżniała czołgi od ciężarówek, ale okazało się, że czołgi fotografowano akurat przy lepszym słońcu.
zadziwiająca ta wiara w działanie czegoś, czego działania nie da się zrozumieć

o tak, zaraz ktoś poda multum przykładów "zadziałania".
I co z tego? Ominąłem czarnego kota i fortepian nie spadł mi na głowę.
A co z tego wynika?

0
mag.Dobrowolski napisał(a)

zadziwiająca ta wiara w działanie czegoś, czego działania nie da się zrozumieć

Wydaje mi się, że ci, którzy tworzą SSN doskonale rozumieją jak ona działa, a przynajmniej powinni wiedzieć! Ja rozumiem a co więcej pokuszę się o stwierdzenie, że jej działanie jest banalnie proste...
Jeśli nie miałeś do czynienia z SSN to może to być dla Ciebie czarna skrzynka ale jak ktoś chce zrobić jakiś projekt wykorzystujący SSN to po prostu musi to rozumieć -> inaczej rzeczywiście może nie działać. Poza tym jeśli coś nie działa to nie znaczy, że się czegoś nie rozumie - po prostu problem nie jest wystarczająco prosty, żeby coś (np. SSN) sobie z tym poradziło...

1 użytkowników online, w tym zalogowanych: 0, gości: 1