Решение задач кластеризации и аппроксимации в нейросетевом логическом базисе. Описание сети Кохонена (алгоритм работы), страница 3

puts("...Чтение файла закончено");

/* Инициализация начальных весов */

randomize();

for (j=0;j<n;j++)

for (i=0;i<k;i++)

{

alpha[i+j*k]=float(random(100))/100;

alphaS[i+j*k]=alpha[i+j*k];

}

t=1;

/*Чтение входного обучающего файла*/

for (j=0;j<m;j++)

{

for (i=0;i<k;i++) Xs[j][i]=fgetc(trenir)-'0';

fgetc(trenir);

}

do

{

for (s=0;s<m;s++)

{

for (i=0;i<k;i++) temp[i]=Xs[s][i];

/* Определение откликов нейронов слоя Кохонена */

yi=Otklik(&temp[0],&alpha[0]);

/* Коррекция весов */

Function_Korrect(yi,t,&temp[0],&alpha[0]);

}

for (j=0;j<n;j++)

for (i=0;i<k;i++)

if (fabs(alphaS[i+j*k]-alpha[i+j*k])<eps)

{

alphaS[i+j*k]=alpha[i+j*k];

l++;

}

else alphaS[i+j*k]=alpha[i+j*k];

if (l==n*k) t++;

l=0;

}

while (t<T);

puts("....Обучение закончено");

puts("\nДля вывода результатов нажмите <Enter>");

ch=getchar();

/* Запись полученных весов в файл ves_ner.dat */

ves_ner=fopen("ves_ner.dat","w");

for (j=0;j<n;j++)

for (i=0;i<k;i++)

fprintf(ves_ner,"\t%f%s",alpha[i+j*k],"");

clrscr();

}

/* Тестирование сети */

void Test_net (void)

{

test=fopen("test.dat","r");

trenir=fopen("trenir.dat","r");

fscanf(trenir,"%d",&k);

fscanf(trenir,"%d",&n);

fscanf(trenir,"%d",&m);

fgetc(trenir);

clrscr();

/* Тестовой последовательности из файла test.dat */

for (i=0;i<k;i++) temp[i]=fgetc(test)-'0';

/*определение класса тестового примера*/

yi=Otklik(&temp[0],&alpha[0]);

/* Вывод результатов обучения*/

puts("** Номер нейрона **      Тестовый пример  ** ");

puts("** (тестовый)    **                       ** ");

printf("%s%d","       ",yi,"       ");

printf("             ");

for (i=0;i<k;i++) printf("%1.0f",temp[i]);

puts("\n");

puts("Нажмите Enter ... для вывода результатов");

ch=getch();

clrscr();

puts("** Номер нейрона     ** Номер обучающей    **       Входной вектор  **");

puts("** (класса)          ** последовательности **                       **");

for(j=0;j<m;j++)

{

for (i=0;i<k;i++) temp[i]=Xs[j][i];

yi=Otklik(&temp[0],&alpha[0]);

printf("%s%d","           ",yi);

printf("           ");

printf("%s%d%s%d%s"," ",j+1,"(",m,")");

printf("                  ");

for (i=0;i<k;i++) printf("%1.0f",temp[i]);

puts("\t");

if (i==60) { ch=getch();puts("\n Нажмите Enter для продолжения...");}

if (ch==27) break ;

}

ch=getch();

clrscr();

puts("....Тестирование закончено");

puts("Нажмите <Enter>");

ch=getchar();

}

void Exit_prog  (void)

{

exit(EXIT_SUCCESS);

}

Функция  void Obuchen (void) , блок программы реализующий обучение сети Кохонена.

Функция int Otklik( float *Xs, float *alpha) определяет отклики всех нейронов слоя Кохонена по формуле : yj=aij*xsi ,  j=1,n    и  выбирает нейрон победитель, т.е. нейрон с наибольшим откликом. 

Функция  void Test_net (void) , отвечающая за блок тестирования сети.

Функция void Function_Korrect(int index,int t, float *Xs, float *alpha) выполняет коррекцию весов по следующей формуле : aij=aij+g*g(r,t)*(xsi-aij)

Функция int g(int r, int t) представляет собой g(r,t) - параметр, характеризующий процесс обучения. g(r,t) - функция влияния нейронов друг на друга, где r - расстояние между нейронами, t - время, характеризующее длительность процесса обучения t = 1,2,3... . Функция g(r,t) имеет вид «мексиканской шляпы», которая в процессе обучения должна сужаться. Например,

g(r,t) = 1, если r < D/t

g(r,t) = 0, иначе,                

где D - константа, характеризующая начальный радиус пика «мексиканской шляпы».