/* A backpropagation simulator. * This is oversimplified version of 2 boolean inputs to 1 boolean output * by asakawa@twcu.ac.jp */ #include #include #include #include "general.h" #include "rand.h" #include "neuron_util.h" #define learning_rate 0.5 /* McCalloch and Pitts' formal neuron */ double formal_f(double state) { return (state > 0) ? 1.0 : 0.0; } /* Logistic function */ double logistic_f(double state) { return 1.0 / ( 1.0 + exp( - 1.7 * state )); } double Dlogistic_f(double state) { return ((state) * (1.0 - state)); } /* Hygerbolic function */ double hyperbolic_f(double state) { return 0.5 * ( tanh(state) + 1.0 ); } double Dhyperbolic_f(double state) { return (1.0 - (state) * (state)); } double liner_f(double state) { return state; } double Dliner_f(double state) { return 1.0; } /* Initilazing a neuron, which is described as a struct NEURON */ /* in neuron_util.h, and assigning an initial value as default */ /* to each variable */ void initialize_neuron(neuron *a, int N, double output_func(), double Doutput_func() ) { int i; a->output = 0.0; a->Ninp = N; a->output_func = output_func; a->Doutput_func = Doutput_func; if ( a->Ninp == 0 ) { a->inp_wgt = NULL; a->inp_neuron = NULL; return; } a->inp_wgt = (double *)malloc(sizeof(double) * (a->Ninp)); if ( a->inp_wgt == NULL){ fprintf(stderr, "Can not allocate memory\n"); exit (EXIT_FAILURE); } for (i=0; i< a->Ninp; i++) { a->inp_wgt[i] = drand2(); } a->inp_neuron = (neuron **)malloc(sizeof(neuron *) * (a->Ninp)); if ( a->inp_neuron == NULL ) { fprintf(stderr, "Can not allocate memory\n"); exit (EXIT_FAILURE); } for (i=0; i < a->Ninp; i++) { a->inp_neuron[i] = NULL; } } void copy_neuron(neuron *a, neuron *b) { int i; b->output = a->output; b->Ninp = a->Ninp; for (i=0; i< a->Ninp; i++) { b->inp_wgt[i] = a->inp_wgt[i]; if ( a->inp_neuron[i] != NULL && b->inp_neuron[i] != NULL ){ b->inp_neuron[i] = a->inp_neuron[i]; } } } void calc_neuron (neuron *a) { double wrk = 0.0; int i; for(i=0; i< a->Ninp; i++){ wrk += a->inp_wgt[i] * a->inp_neuron[i]->output; } a->output = a->output_func(wrk); } /* This is a generalized delta rule proposed by Mclleland and Rumelhart */ void update_wgt(neuron *a, double error) { int i; double g_delta; g_delta = error * a->Doutput_func(a->output); for (i=0; iNinp; i++) { a->inp_wgt[i] += - learning_rate * g_delta * a->inp_neuron[i]->output; } }