Ciągle "walczę" z sieciami jednowarstwowymi, autoasocjacyjnymi. Tym razem zacząłem robić Hebba. Sieć nie ma funkcji aktywacji, a modulacja wag wygląda następująco:

 setW(i, j, getW(i, j) + getEta()*getO(1,i)*getO(0, j));

Słowem teorii: ustawiamy dla neuronu numer i znajdującego się na ostatniej sieci wagę j, która jest powiększana o iloczyn współczynnika eta (ustawiłem na 0.01), wejście z poprzedniej sieci (albo 0, albo 1, bowiem na wejście wprowadzamy zero-jedynkowy obraz danej cyfry, który sieć ma rozpoznać) oraz wyjście, które jest sumą iloczynów wag z poprzedniego cyklu oraz wejść:

 for (int i = 0; i < getN(1); i++)
		{
			tmp[i] = 0;
			for (int j = 0; j < getN(0); j++)
				tmp[i] += getO(0, j) * getW(i, j); // O[0][j], wejście z poprzedniej, zerowej sieci (0 lub 1) numer j (0-35), W[i][j] - wagi na ostatniej warstwie dla neuronu i, numer j (od         0-35)
                        setO(1, i, tmp[i]);
		}

Sieć w domyśle ma wzmacniać wyjścia odpowiadające wprowadzonemu wzorcowi, co ma się ładnie manifestować na wyjściu sieci. A jak wygląda praktyka?

 OOO
O   O
O   O
O   O
O   O
O   O
 OOO
Wyjscie 0: -162.806
Wyjscie 1: -27.5472
Wyjscie 2: 151.101
Iteracja: 97

  O
 OO
O O
  O
  O
  O
  O
Wyjscie 0: -55.7742
Wyjscie 1: -9.49338
Wyjscie 2: 51.715
Iteracja: 98

  O
 OO
O O
  O
  O
  O
  O
Wyjscie 0: -60.7938
Wyjscie 1: -10.3478
Wyjscie 2: 56.3693
Iteracja: 99

 OOO
O   O
    O
   O
  O
 O
OOOOO
Wyjscie 0: -163.024
Wyjscie 1: -27.643
Wyjscie 2: 150.965
Iteracja: 100

  O
 OO
O O
  O
  O
  O
  O
Wyjscie 0: -71.156
Wyjscie 1: -12.1084
Wyjscie 2: 65.9715
Iteracja: 101

A no tak: przedstawione obrazki to to, co zostało wprowadzone na wejście (35 neuronów 5x7 składające się na obraz), gdzie zamiast jedynki jest kółko, a zamiast zera pusta przestrzeń. Sieć wzmacnia w momencie zmiany wprowadzonych wzorców dosłownie każdy sygnał, który finalnie jest albo coraz mniejszy, albo coraz większy, w zależności od wylosowanych wag początkowych, więc w konsekwencji nic nam to nie mówi o klasyfikowaniu wzorców. Generalnie: mimo poprawnej, książkowej implementacji, na wyjściach mam totalny, nic nieznaczący rezultat. Być może problemem jest sposób, w jaki uczę sieć? Aktualnie co pojedynczy cykl zmieniam dane wejściowe na losowo wybraną cyfrę: albo 0, albo 1, albo 2. Ma ktoś pomysł, jak to wszystko zoptymalizować?