/****************************************************************************/ /* /* File: "rtrl_pc.c" /* Real-Time Recurrent Learning for an RMLP (PC version) /* /* Authors: Scott A. Morrison, scott@cnel.ufl.edu /* Deniz Erdogmus, deniz@cnel.ufl.edu /* Justin Sanchez, justin@cnel.ufl.edu /* Dongho Han, dhan@cnel.ufl.edu /* /* Computational NeuroEngineering Laboratory /* Department of Electrical and Computer Engineering /* The University of Florida /* Gainesville, FL, 32611, USA /* /* Created: 26 November 2002 /* /*****************************************************************************/ #define FILE_NAME_MAX 40 #define MAX_LABEL_LENGTH 40 /* the following will generate a random number between -0.8 and +0.8 */ #define RANDOM_NUMBER (rand()%2 ? 1 : -1)/(0.1f*(rand()%500) + 1) #include #include #include #include #include /*********************** Parameters from "params.txt" ***********************/ char PARAM_FILE[FILE_NAME_MAX] = ""; char INPUT_FILE[FILE_NAME_MAX] = ""; char DESIRED_FILE[FILE_NAME_MAX] = ""; int TRAINING_START = 0; int TRAINING_END = 0; int TESTING_START = 0; int TESTING_END = 0; int TRAJ_LENGTH = 0; int TRAJ_PER_UPDATE = 0; int EPOCHS = 0; int N0 = 0; int N1 = 0; int N2 = 0; float SLOPE = 0.0f; float DERIVATIVE_OFFSET = 0.0f; float ETA1 = 0.0f; float ETA2 = 0.0f; float ETAF = 0.0f; int ADAPTIVE_STEP_SIZE = 0; float ETA_MIN = 0.0f; float ETA_MAX = 0.0f; float ETA_INCREASE = 0.0f; float MOMENTUM = 0.0f; int USE_INITS = 0; char W1_INIT_FILE[FILE_NAME_MAX*40] = ""; char B1_INIT_FILE[FILE_NAME_MAX*40] = ""; char W2_INIT_FILE[FILE_NAME_MAX] = ""; char B2_INIT_FILE[FILE_NAME_MAX] = ""; char WF_INIT_FILE[FILE_NAME_MAX] = ""; char WEIGHT_OUT_FILE[FILE_NAME_MAX] = ""; int TRAINING_LENGTH = 0; int UPDATES_PER_EPOCH = 0; /*************************** Temporary Variables ***************************/ int epoch = 0; float d_power = 0.0f; /* power of the desired signal, for normalized MSE */ float e_power = 0.0f; /* power of the error signal, for normalized MSE */ float *W1,*b1,*W2,*b2,*Wf; /* pointers to network weights */ float *G_W1,*G_b1,*G_W2,*G_b2,*G_Wf; /* pointers to gradients */ float *U_W1,*U_b1,*U_W2,*U_b2,*U_Wf; /* pointers to weight updates */ float *c,*g,*h; /* pointers to update parameters */ float *y1p,*z1,*Y1,*y2,*e,*a,*temp; /* pointers to network feedforward */ float *input,*desired; /* pointers to data */ float *x_ptr = NULL; float *d_ptr = NULL; float MSE = 0.0f; float MSEp = 0.0f; /*************************** Function Prototypes ***************************/ void displayMSE(); void updateGradient(); void doTraining(); void getParameters(); void showParameters(); void getWeights(); void putWeights(); float randomNumber(void); /***************************** Main program **********************************/ int main(int argc, char **argv) { int i = 0; int j = 0; int lines = 0; FILE * infile; FILE * desfile; /* check for the proper command line arguments */ if (argc != 2) { printf("\n*ERROR* Please specify only the parameter file name.\n"); printf("Usage: bptt params.txt\n"); printf("Exiting with nothing done.\n"); exit(EXIT_FAILURE); } else { strcpy(PARAM_FILE,argv[1]); } /* get the parameters from the parameter file */ getParameters(); TRAINING_LENGTH = TRAINING_END - TRAINING_START; UPDATES_PER_EPOCH = floor(TRAINING_LENGTH / (TRAJ_LENGTH * TRAJ_PER_UPDATE)); /* display title and parameters to screen */ printf("\n**********************************************************************\n"); printf("Training a Recurrent Neural Network using Backpropagation Through Time\n"); showParameters(); /* display the parameters */ printf("**********************************************************************\n"); /* allocate the memory */ W1 = calloc(N1*N0,sizeof(float)); /* first layer weights */ b1 = calloc(N1*1,sizeof(float)); /* first layer bias */ W2 = calloc(N2*N1,sizeof(float)); /* second layer weights */ b2 = calloc(N2*1,sizeof(float)); /* second layer bias */ Wf = calloc(N1*N1,sizeof(float)); /* feedback weights */ G_W1 = calloc(N1*N0,sizeof(float)); /* gradient updates for above */ G_b1 = calloc(N1*1,sizeof(float)); G_W2 = calloc(N2*N1,sizeof(float)); G_b2 = calloc(N2*1,sizeof(float)); G_Wf = calloc(N1*N1,sizeof(float)); U_W1 = calloc(N1*N0,sizeof(float)); /* weight updates for above */ U_b1 = calloc(N1*1,sizeof(float)); U_W2 = calloc(N2*N1,sizeof(float)); U_b2 = calloc(N2*1,sizeof(float)); U_Wf = calloc(N1*N1,sizeof(float)); c = calloc(N1*N1,sizeof(float)); /* intermediate update parameters */ g = calloc(N1*N1*N0,sizeof(float)); h = calloc(N1*N1*N1,sizeof(float)); y1p = calloc(N1*1,sizeof(float)); /* previous Y1 */ z1 = calloc(N1*1,sizeof(float)); /* input to hidden layer */ Y1 = calloc(N1*1,sizeof(float)); /* output of hidden layer */ y2 = calloc(N2*1,sizeof(float)); /* network output */ e = calloc(N2*1,sizeof(float)); /* network error */ a = calloc(N1*1,sizeof(float)); /* save sech(z1)^2 */ temp = calloc(N1*1,sizeof(float)); input = calloc(TRAINING_LENGTH*N0,sizeof(float)); /* input data */ desired = calloc(TRAINING_LENGTH*N2,sizeof(float)); /* desired data */ x_ptr = input; /* initialize the pointer to the input data */ d_ptr = desired; /* initialize the pointer to the desired data */ ETA1 = ETA1 / TRAJ_LENGTH; /* adjust the step size according to the trajectory length */ ETA2 = ETA2 / TRAJ_LENGTH; ETAF = ETAF / TRAJ_LENGTH; printf("Opening the input file...\n"); /* open the input file */ infile = fopen(INPUT_FILE,"r"); if (infile == NULL) { printf("\n*ERROR* The input file \"%s\" could not be opened for reading.\n",INPUT_FILE); printf("Exiting with nothing done.\n"); exit(EXIT_FAILURE); } /* read from the input file */ lines = 0; while( fscanf( infile,"%f",&input[lines]) != EOF) { lines++; if (lines >= TRAINING_LENGTH*N0) break; } printf("There were %d values read from the input file \"%s\".\n",lines,INPUT_FILE); /* close the input file */ if (fclose(infile) != 0) { printf("\n*ERROR* The input file \"%s\" could not be closed properly.\n",INPUT_FILE); printf("Exiting with nothing done.\n"); exit(EXIT_FAILURE); } printf("Opening the desired file...\n"); /* open the desired file */ desfile = fopen(DESIRED_FILE,"r"); if (infile == NULL) { printf("\n*ERROR* The desired file \"%s\" could not be opened for reading.\n",DESIRED_FILE); printf("Exiting with nothing done.\n"); exit(EXIT_FAILURE); } /* read from the desired file */ lines = 0; while(fscanf( desfile,"%f",&desired[lines]) != EOF) { lines++; if (lines >= TRAINING_LENGTH*N2) break; } printf("There were %d values read from the desired file \"%s\".\n",lines,DESIRED_FILE); /* close the desired file */ if (fclose(desfile) != 0) { printf("\n*ERROR* The desired file \"%s\" could not be closed properly.\n",DESIRED_FILE); printf("Exiting with nothing done.\n"); exit(EXIT_FAILURE); } /* initialize weights */ if (USE_INITS == 0) { printf("\nInitializing weights to small random numbers...\n"); /* initialize to random numbers */ for (i=0;i