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();
}