Sieci neuronowe - obiektowo

0

Witam,
chciałbym samodzielnie zaimplementować sztuczną sieć neuronową obiektowo w C++. Podstawy teoretyczne (w tym obliczanie pochodnych etc.) mam opanowane bardzo dobrze. Niestety w programowaniu nie jestem już tak mocny jak w matematyce i dlatego mam prośbę do was o pomoc. Chodzi mi jak najlepiej byłoby zrobić? Jakie zrobić klasy, co dana klasa powinna zawierać, jak je połączyć, jakich mechanizmów użyć? etc.

W necie znalazłem kilka bibliotek open source ale one są strasznie rozbudowane i ciężko mi je analizować :(. Chciałbym zrobić coś swojego ale znacznie mniej rozbudowanego.

Czy miałby może ktoś dostęp do jakiś materiałów etc. które opisują tylko sam sposób takiej implementacji niekoniecznie z kodem - chociaż to byłoby również bardzo pomocne w analizie :).
Ważne jest również, żeby było to opisane w C++ bo póki co nie znam innego języka programowania (poza C, które niewiele się różni od C++ poza obiektowością).

Póki co mam tylko wstępną koncepcję jak zrobić klasę pojedynczego neuronu :) która przechowywałaby wskaźnik do tablicy z wagami, bias, wynik wyjścia neuronu (czyli f(z sumy wag*wejście+bias)) -> oczywiście byłoby kilka wzorów na funkcję aktywacji (liniowa, sigmoidalna, bipolarna, sin/cos etc.) i odpowiednio pochodne do nich.

Nie wiem natomiast jak połączyć te wszystkie neurony w danej warstwie i w całej sieci :(. Nie wiem w którym miejscu napisać funkcję, która by modyfikowała wagi (uczyła sieć) i jak ją zorganizować itd.
Potrzebuję jakiegoś planu na zrobienie tego :/
Znalazłem jakąś pracę, że należałoby zrobić klasę neuron, warstwa i sieć ale bez większych szczegółów :(.

Bardzo proszę o pomoc osoby, które już robiły podobne projekty lub wiedzą jak mi pomóc.
pozdrawiam i z góry dziękuję!

0

Robienie klasy dla pojedynczego neuronu jest ogromnym marnotrawstwem pamięci i wydajności. Wszystkie obliczenia najlepiej zrobić na macierzach, gdzie sieć o n wymiarach reprezentuje n-1 macierzy wag.

0

Dlaczego uważasz, że jest to marnotrastwo pamięci? Co za różnica czy zrobić tablicę 2D neuronów, który ma swoją tablicę wag czy zrobić tablicę 3D dla wag?
Oczywiście zapewne nie będzie to najszybszy sposób ale nie przesadzajmy już - parę sekund nie robi mi różnicy... Poza tym mi chodzi o łatwość modyfikowania takiego kodu! Chciałem kilka rzeczy wypróbować w tym algorytmy uczenia, strukturę sieci, różne funkcje etc. W tym własne modyfikacje.

tutaj: http://www.ai.c-labtech.net/sn/pod_prakt.html jest ładny przykład jak to zrobić strukturalnie, ale taki kod dosyć ciężko modyfikować i nie wygląda zbyt przyjaźnie...

Dlatego wydaje mi się, że lepiej już trochę poświęcić tej pamięci niż robić wszystko na max-a optymalnie. Projekt jest typowo badawczy :)

Obiektowość nie jest moją mocną stroną - jeszcze się jej uczę i SSN to takie małe wyzwanie dla mnie :) -> ponieważ teorię mam bardzo dobrze opanowaną więc teraz trzeba "tylko" napisać kod :)

Moim celem jest właśnie takie zbudowanie sieci, bym mógł wprowadzać swoje pewne koncepcje i je porównać z innymi.

Bardzo proszę o jakieś podpowiedzi :)

1

Jeżeli chcesz zamienić używanie wydajnej biblioteki do obliczeń macierzowych na samodzielną zabawę z dziesiątkami obiektów, to proszę bardzo. Żeby implementacja SN była łatwa do przetestowania różnych funkcji/algorytmów uczących wcale nie musi być tak "przeobiektowana". Nie wydaje mi się, żeby stworzenie obiektu dla neuronu w jakikolwiek sposób ułatwiło pracę z tym kodem. Jak masz w macierzy wagi i dobrą bibliotekę macierzową to możesz zrobić ładny, kompaktowy kod nie bawiąc się jak w podanym przykładzie w indeksy.

0

W takim razie pozostaje pytanie "jak to zorganizować" - chociaż jakiś ogólny szkielet...

0

Ogólnie masz dużo parametrów, które znacząco wpływają na zachowanie sieci. Po pierwsze oczywiście funkcja aktywacji (potrzebujesz jej, oraz jej pochodnej). Po drugie rodzaj treningu (batch, czy online) i dokładny algorytm (Rprop, LM, największego spadku itp.), z których nie każdy jest dostępny przy każdym rodzaju uczenia. Po trzecie funkcja kosztu i powiązana z nią propagacja wsteczna. Ogólnie samą strukturę sieci (wagi) trzymam w jednym obiekcie który jest polem razem z wymienionymi wcześniej rzeczami obiektu "zewnętrznego".

0
Zjarek napisał(a)

Ogólnie masz dużo parametrów, które znacząco wpływają na zachowanie sieci. Po pierwsze oczywiście funkcja aktywacji (potrzebujesz jej, oraz jej pochodnej). Po drugie rodzaj treningu (batch, czy online) i dokładny algorytm (Rprop, LM, największego spadku itp.), z których nie każdy jest dostępny przy każdym rodzaju uczenia. Po trzecie funkcja kosztu i powiązana z nią propagacja wsteczna. Ogólnie samą strukturę sieci (wagi) trzymam w jednym obiekcie który jest polem razem z wymienionymi wcześniej rzeczami obiektu "zewnętrznego".

Zjarek, po pierwsze dzięki za wypowiedzi - temat nie jest chyba zbyt popularny więc nie mogę liczyć na zbyt duży udział innych forumowiczów :)
Chodzi mi właśnie o to, żeby łatwo było zaimplementować różne algorytmy, różne funkcje aktywacji etc. żeby to nie była jedna prosta sieć ale narzędzie, które będzie mogło wykorzystać wiele rodzajów tych rzeczy.
Z funkcją aktywacji i jej pochodną jest w miarę łatwo - wystarczy coś takiego:

double fun_akt(double x; int rodzaj_fun){
   double exp = exp(-x);
   swich(rodzaj_fun)
   {
      case 0:
      return 1.0/(1.0+exp);
      case 1:
      //...
   }
}

Gorzej już z algorytmem uczenia - liczyłem, że łatwiej to będzie obiektowo...
Tak samo jeśli chodzi o rodzaj treningu - chciałbym mieć to do wyboru - ale myślałem, że da się to jakoś lepiej zorganizować obiektowo -> jak pisałem coś podobnego strukturalnie to dałem if-a przy obliczaniu pochodnej i było coś w stylu if(online) //liczenie pochodnej dla danej próby... a dla off-line było identycznie tylko sumowanie sumowanie obliczonych wcześniej pochodnych... Ale to jest dosyć kłopotliwe i zorganizowanie takiej funkcji nauki SSN z kilkoma algorytmami uczenia etc. jest bardzo rozbudowane i ciężko się w tym połapać. Później każda zmiana jest bardzo kłopotliwa...
Aha, i jakby co to tak jak wspomniałem wcześniej - ja znam bardzo dobrze SSN z teoretycznego punku więc teraz chciałem się skupić tylko jak to zorganizować w C++ :)
pozdrawiam

0
Zjarek napisał(a)

Robienie klasy dla pojedynczego neuronu jest ogromnym marnotrawstwem pamięci i wydajności. Wszystkie obliczenia najlepiej zrobić na macierzach, gdzie sieć o n wymiarach reprezentuje n-1 macierzy wag.

Tylko wtedy to nie będzie programowanie obiektowe.

0

Na Twoim miejscu nie pisałbym tego w C++. chyba, że chcesz to zrobić w ramach "wprawki programistycznej" a nie żeby zobaczyć jak działają SSN. Mniejszym nakładem pracy zrealizujesz to przy pomocy np. Octave.
http://metaoptimize.com/qa - to jest bardzo ciekawe forum. Często polecają też pythona+numpy jednak sam tego nie próbowałem. @Zjarek ma oczywiście rację - użycie dobrej biblioteki do obliczeń numerycznych zaoszczędzi Ci sporo czasu, obliczenia wykonają się znacznie szybciej niż sam byś je napisał oraz skupisz się tak na prawdę na tym co Cię interesuje.

0
somekind napisał(a)

Tylko wtedy to nie będzie programowanie obiektowe.

A mógłbyś coś doradzić plz!

mychal.szczygiel napisał(a)

Na Twoim miejscu nie pisałbym tego w C++. chyba, że chcesz to zrobić w ramach "wprawki programistycznej" a nie żeby zobaczyć jak działają SSN. Mniejszym nakładem pracy zrealizujesz to przy pomocy np. Octave.
http://metaoptimize.com/qa - to jest bardzo ciekawe forum. Często polecają też pythona+numpy jednak sam tego nie próbowałem. @Zjarek ma oczywiście rację - użycie dobrej biblioteki do obliczeń numerycznych zaoszczędzi Ci sporo czasu, obliczenia wykonają się znacznie szybciej niż sam byś je napisał oraz skupisz się tak na prawdę na tym co Cię interesuje.

Tak, po pierwsze chcę to zrobić w ramach "wprawki programistycznej" - chcę sobie utrwalić programowanie obiektowe a jednocześnie zrobić badania pewnych własnych usprawnień SSN a nie bazować na gotowcach...
Dodatkowo tak jak już wcześniej wspomniałem ja dokładnie wiem jak działają SSN i kwestie teoretyczne opanowałem bardzo dobrze!
pozdrawiam

0
WsaL napisał(a)

A mógłbyś coś doradzić plz!

Tak, używanie wyszukiwarki. Np.: http://4programmers.net/Forum/Algorytmy/147499-Backpropagation_i_SSN_typu_RBF?p=560687#id560687

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