78168

Программирование искусственного нейрона

Лабораторная работа

Информатика, кибернетика и программирование

В данной лабораторной работе используются методы градиента и метод наискорейшего спуска для обучения нейрона в режиме оффлайн и правило Видроу-Хоффа для обучения нейрона в режиме онлайн

Русский

2017-10-18

93 KB

5 чел.

   Московский Государственный Технический Университет

им. Н.Э. Баумана

кафедра РК6 (САПР)

Отчёт

по лабораторной работе №3

по курсу "Интеллектуальные подсистемы САПР"

Группа: РК6-102

Студентка: Митина Е.В.

Преподаватель: Федорук В.Г.

Москва

2011

Программирование искусственного нейрона

Вариант 2-8.Тип нейрона – сигмоидальный нейрон. Вариант 8 обучающих данных.

Структурная схема сигмоидального нейрона представлена на рис. 1.

                         Рис. 1.  Структурная схема сигмоидального нейрона

Здесь  — взвешенная сумма входных сигналов, вычисляемая по формуле 

Выходной сигнал  вычисляется с использованием униполярной сигмоидальной функции активации в виде

где  — коэффициент "крутизны" функции.

Процесс обучения нейрона сводится к отысканию значений весов , доставляющих минимум целевой функции в виде 

где  — ожидаемое значение выходного сигнала нейрона при подаче на его вход 

-ой обучающей выборки, .

В данной лабораторной работе используются методы градиента и метод наискорейшего спуска для обучения нейрона в режиме "оффлайн" и правило Видроу-Хоффа для обучения нейрона в режиме "онлайн".

Результаты обучения

                                       Рисунок 1 – Результат работы обученного нейрона

Текст программы

//---------------------------------------------------------------------------

#include <math.h>

#include <stdlib.h>

#include <stdio.h>

#pragma hdrstop

//---------------------------------------------------------------------------

#pragma argsused

#include "Neir.h"

struct dann dann_obuch;

FILE *r;

double w[3], w_nach[3];

double u;

double nu_nach, nu_kon;

int t;

double vzvesh_sum( double w[3], double x[3]);

double funct_act( double b1, double u, double *f_pr);

void obuchenie(double w_new[3], double w_nach[3], double *nu_nach, double *nu_kon, int *t);

void obuchenie2(double w_new[3], double w_nach[3], double *nu_nach, double *nu_kon, int *t);

void obuchenie3(double w_new[3], double w_nach[3], int *t);

void testirovanie(double w[3]);

int main(int argc, char* argv[])

{

int i;

double W;

/* чтение данных обучения */

r=fopen("dan.txt","r");

fscanf(r, "%d\n",&i);

dann_obuch.k = i;

for (i=0;i< dann_obuch.k ;i++) fscanf(r, "%lf",&dann_obuch.x1[i]);

for (i=0;i< dann_obuch.k ;i++) fscanf(r, "%lf",&dann_obuch.x2[i]);

for (i=0;i< dann_obuch.k ;i++) fscanf(r, "%lf",&dann_obuch.d[i]);

fclose(r);

randomize();

r=fopen("rez.txt","w");

// obuchenie(w, w_nach, &nu_nach, &nu_kon, &t); /*оптимизацияметодомградиентаоффлайн*/

obuchenie2(w, w_nach, &nu_nach, &nu_kon, &t); /*оптимизацияметодомнаискорейшегоспускаоффлайн*/

// obuchenie3(w, w_nach, &t); /*методВидроу-Хоффаонлайн*/

    W = sqrt((w[0])*(w[0])+(w[1])*(w[1])+(w[2])*(w[2]));

// fprintf(r, "nu_nach= %f nu_kon= %f t= %d\n",nu_nach, nu_kon, t);

fprintf(r, "t= %d\n", t);

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

fprintf(r, "w_nach[%d]= % 11.6f w_kon[%d]= % 11.6f del[%d]= % 11.6f\n", i, w_nach[i], i, w[i], i, w[i]/W);

testirovanie(w);

fclose(r);

       return 0;

}

//---------------------------------------------------------------------------

double vzvesh_sum( double w[3], double x[3])

{

double u;

//  fprintf(r,"x[0]= % 10.6f x[1]= % 10.6f x[2]= % 10.6f\n", x[0], x[1], x[2]);

 u=x[0]*w[0]+x[1]*w[1]+x[2]*w[2];

return u;

}

double funct_act( double b1, double u, double *f_pr)

{

double f;

 f=1.0/(1.0+exp(-b1*u));

 *f_pr=b1*f*(1-f);

return f;

}

/*методградиента*/

void obuchenie(double w_new[3], double w_nach[3], double *nu_nach, double *nu_kon, int *t)

{

 double E, Enew, E_pr[3];

 double x[3],w[3];

 int i,j,sch=0, porog=2;

 double nu=0.5,d;

//  double eps=0.01;

 double f,f_pr;

 double nu_min=0.0001;

 *nu_nach=nu;

 *t=0;

 w_new[0]=-0.23; w_new[1]=-1.15; w_new[2]=0.46;

 for (j=0;j<3;j++) {w_new[j]= -2/sqrt(3)+(double)(rand()%10)/10*(4/sqrt(3));}  /*весаназначаютсяслучобразом*/

   for (j=0;j<3;j++) {w_nach[j]=w_new[j];}

 do

 {

  E=0; Enew=0; E_pr[0]=0; E_pr[1]=0; E_pr[2]=0;

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

   {

      x[0]=1;

      x[1]=dann_obuch.x1[i];

      x[2]=dann_obuch.x2[i];

      u=vzvesh_sum(w_new,x);

      f=funct_act(b,u,&f_pr);

      E+=1.0/2*(f-dann_obuch.d[i])*(f-dann_obuch.d[i]);

      d=(f-dann_obuch.d[i])*f_pr;

      E_pr[0]+=d*x[0];

      E_pr[1]+=d*x[1];

E_pr[2]+=d*x[2];

    }

    /*определение новых весов*/

w[0]=w_new[0]-nu*E_pr[0];

    w[1]=w_new[1]-nu*E_pr[1];

    w[2]=w_new[2]-nu*E_pr[2];

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

   {

      x[0]=1;

      x[1]=dann_obuch.x1[i];

      x[2]=dann_obuch.x2[i];

      u=vzvesh_sum(w,x);

      f=funct_act(b,u,&f_pr);

      Enew+=1.0/2*(f-dann_obuch.d[i])*(f-dann_obuch.d[i]);

  }

    if (Enew<E)

         {w_new[0]=w[0];

          w_new[1]=w[1];

          w_new[2]=w[2];

          sch+=1;

          if (sch>porog) {nu=nu*2; sch=0;}

         }

    if (Enew>=E)

        { nu=0.1*nu;

          sch=0;

        }

     *t+=1;

//   } while (fabs(E_pr[0]+E_pr[1]+E_pr[2])< eps);

  } while (nu>nu_min);

  *nu_kon=nu;

}

 void testirovanie(double w[3])

 {

  double x1_min=-6, x1_max=10;

  double x2_min=-10, x2_max=10;

  double x[3];

  double u,f,f_pr;

  int i,j, max=10, d;

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

  {

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

    {

     x[0]=1;

     x[1]=x1_min+(double)i/max*(x1_max-x1_min);

     x[2]=x2_min+(double)j/max*(x2_max-x2_min);

     u=vzvesh_sum( w,x);

     f=funct_act(b,u,&f_pr);

     if (f>0.5) d=1;

     if (f<=0.5) d=0;

     fprintf(r,"x[1]= % 10.6f x[2]= % 10.6f  d= % d f= % f\n", x[1], x[2], d, f);

    }

  }

 }

/*методнаискорейшегоспуска*/

 void obuchenie2(double w_new[3], double w_nach[3], double *nu_nach, double *nu_kon, int *t)

{

 double E=100000.0, E_pr[3], E_norm, S[3], ld_new, Ec, W, Es=10000.0;

 double x[3],w[3],eps_norm=0.001;

 int i,j;

 double ld=0.5,d;

 double f,f_pr;

 void poisk_ld(double *w_new,double *s,double ld,double *ld_new, double *Ec, double *w);

 *t=0;

//  w_new[0]=-0.23; w_new[1]=-1.15; w_new[2]=0.46;

 for (j=0;j<3;j++) {w_new[j]= -2/sqrt(3)+(double)(rand()%10)/10*(4/sqrt(3));}  /*весаназначаютсяслучобразом*/

   for (j=0;j<3;j++) {w_nach[j]=w_new[j];}

 do

 {

  Es = E;

  E=0; E_pr[0]=0; E_pr[1]=0; E_pr[2]=0;

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

   {

      x[0]=1;

      x[1]=dann_obuch.x1[i];

      x[2]=dann_obuch.x2[i];

      u=vzvesh_sum(w_new,x);

      f=funct_act(b,u,&f_pr);

      E+=1.0/2*(f-dann_obuch.d[i])*(f-dann_obuch.d[i]);

      d=(f-dann_obuch.d[i])*f_pr;

      E_pr[0]+=d*x[0];

      E_pr[1]+=d*x[1];

      E_pr[2]+=d*x[2];

    }

    E_norm=sqrt(E_pr[0]*E_pr[0]+E_pr[1]*E_pr[1]+E_pr[2]*E_pr[2]);

    S[0]=-E_pr[0]/E_norm;

    S[1]=-E_pr[1]/E_norm;

    S[2]=-E_pr[2]/E_norm;

    poisk_ld(w_new,S,ld,&ld_new, &Ec,w);

    if (ld!=0.0 && fabs(ld_new/ld)>10 && *t>1)

     {

      w[0] = w_new[0];

      w[1] = w_new[1];

      w[2] = w_new[1];

      break;

     }

    //      ld_new=1;

    W = sqrt((w_new[0]-w[0])*(w_new[0]-w[0])+(w_new[1]-w[1])*(w_new[1]-w[1])+(w_new[2]-w[2])*(w_new[2]-w[2]));

    w_new[0]=w_new[0]+ld_new*S[0];

    w_new[1]=w_new[1]+ld_new*S[1];

    w_new[2]=w_new[2]+ld_new*S[2];

    for (j=0;j<3;j++) {w_new[j]=w[j];}

    ld = ld_new;

    fprintf(r,"w[0]= % 10.6f w[1]= % 10.6f w[2]= % 10.6f  ldf= % f W=%f E=%e t=%d\n", w[0], w[1], w[2], ld_new, W, E, *t);

     *t+=1;

//   } while (E_norm>0.1e-30);

//   } while (fabs(Es-E)>0.00000001);

    } while (fabs(ld_new)>0.001);

}

