📄 backprop.c
字号:
epoch_error = 0.0; epoch_error_num = 0; for (p=0; p<n_pat; p++) { for (i=0;i<NN_n_inp;i++) inp[i] = train_in[p][i]; /* set input vector */ forward_pass(); for (o=0;o<NN_n_out;o++) target[o] = train_out[p][o]; /* set target vector */ backward_pass(); } update_weights ();/*my_error("1epoch");*/}#endif /* Need actfn for forward_pass which is needed for use*//* applies an activation function of type g to a value */float actfn(enum actfntype g, float value){ if (g==line) return value; if (g==sigm) return 1.0 / (1.0+exp(-value)); if (g==gauss) return exp(-sqr(value));}/* computes the deriv. of an act.fn. g at a value, possibly using g(value) */float actfnprime(enum actfntype g,float value,float g_value){ if (g==line) return 1.0; if (g==sigm) return g_value*(1.0-g_value) + .1; /* .1 is Fahlman's suggestion *//* if (g==sigm) return g_value*(1.0-g_value);*/ if (g==gauss) return -2.0*value*g_value;}/* assume the inp[] array has already been set with the desired input */void forward_pass (){ int i,h,o; /* propagate inputs to hidden layer */ for (h=0; h<NN_n_hid; h++) { hid0[h]=0.0; for (i=0; i<NN_n_inp+1; i++) { hid0[h] += inp[i] * w1[i][h]; } hid[h] = actfn(h_actfn, hid0[h]); } /* propagate hidden layer to outputs */ for (o=0; o<NN_n_out; o++) { out0[o]=0.0; for (h=0; h<NN_n_hid+1; h++) { out0[o] += hid[h] * w2[h][o]; } out[o] = actfn(o_actfn, out0[o]); }/* my_error("forward");*/}#ifndef FOR_USE /* assume the inp[] array has been set, forward_pass() has already been called to propagate forward those inputs, and the target[] array is also set. */void backward_pass (){ float error,delta; int i,h,o; /* compute error at outputs */ for (o=0; o<NN_n_out; o++) { error = target[o]-out[o]; epoch_error += sqr(error); if ( fabs(error) > .4 ) epoch_error_num++; dout[o] = error * actfnprime(o_actfn,out0[o],out[o]); } /* backpropagate error signal to the hidden layer */ for (h=0; h<NN_n_hid; h++) { delta=0.0; for (o=0; o<NN_n_out; o++) { delta += dout[o] * w2[h][o]; } dhid[h] = delta * actfnprime(h_actfn,hid0[h],hid[h]); } /* Now that we've got an error signal for each unit in the network, we can determine the weight changes & accumulate them in dw1 and dw2. */ for (o=0; o<NN_n_out; o++) { for (h=0; h<NN_n_hid+1; h++) { dw2[h][o] += eta2 * dout[o] * hid[h]; } } for (h=0; h<NN_n_hid; h++) { for (i=0; i<NN_n_inp+1; i++) { dw1[i][h] += eta1 * dhid[h] * inp[i]; } }/* my_error("backward");*/}/* update the w1 and w2 weights using the accumulated changes in dw1 and dw2 as well as a momentum term involving the last epoch's total weight change.*/void update_weights(){ int i,h,o; for (i=0; i<NN_n_inp+1; i++) { for (h=0; h<NN_n_hid; h++) { w1[i][h] += ( prev_dw1[i][h] = dw1[i][h] + alpha*prev_dw1[i][h] ); w1[i][h] *= beta; } } for (h=0; h<NN_n_hid+1; h++) { for (o=0; o<NN_n_out; o++) { w2[h][o] += ( prev_dw2[h][o] = dw2[h][o] + alpha*prev_dw2[h][o] ); w2[h][o] *= beta; } }}/* Write the weights to a file */void write_weights(char *source){ FILE *weightFile; int i,j; weightFile = fopen(source,"w"); if ( !weightFile ) my_error("couldn't open weightFile");/* The weights */ fprintf(weightFile,"{"); for (i=0; i<NN_n_inp+1; i++){ fprintf(weightFile,"{"); for (j=0; j<NN_n_hid; j++) fprintf(weightFile,"%f ",w1[i][j]); fprintf(weightFile,"} "); } fprintf(weightFile,"}\n"); fprintf(weightFile,"{"); for (i=0; i<NN_n_hid+1; i++){ fprintf(weightFile,"{"); for (j=0; j<NN_n_out; j++) fprintf(weightFile,"%f ",w2[i][j]); fprintf(weightFile,"} "); } fprintf(weightFile,"}\n\n"); fprintf(weightFile,"Last changes in weights:\n"); fprintf(weightFile,"{"); for (i=0; i<NN_n_inp+1; i++){ fprintf(weightFile,"{"); for (j=0; j<NN_n_hid; j++) fprintf(weightFile,"%f ",dw1[i][j]); fprintf(weightFile,"} "); } fprintf(weightFile,"}\n"); fprintf(weightFile,"{"); for (i=0; i<NN_n_hid+1; i++){ fprintf(weightFile,"{"); for (j=0; j<NN_n_out; j++) fprintf(weightFile,"%f ",dw2[i][j]); fprintf(weightFile,"} "); } fprintf(weightFile,"}\n\n"); fprintf(weightFile,"The last forward pass, followed by target (epoch %d):\n", epoch_counter); for (i=0; i<NN_n_inp+1; i++) fprintf(weightFile,"%f ",inp[i]); fprintf(weightFile,"\n"); for (i=0; i<NN_n_hid; i++) fprintf(weightFile,"%f ",hid0[i]); fprintf(weightFile,"\n"); for (i=0; i<NN_n_hid+1; i++) fprintf(weightFile,"%f ",hid[i]); fprintf(weightFile,"\n"); for (i=0; i<NN_n_out; i++) fprintf(weightFile,"%f ",out0[i]); fprintf(weightFile,"\n"); for (i=0; i<NN_n_out; i++) fprintf(weightFile,"%f ",out[i]); fprintf(weightFile,"\n"); for (i=0; i<NN_n_out; i++) fprintf(weightFile,"%f ",target[i]); fprintf(weightFile,"\n\n"); fprintf(weightFile,"dhid and dout from last pass:\n"); for (i=0; i<NN_n_hid; i++) fprintf(weightFile,"%f ",dhid[i]); fprintf(weightFile,"\n"); for (i=0; i<NN_n_out; i++) fprintf(weightFile,"%f ",dout[i]); fprintf(weightFile,"\n\n"); fprintf(weightFile,"%d->%d->%d network:\n", NN_n_inp,NN_n_hid,NN_n_out); fprintf(weightFile,"\teta = (%f,%f), alpha = %f, beta = %f, randmax = %f\n", eta1,eta2,alpha,beta,randmax); fprintf(weightFile,"\t%d training patterns from %s\n", n_pat, TRAIN_FILE); if ( strcmp(INITIALIZE_FILE,"none") ) fprintf(weightFile,"Weights initialized from %s\n",INITIALIZE_FILE); fprintf(weightFile,"Epoch %d: tot err = %7.4f, avg err = %7.4f, num wrong = %d\n", epoch_counter, epoch_error, epoch_error/(n_pat*NN_n_out), epoch_error_num); fclose(weightFile);}#endif/* Load the weights from a file */void load_weights(char *source){ FILE *weightFile; int i,j; weightFile = fopen(source,"r"); if ( !weightFile ) my_error("couldn't open weightFile"); /* The weights */ fscanf(weightFile,"{"); for (i=0; i<NN_n_inp+1; i++){ fscanf(weightFile,"{"); for (j=0; j<NN_n_hid; j++) fscanf(weightFile,"%f ",&(w1[i][j])); fscanf(weightFile,"} "); } fscanf(weightFile,"}\n"); fscanf(weightFile,"{"); for (i=0; i<NN_n_hid+1; i++){ fscanf(weightFile,"{"); for (j=0; j<NN_n_out; j++) fscanf(weightFile,"%f ",&(w2[i][j])); fscanf(weightFile,"} "); } fscanf(weightFile,"}\n\n"); fclose(weightFile);/* my_error("load_weights");*/}#ifndef FOR_USE/* Load the weights from a file called */void initialize_from_file(char *source){ FILE *weightFile; int i,j; printf("Initializing %d->%d->%d network:\n", NN_n_inp,NN_n_hid,NN_n_out); printf("\teta = (%f,%f), alpha = %f\n", eta1,eta2,alpha); printf("\t%d training patterns\n", n_pat); printf("Initializing weights from %s\n", source); weightFile = fopen(source,"r"); if ( !weightFile ) my_error("couldn't open weightFile"); /* initialize bias units */ inp[NN_n_inp] = 1.0; hid[NN_n_hid] = 1.0; /* The weights */ fscanf(weightFile,"{"); for (i=0; i<NN_n_inp+1; i++){ fscanf(weightFile,"{"); for (j=0; j<NN_n_hid; j++) fscanf(weightFile,"%f ",&(w1[i][j])); fscanf(weightFile,"} "); } fscanf(weightFile,"}\n"); fscanf(weightFile,"{"); for (i=0; i<NN_n_hid+1; i++){ fscanf(weightFile,"{"); for (j=0; j<NN_n_out; j++) fscanf(weightFile,"%f ",&(w2[i][j])); fscanf(weightFile,"} "); } fscanf(weightFile,"}\n\n"); fscanf(weightFile,"Last changes in weights:\n"); fscanf(weightFile,"{"); for (i=0; i<NN_n_inp+1; i++){ fscanf(weightFile,"{"); for (j=0; j<NN_n_hid; j++) fscanf(weightFile,"%f ",&(dw1[i][j])); fscanf(weightFile,"} "); } fscanf(weightFile,"}\n"); fscanf(weightFile,"{"); for (i=0; i<NN_n_hid+1; i++){ fscanf(weightFile,"{"); for (j=0; j<NN_n_out; j++) fscanf(weightFile,"%f ",&(dw2[i][j])); fscanf(weightFile,"} "); } fscanf(weightFile,"}\n\n"); fclose(weightFile);}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -