📄 fann.c
字号:
#endif case FANN_THRESHOLD: neuron_it->value = (fann_type)((neuron_value < 0) ? 0 : 1); break; case FANN_THRESHOLD_SYMMETRIC: neuron_it->value = (fann_type)((neuron_value < 0) ? -1 : 1); break; default: fann_error((struct fann_error *)ann, FANN_E_CANT_USE_ACTIVATION); } } } /* set the output */ output = ann->output; num_output = ann->num_output; neurons = (ann->last_layer-1)->first_neuron; for(i = 0; i != num_output; i++){ output[i] = neurons[i].value; } return ann->output;}/* deallocate the network. */FANN_EXTERNAL void FANN_API fann_destroy(struct fann *ann){ if(ann == NULL) return; fann_safe_free(fann_get_weights(ann)); fann_safe_free(fann_get_connections(ann)); fann_safe_free(ann->first_layer->first_neuron); fann_safe_free(ann->first_layer); fann_safe_free(ann->output); fann_safe_free(ann->train_errors); fann_safe_free(ann->train_slopes); fann_safe_free(ann->prev_train_slopes); fann_safe_free(ann->prev_steps); fann_safe_free(ann->errstr); fann_safe_free(ann);}FANN_EXTERNAL void FANN_API fann_randomize_weights(struct fann *ann, fann_type min_weight, fann_type max_weight){ fann_type *last_weight; fann_type *weights = (ann->first_layer+1)->first_neuron->weights; last_weight = weights + ann->total_connections; for(;weights != last_weight; weights++){ *weights = (fann_type)(fann_rand(min_weight, max_weight)); }}FANN_EXTERNAL void FANN_API fann_print_connections(struct fann *ann){ struct fann_layer *layer_it; struct fann_neuron *neuron_it; unsigned int i, value; char *neurons; unsigned int num_neurons = fann_get_total_neurons(ann) - fann_get_num_output(ann); neurons = (char *)malloc(num_neurons+1); neurons[num_neurons] = 0; printf("Layer / Neuron "); for(i = 0; i < num_neurons; i++){ printf("%d", i%10); } printf("\n"); for(layer_it = ann->first_layer+1; layer_it != ann->last_layer; layer_it++){ for(neuron_it = layer_it->first_neuron; neuron_it != layer_it->last_neuron-1; neuron_it++){ memset(neurons, (int)'.', num_neurons); for(i = 0; i < neuron_it->num_connections; i++){ value = (unsigned int)(fann_abs(neuron_it->weights[i])+0.5); if(value > 25) value = 25; neurons[neuron_it->connected_neurons[i] - ann->first_layer->first_neuron] = 'a' + value; } printf("L %3d / N %4d %s\n", layer_it - ann->first_layer, neuron_it - ann->first_layer->first_neuron, neurons); } } free(neurons);}/* Initialize the weights using Widrow + Nguyen's algorithm.*/FANN_EXTERNAL void FANN_API fann_init_weights(struct fann *ann, struct fann_train_data *train_data){ fann_type smallest_inp, largest_inp; unsigned int dat = 0, elem, num_neurons_in, num_neurons_out, num_connect, num_hidden_neurons; struct fann_layer *layer_it; struct fann_neuron *neuron_it, *last_neuron, *bias_neuron;#ifdef FIXEDFANN unsigned int multiplier = ann->multiplier;#endif float scale_factor; for ( smallest_inp = largest_inp = train_data->input[0][0] ; dat < train_data->num_data ; dat++ ) { for ( elem = 0 ; elem < train_data->num_input ; elem++ ) { if ( train_data->input[dat][elem] < smallest_inp ) smallest_inp = train_data->input[dat][elem]; if ( train_data->input[dat][elem] > largest_inp ) largest_inp = train_data->input[dat][elem]; } } num_hidden_neurons = ann->total_neurons - (ann->num_input + ann->num_output + (ann->last_layer - ann->first_layer)); scale_factor = (float)(pow((double)(0.7f * (double)num_hidden_neurons), (double)(1.0f / (double)ann->num_input)) / (double)(largest_inp - smallest_inp));#ifdef DEBUG printf("Initializing weights with scale factor %f\n", scale_factor);#endif for ( layer_it = ann->first_layer+1; layer_it != ann->last_layer ; layer_it++) {#ifdef DEBUG printf(" Layer: %x/%x (%d neurons)\n", layer_it-ann->first_layer, ann->last_layer-ann->first_layer, layer_it->last_neuron - layer_it->first_neuron);#endif num_neurons_out = layer_it->last_neuron - layer_it->first_neuron - 1; num_neurons_in = (layer_it-1)->last_neuron - (layer_it-1)->first_neuron - 1; last_neuron = layer_it->last_neuron-1; bias_neuron = (layer_it-1)->last_neuron-1; for(neuron_it = layer_it->first_neuron; neuron_it != last_neuron; neuron_it++) {#ifdef DEBUG printf(" Neuron %x/%x (%d connections)\n", neuron_it-layer_it->first_neuron, last_neuron-layer_it->first_neuron, neuron_it->num_connections);#endif for ( num_connect = 0 ; num_connect < neuron_it->num_connections ; num_connect++ ) {#ifdef DEBUG printf(" Connection %d/%d (%x)\n", num_connect, neuron_it->num_connections, neuron_it->connected_neurons[num_connect] - ann->first_layer->first_neuron);#endif if ( bias_neuron == neuron_it->connected_neurons[num_connect] ) {#ifdef FIXEDFANN neuron_it->weights[num_connect] = (fann_type)fann_rand(-scale_factor, scale_factor * multiplier);#else neuron_it->weights[num_connect] = (fann_type)fann_rand(-scale_factor, scale_factor);#endif } else {#ifdef FIXEDFANN neuron_it->weights[num_connect] = (fann_type)fann_rand(0, scale_factor * multiplier);#else neuron_it->weights[num_connect] = (fann_type)fann_rand(0, scale_factor);#endif } } } }}/* INTERNAL FUNCTION Allocates the main structure and sets some default values. */struct fann * fann_allocate_structure(float learning_rate, unsigned int num_layers){ struct fann *ann; if(num_layers < 2){#ifdef DEBUG printf("less than 2 layers - ABORTING.\n");#endif return NULL; } /* allocate and initialize the main network structure */ ann = (struct fann *)malloc(sizeof(struct fann)); if(ann == NULL){ fann_error(NULL, FANN_E_CANT_ALLOCATE_MEM); return NULL; } ann->errno_f = 0; ann->error_log = NULL; ann->errstr = NULL; ann->learning_rate = learning_rate; ann->total_neurons = 0; ann->total_connections = 0; ann->num_input = 0; ann->num_output = 0; ann->train_errors = NULL; ann->train_slopes = NULL; ann->prev_steps = NULL; ann->prev_train_slopes = NULL; ann->training_algorithm = FANN_TRAIN_RPROP; ann->num_MSE = 0; ann->MSE_value = 0; ann->shortcut_connections = 0; ann->train_error_function = FANN_ERRORFUNC_TANH; /* variables used for cascade correlation (reasonable defaults) */ /*ann->change_fraction = 0.01; ann->stagnation_epochs = 12;*/ /* Variables for use with with Quickprop training (reasonable defaults) */ ann->quickprop_decay = (float)-0.0001; ann->quickprop_mu = 1.75; /* Variables for use with with RPROP training (reasonable defaults) */ ann->rprop_increase_factor = (float)1.2; ann->rprop_decrease_factor = 0.5; ann->rprop_delta_min = 0.0; ann->rprop_delta_max = 50.0; fann_init_error_data((struct fann_error *)ann);#ifdef FIXEDFANN /* these values are only boring defaults, and should really never be used, since the real values are always loaded from a file. */ ann->decimal_point = 8; ann->multiplier = 256;#endif ann->activation_function_hidden = FANN_SIGMOID_STEPWISE; ann->activation_function_output = FANN_SIGMOID_STEPWISE;#ifdef FIXEDFANN ann->activation_steepness_hidden = ann->multiplier/2; ann->activation_steepness_output = ann->multiplier/2;#else ann->activation_steepness_hidden = 0.5; ann->activation_steepness_output = 0.5;#endif /* allocate room for the layers */ ann->first_layer = (struct fann_layer *)calloc(num_layers, sizeof(struct fann_layer)); if(ann->first_layer == NULL){ fann_error(NULL, FANN_E_CANT_ALLOCATE_MEM); free(ann); return NULL; } ann->last_layer = ann->first_layer + num_layers; return ann;}/* INTERNAL FUNCTION Allocates room for the neurons. */void fann_allocate_neurons(struct fann *ann){ struct fann_layer *layer_it; struct fann_neuron *neurons; unsigned int num_neurons_so_far = 0; unsigned int num_neurons = 0; /* all the neurons is allocated in one long array */ neurons = (struct fann_neuron *)calloc(ann->total_neurons, sizeof(struct fann_neuron)); if(neurons == NULL){ fann_error((struct fann_error *)ann, FANN_E_CANT_ALLOCATE_MEM); return; } /* clear data, primarily to make the input neurons cleared */ memset(neurons, 0, ann->total_neurons * sizeof(struct fann_neuron)); for(layer_it = ann->first_layer; layer_it != ann->last_layer; layer_it++){ num_neurons = layer_it->last_neuron - layer_it->first_neuron; layer_it->first_neuron = neurons+num_neurons_so_far; layer_it->last_neuron = layer_it->first_neuron+num_neurons; num_neurons_so_far += num_neurons; } ann->output = (fann_type *)calloc(num_neurons, sizeof(fann_type)); if(ann->output == NULL){ fann_error((struct fann_error *)ann, FANN_E_CANT_ALLOCATE_MEM); return; }}/* INTERNAL FUNCTION Allocate room for the connections. */void fann_allocate_connections(struct fann *ann){ struct fann_layer *layer_it, *last_layer; struct fann_neuron *neuron_it, *last_neuron; fann_type *weights; struct fann_neuron **connected_neurons = NULL; unsigned int connections_so_far = 0; weights = (fann_type *)calloc(ann->total_connections, sizeof(fann_type)); if(weights == NULL){ fann_error((struct fann_error *)ann, FANN_E_CANT_ALLOCATE_MEM); return; } /* TODO make special cases for all places where the connections is used, so that it is not needed for fully connected networks. */ connected_neurons = (struct fann_neuron **) calloc(ann->total_connections, sizeof(struct fann_neuron*)); if(connected_neurons == NULL){ fann_error((struct fann_error *)ann, FANN_E_CANT_ALLOCATE_MEM); return; } last_layer = ann->last_layer; for(layer_it = ann->first_layer+1; layer_it != ann->last_layer; layer_it++){ last_neuron = layer_it->last_neuron-1; for(neuron_it = layer_it->first_neuron; neuron_it != last_neuron; neuron_it++){ neuron_it->weights = weights+connections_so_far; neuron_it->connected_neurons = connected_neurons+connections_so_far; connections_so_far += neuron_it->num_connections; } } if(connections_so_far != ann->total_connections){ fann_error((struct fann_error *)ann, FANN_E_WRONG_NUM_CONNECTIONS, connections_so_far, ann->total_connections); return; }}/* INTERNAL FUNCTION Seed the random function. */void fann_seed_rand(){ FILE *fp = fopen("/dev/urandom", "r"); unsigned int foo; struct timeval t; if(!fp){ gettimeofday(&t, NULL); foo = t.tv_usec;#ifdef DEBUG printf("unable to open /dev/urandom\n");#endif }else{ fread(&foo, sizeof(foo), 1, fp); fclose(fp); } srand(foo);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -