Listing des Programms BACKPRO2.C


/*      Programm backpro2.c                                    */        
/*      3-Schicht-Netz mit Werbos Backpropagation-Lernregel    */
/*      --- Spezielle Version fuer Standardbeispiel ---        */
/*      Burkhard Lenze                                         */
/*      13.02.2009                                             */

/*      header-files                                           */

#include <stdio.h>
#include <math.h>
#include "backpro2.h"

/*      globale Variablen                                                 */

float x[5][500];                 /*  Eingabevektorfeld                    */
float y[5][500];                 /*  Ausgabevektorfeld                    */
float theta[30];                 /*  Schwellwertvektorfeld                */
float w[30][30];                 /*  Matrixfeld der Eingangsgewichte      */
float g[30][30];                 /*  Matrixfeld der Ausgangsgewichte      */
float x_test[5];                 /*  Aktueller Testeingang                */
float y_test[5];                 /*  Aktueller Testausgang                */
int n=2;                         /*  Anzahl der Eingabe-Neuronen          */
int q;                           /*  Anzahl der verborgenen Neuronen      */
int m=1;                         /*  Anzahl der Ausgabe-Neuronen          */
int Pxy;                         /*  Anzahl der x-y-Abtastpunkte          */
int t;                           /*  Anzahl der Assoziationen (t=Pxy*Pxy) */
int s;                           /*  Anzahl der Trainingszyklen           */
int s_max;                       /*  Maximalzahl der Trainingszyklen      */
float epsilon;                   /*  Maximaler Ausgabefehler              */
float beta;                      /*  Stauchungsparameter                  */
float lambda;                    /*  Lernrate                             */
char com;                        /*  Menuparameter                        */

/*      Funktionen               */

void lese_x_test(void)
    {
    int i;
    printf("\n");
    for (i=1;i<=n;i++)
         {
         printf("x[%1d] = ? ",i);
         scanf("%f",&x_test[i]);
         }
    }

float f(float x1, float x2)
    {
    float Z;
    Z=1.0;
    if (x1+x2>=1.5) {Z=0.0;}
    if ((x1<=0.5)&&(x2<=0.25)) {Z=0.0;}
    return(Z);
    }

void lese_x_y(void)
    {
    int k,l,ss;
    for (l=1;l<=Pxy;l++)
         {
         for (k=1;k<=Pxy;k++)
             {
             ss=(l-1)*Pxy+k;
             x[1][ss]=(k-1.0)/(Pxy-1.0);
             x[2][ss]=(l-1.0)/(Pxy-1.0);
             y[1][ss]=f((k-1.0)/(Pxy-1.0),(l-1.0)/(Pxy-1.0));
             }
         }
    }

float T(float A)
    {
    float Z;
    Z=1.0/(1.0+exp(-(beta*A)));
    return(Z);
    }

float TS(float A)
    {
    float Z;
    Z=(beta*exp(-(beta*A)))/((1.0+exp(-(beta*A)))*(1.0+exp(-(beta*A))));
    return(Z);
    }

void lernen(void)
    {
    int i,j,p,st,z;
    float A[30],B[30],C[30],y_[10],H,err;
    lese_x_y();
    s=0;
    do
      {
      s=s+1;
      for (st=1;st<=t;st++)
          {
          for (p=1;p<=q;p++)
              {
              H=0.0;
              for (i=1;i<=n;i++) {H=H+(w[i][p]*x[i][st]);}
              A[p]=T(H-theta[p]);
              B[p]=TS(H-theta[p]);
              }
          for (j=1;j<=m;j++)
              {
              y_[j]=0.0;
              for (p=1;p<=q;p++) {y_[j]=y_[j]+g[p][j]*A[p];}
              }
          for (p=1;p<=q;p++)
              {
              C[p]=0.0;
              for (j=1;j<=m;j++) {C[p]=C[p]+(y[j][st]-y_[j])*g[p][j];}
              }
          for (j=1;j<=m;j++)
              {
              for (p=1;p<=q;p++)
                  {
                  g[p][j]=g[p][j]+lambda*2.0*(y[j][st]-y_[j])*A[p];
                  }
              }
          for (p=1;p<=q;p++)
              {
              for (i=1;i<=n;i++)
                  {
                  w[i][p]=w[i][p]+lambda*2.0*C[p]*B[p]*x[i][st];
                  }
              theta[p]=theta[p]-lambda*2.0*C[p]*B[p];
              }
          }
      err=0.0;
      for (st=1;st<=t;st++)
          {
          for (j=1;j<=m;j++)
              {
              y_[j]=0.0;
              for (p=1;p<=q;p++)
                  {
                  H=0.0;
                  for (i=1;i<=n;i++) {H=H+(w[i][p]*x[i][st]);}
                  y_[j]=y_[j]+g[p][j]*T(H-theta[p]);
                  }
              err=err+(y[j][st]-y_[j])*(y[j][st]-y_[j]);
              }
          }
      z=1;
      if ((s_max/100)>=1) {z=s_max/100;}
      if (s%z==0)
         {
         printf("\nEs wurden bereits %8d Lernzyklen durchlaufen! ",s);
         printf("\nDer summierte quadrierte Fehler lautet: %f ",err);
         }
      if (err<epsilon)
         {
         printf("\n\nEs wurden genau %8d Lernzyklen durchlaufen! ",s);
         printf("\nDer summierte quadrierte Fehler lautet: %f ",err);
         printf("\n\nFehler kleiner als %f !!!\n",epsilon);
         printf("\n\nAbbruch des Lernalgorithmus !!!\n");
         }
      if (s==s_max)
         {
         printf("\n\nEs wurden genau %8d Lernzyklen durchlaufen! ",s);
         printf("\nDer summierte quadrierte Fehler lautet immer noch: %f ",err);
         printf("\n\nAbbruch des Lernalgorithmus !!!\n");
         }
      }
      while ((err>=epsilon)&&(s!=s_max));
    }

void ausfuehren(void)
    {
    int i,j,p;
    float H;
    lese_x_test();
    for (j=1;j<=m;j++)
        {
        y_test[j]=0.0;
        for (p=1;p<=q;p++)
            {
            H=0.0;
            for (i=1;i<=n;i++) {H=H+(w[i][p]*x_test[i]);}
            y_test[j]=y_test[j]+g[p][j]*T(H-theta[p]);
            }
        }
    printf("\n");
    for (j=1;j<=m;j++) {printf("y[%1d] = %8.4f\n",j,y_test[j]);}
    }

void veraendern(void)
    {
    int i,j,p;
    s=0;
    printf("\n");
    printf("\nAnzahl n der Neuronen in der Eingabeschicht lautet %2d . ",n);
    printf("\nAnzahl m der Neuronen in der Ausgabeschicht lautet %2d . ",m);
    printf("\nAnzahl q der Neuronen in der verborgenen Schicht ? ");
    scanf("%d",&q);
    printf("Anzahl Pxy der x-y-Abtastpunkte (ergibt Pxy*Pxy Assoziationen) ? ");
    scanf("%d",&Pxy);
    t=Pxy*Pxy;
    printf("Stauchungsparameter beta der Transferfunktion ? ");
    scanf("%f",&beta);
    printf("Lernrate lambda mit der iteriert werden soll ? ");
    scanf("%f",&lambda);
    printf("Anzahl s_max der maximal zu durchlaufenden Lernzyklen ? ");
    scanf("%d",&s_max);
    printf("Zu unterschreitender maximaler Fehler epsilon ? ");
    scanf("%f",&epsilon);
    for (i=1;i<=n;i++) {x[i][0]=0.0;}
    for (j=1;j<=m;j++) {y[j][0]=0.0;}
    for (p=1;p<=q;p++)
        {
        for (i=1;i<=n;i++) {w[i][p]=0.0;}
        theta[p]=0.0;
        }
    for (j=1;j<=m;j++)
        {
        for (p=1;p<=q;p++) {g[p][j]=0.0;}
        }
    }

void zeigen(void)
    {
    int i,j,p;
    printf("\nDie Gewichte w[i][p] lauten nach %8d Lernzyklen: \n",s);
    for (p=1;p<=q;p++)
        {
        for (i=1;i<=n;i++)
            {
            printf("w[%1d][%1d]=%8.4f   ",i,p,w[i][p]);
            }
        printf("\n");
        }
    printf("\nDie Schwellwerte theta[p] lauten nach %8d Lernzyklen: \n",s);
    for (p=1;p<=q;p++)
        {
        printf("theta[%1d] = %8.4f\n",p,theta[p]);
        }
    printf("\nDie Gewichte g[p][j] lauten nach %8d Lernzyklen: \n",s);
    for (j=1;j<=m;j++)
        {
        for (p=1;p<=q;p++)
            {
            printf("g[%1d][%1d]=%8.4f\n",p,j,g[p][j]);
            }
        printf("\n");
        }
    }

void speichern(void)
    {
    int i,j,p;
    FILE *f;
    char dat[20];
    printf("\nWie lautet die Datei mit den Gewichten und Schwellwerten ? ");
    scanf("%s",&dat);
    f=fopen(dat,"w");
    fprintf(f,"%d\n",n);
    fprintf(f,"%d\n",q);
    fprintf(f,"%d\n",m);
    for (p=1;p<=q;p++)
        {
        for (i=1;i<=n;i++) {fprintf(f,"%f\n",w[i][p]);}
        }
    for (p=1;p<=q;p++) {fprintf(f,"%f\n",theta[p]);}
    for (j=1;j<=m;j++)
        {
        for (p=1;p<=q;p++) {fprintf(f,"%f\n",g[p][j]);}
        }
    fclose(f);
    }

void einlesen(void)
    {
    int i,j,p,r;
    FILE *f;
    char dat[20];
    s=0;
    printf("\nWie lautet die Datei mit den Gewichten und Schwellwerten ? ");
    scanf("%s",&dat);
    f=fopen(dat,"r");
    fscanf(f,"%d",&r);
    if (r==n)
       {
       fscanf(f,"%d",&r);
       if (r==q)
          {
          fscanf(f,"%d",&r);
          if (r==m)
             {
             for (p=1;p<=q;p++)
                 {
                 for (i=1;i<=n;i++) {fscanf(f,"%f",&w[i][p]);}
                 }
             for (p=1;p<=q;p++) {fscanf(f,"%f",&theta[p]);}
             for (j=1;j<=m;j++)
                 {
                 for (p=1;p<=q;p++) {fscanf(f,"%f",&g[p][j]);}
                 }
             }
             else
                {
                printf("\nFehler! m ist in Datei %2d statt %2d \n",r,m);
                }
             }
       else
          {
          printf("\nFehler! q ist in Datei %2d statt %2d \n",r,q);
          }
       }
    else
       {
       printf("\nFehler! n ist in Datei %2d statt %2d\n",r,n);
       }
    fclose(f);
    }

/*      Hauptprogramm                    */

int main(void)
    {
    veraendern();
    do
      {
      printf("\nlernen ausfuehren zeigen veraendern speichern einlesen beenden:\n");
      fflush(stdin);
      scanf("%c",&com);
      switch(com)
            {
            case 'l': lernen(); break;
            case 'a': ausfuehren(); break;
            case 'z': zeigen(); break;
            case 'v': veraendern(); break;
            case 's': speichern(); break;
            case 'e': einlesen(); break;
            default:  break;
            }
      }
    while (com!='b');
    return(0);
    }






Burkhard Lenze
Im Februar 2009