Witam,
mógłby ktoś pomóc, znalazłem w necie kod programu do rozpoznawania liter w SSN wielowarstwowych. Potrzebuje zmienić to na jednowarstwową. ;) Tak zęby nie było warstwy ukrytej itp.
Proszę o jakaś podpowiedź ;)
#pragma hdrstop
#include <iostream.h>
#include <stdlib.h>
#include <math.h>
#include "neuron_w.h"
#pragma package(smart_init)
const MascCount = 26; // liczba wzorcow
const InX = 5; // wejsc po osi X
const InY = 6; // wejsc po osi Y
const InMax = InX*InY; // maks. liczba wejsc
const OutMax = MascCount; // il. wyjsc = il. wejsc
const NeuronCountHide = 10; // liczba neuronow w ukrytej warstwie
const MascLength = 30; // liczba pozycji we wzorcu
double eta = 0.8; // wspol. uczenia
double alfa = 0.75; // moment - ogranicza przyciaganie do minimum lok.
double beta = 0.8; // wspol. krzywej aktywacji - funkcji sigmoidalnej
// neuron warstwy ukrytej
typedef struct TNeuron1
{
double waga[MascLength+1];
double pop[MascLength+1];
double wej;
double wyj;
double delta;
}TNeuron1;
// nauron warstwy wyjsciowej
typedef struct TNeuron2
{
double waga[NeuronCountHide+1];
double pop[NeuronCountHide+1];
double wej;
double wyj;
double delta;
}TNeuron2;
// wzorzec - wektor uczacy
typedef struct TMasc
{
char litera;
char _wzorzec[MascLength];
char _wyjscie[OutMax];
}TMasc;
TMasc _wzorce[MascCount]; // wektor wzorcowy
double _wejscie[MascLength];
double _wyjscie[OutMax];
TNeuron1 w_ukryta[NeuronCountHide]; // warstwa ukryta neuronów
TNeuron2 w_wyj[OutMax]; // warstwa wyjsciowa
double blad_sieci=0.0;
double b=0.0;
// reset sieci - generacja wag losowych
void NetReset(void)
{
int i, j;
for (i=0;i<NeuronCountHide;i++)
for (j=0;j<MascLength+1;j++)
{
w_ukryta[i].waga[j] = (rand()%1000)/(RAND_MAX + 1.0);
w_ukryta[i].pop[j] = 0.0;
if (rand()%2 == 1)
w_ukryta[i].waga[j] = -w_ukryta[i].waga[j];
}
for (i=0;i<OutMax;i++)
for (j=0;j<NeuronCountHide+1;j++)
{
w_wyj[i].waga[j] = (rand()%1000)/(RAND_MAX + 1.0);
w_wyj[i].pop[j] = 0.0;
if (rand()%2 == 1)
w_wyj[i].waga[j] = -w_wyj[i].waga[j];
}
}
// przetworzenie epoki wektora uczacego
void Transform(int value = 0)
{
int i, j;
double w_tmp;
//*** ustawienie sygnalu - wejscia neuronow
// warstwa ukryta
for (i=0;i<NeuronCountHide;i++)
{
w_ukryta[i].wej = 1.0*w_ukryta[i].waga[0];
for (j=0;j<MascLength;j++)
w_ukryta[i].wej += w_ukryta[i].waga[j+1]*_wejscie[j];
w_ukryta[i].wyj = 1.0/(double)(1.0+exp(beta*(-w_ukryta[i].wej)));
}
// warstwa wyjsciowa
for (i=0;i<OutMax;i++)
{
w_wyj[i].wej = 1.0*w_wyj[i].waga[0];
for (j=0;j<NeuronCountHide;j++)
w_wyj[i].wej += w_wyj[i].waga[j+1]*w_ukryta[j].wyj;
w_wyj[i].wyj = 1.0/(double)(1.0+exp(beta*(-w_wyj[i].wej)));
}
//*** jezli uczymy, a nie rozpoznajemy...
if (value)
{
//*** bledy na neuronach
// warstwa wyjsciowa
for (i=0;i<OutMax;i++)
w_wyj[i].delta = (_wyjscie[i]-w_wyj[i].wyj)*w_wyj[i].wyj*(1.0-w_wyj[i].wyj); //(d-y)*y*(1-y)
// warstwa ukryta
for (i=0;i<NeuronCountHide;i++)
{
w_ukryta[i].delta = 0.0;
for (j=0;j<OutMax;j++)
w_ukryta[i].delta += w_ukryta[i].wyj*(1.0-w_ukryta[i].wyj)*w_wyj[j].delta*w_wyj[j].waga[i+1];
}
//*** adaptacja wag
// warstwa ukryta
for (i=0;i<NeuronCountHide;i++)
for (j=0;j<MascLength+1;j++)
{
w_tmp = w_ukryta[i].waga[j];
if (!j) w_ukryta[i].waga[j] += eta*w_ukryta[i].delta*1.0+alfa*(w_ukryta[i].waga[j]-w_ukryta[i].pop[j]);
else
w_ukryta[i].waga[j] += eta*w_ukryta[i].delta*_wejscie[j-1]+alfa*(w_ukryta[i].waga[j]-w_ukryta[i].pop[j]);
w_ukryta[i].pop[j] = w_tmp;
}
// warstwa wyjsciowa
for (i=0;i<OutMax;i++)
for (j=0;j<NeuronCountHide+1;j++)
{
w_tmp = w_wyj[i].waga[j];
if (!j) w_wyj[i].waga[j] += eta*w_wyj[i].delta*1.0+alfa*(w_wyj[i].waga[j]-w_wyj[i].pop[j]);
else
w_wyj[i].waga[j] += eta*w_wyj[i].delta*w_ukryta[j-1].wyj+alfa*(w_wyj[i].waga[j]-w_wyj[i].pop[j]);
w_wyj[i].pop[j] = w_tmp;
}
//*** blad calkowity sieci
b=0.0;
for (i=0;i<OutMax;i++)
b += (_wyjscie[i]-w_wyj[i].wyj)*(_wyjscie[i]-w_wyj[i].wyj);
blad_sieci = sqrt(b/(double)(MascCount*OutMax));
}
}
// nauka reczna
void naucz(double wspolczynnik)
{
int i, j;
eta = wspolczynnik;
for (i=0;i<MascCount;i++)
{
for (j=0;j<MascLength;j++)
if (_wzorce[i]._wzorzec[j] == '1') _wejscie[j] = 1.0;
else _wejscie[j] = 0.0;
// zaladowanie wyjscia d
for (j=0;j<OutMax;j++)
if (_wzorce[i]._wyjscie[j] == '0') _wyjscie[j] = 0.0;
else _wyjscie[j] = 1.0;
//przetworzenie epoki wektora uczacego
Transform(1);
}
}
// generowanie wyjscia we wzorcu
void GenOutput(void)
{
int i, j;
for (i=0;i<MascCount;i++)
for (j=0;j<OutMax;j++)
if (i==j) _wzorce[i]._wyjscie[j] = '1';
else _wzorce[i]._wyjscie[j] = '0';
}
// wczytanie wzorcow
void ReadMasc(void)
{
FILE * _wzorce_plik;
int i=0;
_wzorce_plik = fopen("wzorce.txt","rt");
while (fscanf(_wzorce_plik,"%s %c",_wzorce[i]._wzorzec,&(_wzorce[i].litera))==2)i++;
fclose(_wzorce_plik);
GenOutput();
}