void poisk_ld(double *w_new,double *s,double ld,double *ld_new, double *Ec, double*w)

  {

    double E1, E2, rl=1, x[3],Es=1000.0;

    double f, f_pr, u, ln, lk;

    int j;

     Es=1000.0;

    ln = ld;

//     ln = 0;

    do

    {

      w[0] = w_new[0] + ln*s[0];

      w[1] = w_new[1] + ln*s[1];

      w[2] = w_new[2] + ln*s[2];

      E1=0;

      for (j=0;j<dann_obuch.k;j++)

       {

         x[0]=1;

         x[1]=dann_obuch.x1[j];

         x[2]=dann_obuch.x2[j];

         u=vzvesh_sum(w,x);

//  fprintf(r,"1 w[0]= % 10.6f w[1]= % 10.6f w[2]= % 10.6f u= % 10.6f\n", w[0], w[1], w[2],u);

         f=funct_act(b,u,&f_pr);

         E1+=1.0/2*(f-dann_obuch.d[j])*(f-dann_obuch.d[j]);

       }

//        if(E1<0.000001) break;

//        if(E1>Es) break;

       Es =E1;

      lk = ln+rl;

      w[0] = w_new[0] + lk*s[0];

      w[1] = w_new[1] + lk*s[1];

      w[2] = w_new[2] + lk*s[2];

      E2=0;

      for (j=0;j<dann_obuch.k;j++)

       {

         x[0]=1;

         x[1]=dann_obuch.x1[j];

         x[2]=dann_obuch.x2[j];

         u=vzvesh_sum(w,x);

//  fprintf(r,"2 w[0]= % 10.6f w[1]= % 10.6f w[2]= % 10.6f u= % 10.6f rl= % 10.6f\n", w[0], w[1], w[2],u,rl);

         f=funct_act(b,u,&f_pr);

         E2+=1.0/2*(f-dann_obuch.d[j])*(f-dann_obuch.d[j]);

       }

//  fprintf(r,"3 E1= % 10.6f E2= % 10.6f rl= % 10.6f\n", E1, E2,rl);

//      if(fabs(E1-E2)<0.00001) break;

if (E2>E1)

      {

       rl /=-2.0;

      }

      else

      {

       rl *=2.0;

       ln = lk;

      }

       if(fabs(rl)>10.0) break;

     } while(fabs(rl)>0.001);

     *Ec=E1;

*ld_new=ln;

}

/*онлайнВидроу-Хоффа*/

void obuchenie3(double w_new[3], double w_nach[3], int *t)

{

 int k,j;

 int prizn=0; /* cигнал об окончании процесса*/

double eps=0.0000001,u,f,E, f_pr, x[3];

 double delt[3]; /* x*(y-d)*/

 w_new[0]=-0.23; w_new[1]=-1.15; w_new[2]=0.46;

 for (j=0;j<3;j++) {w_new[j]= -2/sqrt(3)+(double)(rand()%10)/10*(4/sqrt(3));}  /*весаназначаютсяслучобразом*/

 for (j=0;j<3;j++) {w_nach[j]=w_new[j];}

 *t=0;

do

  {

   for (k=0,prizn=0;k<dann_obuch.k;k++)

   {

      x[0]=1;

      x[1]=dann_obuch.x1[k];

      x[2]=dann_obuch.x2[k];

      u=vzvesh_sum(w_new,x);

      f=funct_act(b,u,&f_pr);

      delt[0]=x[0]*(f-dann_obuch.d[k]);

      delt[1]=x[1]*(f-dann_obuch.d[k]);

      delt[2]=x[2]*(f-dann_obuch.d[k]);

      w_new[0] = w_new[0] - delt[0];

      w_new[1] = w_new[1] - delt[1];

      w_new[2] = w_new[2] - delt[2];

      if (fabs(delt[0])>eps) prizn=1;

      if (fabs(delt[1])>eps) prizn=1;

      if (fabs(delt[2])>eps) prizn=1;

}

   *t+=1;

   } while(prizn==1);

}