book_t *book_create(size_t num_lessons, size_t num_input, size_t num_output) { fann_type *in, *out; size_t i = 0; struct fann_train_data *book = NULL; ALLOC(book, 1L, sizeof(struct fann_train_data)); fann_init_error_data((struct fann_error *) book); book->num_data = num_lessons; book->num_input = num_input; book->num_output = num_output; ALLOC(book->input, num_lessons, sizeof(fann_type *)); ALLOC(book->output, num_lessons, sizeof(fann_type *)); ALLOC(in, num_input * num_lessons, sizeof(fann_type)); ALLOC(out, num_output * num_lessons, sizeof(fann_type)); for(i = 0; i != num_lessons; i++) { book->input[i] = in; in += num_input; book->output[i] = out; out += num_output; } return (book_t *) book; }
/* * Creates an empty set of training data */ FANN_EXTERNAL struct fann_train_data * FANN_API fann_create_train(unsigned int num_data, unsigned int num_input, unsigned int num_output) { fann_type *data_input, *data_output; unsigned int i; struct fann_train_data *data = (struct fann_train_data *) malloc(sizeof(struct fann_train_data)); if(data == NULL) { fann_error(NULL, FANN_E_CANT_ALLOCATE_MEM); return NULL; } fann_init_error_data((struct fann_error *) data); data->num_data = num_data; data->num_input = num_input; data->num_output = num_output; data->input = (fann_type **) calloc(num_data, sizeof(fann_type *)); if(data->input == NULL) { fann_error(NULL, FANN_E_CANT_ALLOCATE_MEM); fann_destroy_train(data); return NULL; } data->output = (fann_type **) calloc(num_data, sizeof(fann_type *)); if(data->output == NULL) { fann_error(NULL, FANN_E_CANT_ALLOCATE_MEM); fann_destroy_train(data); return NULL; } data_input = (fann_type *) calloc(num_input * num_data, sizeof(fann_type)); if(data_input == NULL) { fann_error(NULL, FANN_E_CANT_ALLOCATE_MEM); fann_destroy_train(data); return NULL; } data_output = (fann_type *) calloc(num_output * num_data, sizeof(fann_type)); if(data_output == NULL) { fann_error(NULL, FANN_E_CANT_ALLOCATE_MEM); fann_destroy_train(data); return NULL; } for(i = 0; i != num_data; i++) { data->input[i] = data_input; data_input += num_input; data->output[i] = data_output; data_output += num_output; } return data; }
void initialize_ann_data(struct fann_train_data **ann_data, int num_data, int num_input, int num_output) { int i; *ann_data = (struct fann_train_data *) malloc(sizeof(struct fann_train_data)); fann_init_error_data((struct fann_error *) *ann_data); (*ann_data)->num_data = num_data; (*ann_data)->num_input = num_input; (*ann_data)->num_output = num_output; (*ann_data)->input = (fann_type **) calloc(num_data, sizeof(fann_type *)); (*ann_data)->output = (fann_type **) calloc(num_data, sizeof(fann_type *)); for (i = 0; i < num_data; i ++) { (*ann_data)->input[i] = (fann_type*) calloc(num_input, sizeof(fann_type)); (*ann_data)->output[i] = (fann_type*) calloc(num_output, sizeof(fann_type)); } }
FANN_EXTERNAL struct fann_train_data *FANN_API fann_subset_train_data(struct fann_train_data *data, unsigned int pos, unsigned int length) { unsigned int i; fann_type *data_input, *data_output; struct fann_train_data *dest = (struct fann_train_data *) malloc(sizeof(struct fann_train_data)); if(dest == NULL) { fann_error((struct fann_error*)data, FANN_E_CANT_ALLOCATE_MEM); return NULL; } if(pos > data->num_data || pos+length > data->num_data) { fann_error((struct fann_error*)data, FANN_E_TRAIN_DATA_SUBSET, pos, length, data->num_data); return NULL; } fann_init_error_data((struct fann_error *) dest); dest->error_log = data->error_log; dest->num_data = length; dest->num_input = data->num_input; dest->num_output = data->num_output; dest->input = (fann_type **) calloc(dest->num_data, sizeof(fann_type *)); if(dest->input == NULL) { fann_error((struct fann_error*)data, FANN_E_CANT_ALLOCATE_MEM); fann_destroy_train(dest); return NULL; } dest->output = (fann_type **) calloc(dest->num_data, sizeof(fann_type *)); if(dest->output == NULL) { fann_error((struct fann_error*)data, FANN_E_CANT_ALLOCATE_MEM); fann_destroy_train(dest); return NULL; } data_input = (fann_type *) calloc(dest->num_input * dest->num_data, sizeof(fann_type)); if(data_input == NULL) { fann_error((struct fann_error*)data, FANN_E_CANT_ALLOCATE_MEM); fann_destroy_train(dest); return NULL; } memcpy(data_input, data->input[pos], dest->num_input * dest->num_data * sizeof(fann_type)); data_output = (fann_type *) calloc(dest->num_output * dest->num_data, sizeof(fann_type)); if(data_output == NULL) { fann_error((struct fann_error*)data, FANN_E_CANT_ALLOCATE_MEM); fann_destroy_train(dest); return NULL; } memcpy(data_output, data->output[pos], dest->num_output * dest->num_data * sizeof(fann_type)); for(i = 0; i != dest->num_data; i++) { dest->input[i] = data_input; data_input += dest->num_input; dest->output[i] = data_output; data_output += dest->num_output; } return dest; }
/* * return a copy of a fann_train_data struct */ FANN_EXTERNAL struct fann_train_data *FANN_API fann_duplicate_train_data(struct fann_train_data *data) { unsigned int i; fann_type *data_input, *data_output; struct fann_train_data *dest = (struct fann_train_data *) malloc(sizeof(struct fann_train_data)); if(dest == NULL) { fann_error((struct fann_error*)data, FANN_E_CANT_ALLOCATE_MEM); return NULL; } fann_init_error_data((struct fann_error *) dest); dest->error_log = data->error_log; dest->num_data = data->num_data; dest->num_input = data->num_input; dest->num_output = data->num_output; dest->input = (fann_type **) calloc(dest->num_data, sizeof(fann_type *)); if(dest->input == NULL) { fann_error((struct fann_error*)data, FANN_E_CANT_ALLOCATE_MEM); fann_destroy_train(dest); return NULL; } dest->output = (fann_type **) calloc(dest->num_data, sizeof(fann_type *)); if(dest->output == NULL) { fann_error((struct fann_error*)data, FANN_E_CANT_ALLOCATE_MEM); fann_destroy_train(dest); return NULL; } data_input = (fann_type *) calloc(dest->num_input * dest->num_data, sizeof(fann_type)); if(data_input == NULL) { fann_error((struct fann_error*)data, FANN_E_CANT_ALLOCATE_MEM); fann_destroy_train(dest); return NULL; } memcpy(data_input, data->input[0], dest->num_input * dest->num_data * sizeof(fann_type)); data_output = (fann_type *) calloc(dest->num_output * dest->num_data, sizeof(fann_type)); if(data_output == NULL) { fann_error((struct fann_error*)data, FANN_E_CANT_ALLOCATE_MEM); fann_destroy_train(dest); return NULL; } memcpy(data_output, data->output[0], dest->num_output * dest->num_data * sizeof(fann_type)); for(i = 0; i != dest->num_data; i++) { dest->input[i] = data_input; data_input += dest->num_input; dest->output[i] = data_output; data_output += dest->num_output; } return dest; }
/* * merges training data into a single struct. */ FANN_EXTERNAL struct fann_train_data *FANN_API fann_merge_train_data(struct fann_train_data *data1, struct fann_train_data *data2) { unsigned int i; fann_type *data_input, *data_output; struct fann_train_data *dest = (struct fann_train_data *) malloc(sizeof(struct fann_train_data)); if(dest == NULL) { fann_error((struct fann_error*)data1, FANN_E_CANT_ALLOCATE_MEM); return NULL; } if((data1->num_input != data2->num_input) || (data1->num_output != data2->num_output)) { fann_error((struct fann_error*)data1, FANN_E_TRAIN_DATA_MISMATCH); return NULL; } fann_init_error_data((struct fann_error *) dest); dest->error_log = data1->error_log; dest->num_data = data1->num_data+data2->num_data; dest->num_input = data1->num_input; dest->num_output = data1->num_output; dest->input = (fann_type **) calloc(dest->num_data, sizeof(fann_type *)); if(dest->input == NULL) { fann_error((struct fann_error*)data1, FANN_E_CANT_ALLOCATE_MEM); fann_destroy_train(dest); return NULL; } dest->output = (fann_type **) calloc(dest->num_data, sizeof(fann_type *)); if(dest->output == NULL) { fann_error((struct fann_error*)data1, FANN_E_CANT_ALLOCATE_MEM); fann_destroy_train(dest); return NULL; } data_input = (fann_type *) calloc(dest->num_input * dest->num_data, sizeof(fann_type)); if(data_input == NULL) { fann_error((struct fann_error*)data1, FANN_E_CANT_ALLOCATE_MEM); fann_destroy_train(dest); return NULL; } memcpy(data_input, data1->input[0], dest->num_input * data1->num_data * sizeof(fann_type)); memcpy(data_input + (dest->num_input*data1->num_data), data2->input[0], dest->num_input * data2->num_data * sizeof(fann_type)); data_output = (fann_type *) calloc(dest->num_output * dest->num_data, sizeof(fann_type)); if(data_output == NULL) { fann_error((struct fann_error*)data1, FANN_E_CANT_ALLOCATE_MEM); fann_destroy_train(dest); return NULL; } memcpy(data_output, data1->output[0], dest->num_output * data1->num_data * sizeof(fann_type)); memcpy(data_output + (dest->num_output*data1->num_data), data2->output[0], dest->num_output * data2->num_data * sizeof(fann_type)); for(i = 0; i != dest->num_data; i++) { dest->input[i] = data_input; data_input += dest->num_input; dest->output[i] = data_output; data_output += dest->num_output; } return dest; }
//-------------------------------------------------------------------------------------------------------- // Function code adapted from: // http://leenissen.dk/fann/forum/viewtopic.php?p=719&sid=1661ac359e28908e704231faa6310518 // struct fann_train_data *read_from_array(const double *din, const double *dout, const unsigned int num_data, const unsigned int num_input, const unsigned int num_output) { unsigned int i, j; struct fann_train_data * data = (struct fann_train_data *)MALLOC(sizeof(struct fann_train_data)); if (data == NULL) { fann_error(NULL, FANN_E_CANT_ALLOCATE_MEM); return NULL; } fann_init_error_data((struct fann_error *) data); data->num_data = num_data; data->num_input = num_input; data->num_output = num_output; data->input = (fann_type **)MALLOC(num_data * sizeof(fann_type *)); if (data->input == NULL) { fann_error(NULL, FANN_E_CANT_ALLOCATE_MEM); fann_destroy_train(data); return NULL; } data->output = (fann_type **)MALLOC(num_data * sizeof(fann_type *)); if (data->output == NULL) { fann_error(NULL, FANN_E_CANT_ALLOCATE_MEM); fann_destroy_train(data); return NULL; } for(i=0; i<num_data; i++) { data->input[i] = (fann_type *)MALLOC(num_input*sizeof(fann_type)); if (data->input[i] == NULL) { fann_error(NULL, FANN_E_CANT_ALLOCATE_MEM); fann_destroy_train(data); return NULL; } data->output[i] = (fann_type *)MALLOC(num_output*sizeof(fann_type)); if (data->output[i] == NULL) { fann_error(NULL, FANN_E_CANT_ALLOCATE_MEM); fann_destroy_train(data); return NULL; } } //Code changed to support the way scilab passes arrays for(i=0; i<num_data; i++) { for(j=0; j<num_input; j++) { data->input[i][j] = din[(j*num_data)+i]; } for(j=0; j!=num_output; j++) { data->output[i][j] = dout[(j*num_data)+i]; } } return data; }
/* INTERNAL FUNCTION Allocates the main structure and sets some default values. */ struct fann *fann_allocate_structure(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 *) fann_malloc(sizeof(struct fann)); if(ann == NULL) { fann_error(NULL, FANN_E_CANT_ALLOCATE_MEM); return NULL; } ann->errno_f = FANN_E_NO_ERROR; ann->error_log = fann_default_error_log; ann->errstr = NULL; ann->learning_rate = 0.7f; ann->learning_momentum = 0.0; 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->prev_weights_deltas = NULL; ann->training_algorithm = FANN_TRAIN_RPROP; ann->num_MSE = 0; ann->MSE_value = 0; ann->num_bit_fail = 0; ann->bit_fail_limit = (fann_type)0.35; ann->train_error_function = FANN_ERRORFUNC_TANH; ann->train_stop_function = FANN_STOPFUNC_MSE; ann->callback = NULL; ann->user_data = NULL; /* User is responsible for deallocation */ ann->weights = NULL; ann->connections = NULL; ann->output = NULL; #ifndef FIXEDFANN ann->scale_mean_in = NULL; ann->scale_deviation_in = NULL; ann->scale_new_min_in = NULL; ann->scale_factor_in = NULL; ann->scale_mean_out = NULL; ann->scale_deviation_out = NULL; ann->scale_new_min_out = NULL; ann->scale_factor_out = NULL; #endif /* 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 = 1.2f; ann->rprop_decrease_factor = 0.5f; ann->rprop_delta_min = 0.0f; ann->rprop_delta_max = 50.0f; ann->rprop_delta_zero = 0.1f; ann->can_use_sse = false; ann->can_use_avx = false; fann_init_error_data((struct fann_error *) ann); /* allocate room for the layers */ ann->first_layer = (struct fann_layer *) fann_calloc(num_layers, sizeof(struct fann_layer)); if(ann->first_layer == NULL) { fann_error(NULL, FANN_E_CANT_ALLOCATE_MEM); fann_free(ann); return NULL; } ann->last_layer = ann->first_layer + num_layers; return ann; }
/* * Creates training data from a callback function. */ FANN_EXTERNAL struct fann_train_data * FANN_API fann_create_train_from_callback(unsigned int num_data, unsigned int num_input, unsigned int num_output, void (FANN_API *user_function)( unsigned int, unsigned int, unsigned int, fann_type * , fann_type * )) { unsigned int i; fann_type *data_input, *data_output; struct fann_train_data *data = (struct fann_train_data *) malloc(sizeof(struct fann_train_data)); if(data == NULL) { fann_error(NULL, FANN_E_CANT_ALLOCATE_MEM); return NULL; } fann_init_error_data((struct fann_error *) data); data->num_data = num_data; data->num_input = num_input; data->num_output = num_output; data->input = (fann_type **) calloc(num_data, sizeof(fann_type *)); if(data->input == NULL) { fann_error(NULL, FANN_E_CANT_ALLOCATE_MEM); fann_destroy_train(data); return NULL; } data->output = (fann_type **) calloc(num_data, sizeof(fann_type *)); if(data->output == NULL) { fann_error(NULL, FANN_E_CANT_ALLOCATE_MEM); fann_destroy_train(data); return NULL; } data_input = (fann_type *) calloc(num_input * num_data, sizeof(fann_type)); if(data_input == NULL) { fann_error(NULL, FANN_E_CANT_ALLOCATE_MEM); fann_destroy_train(data); return NULL; } data_output = (fann_type *) calloc(num_output * num_data, sizeof(fann_type)); if(data_output == NULL) { fann_error(NULL, FANN_E_CANT_ALLOCATE_MEM); fann_destroy_train(data); return NULL; } for( i = 0; i != num_data; i++) { data->input[i] = data_input; data_input += num_input; data->output[i] = data_output; data_output += num_output; (*user_function)(i, num_input, num_output, data->input[i],data->output[i] ); } return data; }
/* * INTERNAL FUNCTION Reads training data from a file descriptor. */ struct fann_train_data *fann_read_train_from_fd(FILE * file, const char *filename) { unsigned int num_input, num_output, num_data, i, j; unsigned int line = 1; fann_type *data_input, *data_output; struct fann_train_data *data = (struct fann_train_data *) malloc(sizeof(struct fann_train_data)); if(data == NULL) { fann_error(NULL, FANN_E_CANT_ALLOCATE_MEM); return NULL; } if(fscanf(file, "%u %u %u\n", &num_data, &num_input, &num_output) != 3) { fann_error(NULL, FANN_E_CANT_READ_TD, filename, line); fann_destroy_train(data); return NULL; } line++; fann_init_error_data((struct fann_error *) data); data->num_data = num_data; data->num_input = num_input; data->num_output = num_output; data->input = (fann_type **) calloc(num_data, sizeof(fann_type *)); if(data->input == NULL) { fann_error(NULL, FANN_E_CANT_ALLOCATE_MEM); fann_destroy_train(data); return NULL; } data->output = (fann_type **) calloc(num_data, sizeof(fann_type *)); if(data->output == NULL) { fann_error(NULL, FANN_E_CANT_ALLOCATE_MEM); fann_destroy_train(data); return NULL; } data_input = (fann_type *) calloc(num_input * num_data, sizeof(fann_type)); if(data_input == NULL) { fann_error(NULL, FANN_E_CANT_ALLOCATE_MEM); fann_destroy_train(data); return NULL; } data_output = (fann_type *) calloc(num_output * num_data, sizeof(fann_type)); if(data_output == NULL) { fann_error(NULL, FANN_E_CANT_ALLOCATE_MEM); fann_destroy_train(data); return NULL; } for(i = 0; i != num_data; i++) { data->input[i] = data_input; data_input += num_input; for(j = 0; j != num_input; j++) { if(fscanf(file, FANNSCANF " ", &data->input[i][j]) != 1) { fann_error(NULL, FANN_E_CANT_READ_TD, filename, line); fann_destroy_train(data); return NULL; } } line++; data->output[i] = data_output; data_output += num_output; for(j = 0; j != num_output; j++) { if(fscanf(file, FANNSCANF " ", &data->output[i][j]) != 1) { fann_error(NULL, FANN_E_CANT_READ_TD, filename, line); fann_destroy_train(data); return NULL; } } line++; } return data; }
/* INTERNAL FUNCTION Allocates the main structure and sets some default values. */ struct fann *fann_allocate_structure(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 = FANN_E_NO_ERROR; ann->error_log = fann_default_error_log; ann->errstr = NULL; ann->learning_rate = 0.7f; ann->learning_momentum = 0.0; 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->prev_weights_deltas = NULL; ann->training_algorithm = FANN_TRAIN_RPROP; ann->num_MSE = 0; ann->MSE_value = 0; ann->num_bit_fail = 0; ann->bit_fail_limit = (fann_type)0.35; ann->network_type = FANN_NETTYPE_LAYER; ann->train_error_function = FANN_ERRORFUNC_TANH; ann->train_stop_function = FANN_STOPFUNC_MSE; ann->callback = NULL; ann->user_data = NULL; /* User is responsible for deallocation */ ann->weights = NULL; ann->connections = NULL; ann->output = NULL; #ifndef FIXEDFANN ann->scale_mean_in = NULL; ann->scale_deviation_in = NULL; ann->scale_new_min_in = NULL; ann->scale_factor_in = NULL; ann->scale_mean_out = NULL; ann->scale_deviation_out = NULL; ann->scale_new_min_out = NULL; ann->scale_factor_out = NULL; #endif /* variables used for cascade correlation (reasonable defaults) */ ann->cascade_output_change_fraction = 0.01f; ann->cascade_candidate_change_fraction = 0.01f; ann->cascade_output_stagnation_epochs = 12; ann->cascade_candidate_stagnation_epochs = 12; ann->cascade_num_candidate_groups = 2; ann->cascade_weight_multiplier = (fann_type)0.4; ann->cascade_candidate_limit = (fann_type)1000.0; ann->cascade_max_out_epochs = 150; ann->cascade_max_cand_epochs = 150; ann->cascade_candidate_scores = NULL; ann->cascade_activation_functions_count = 10; ann->cascade_activation_functions = (enum fann_activationfunc_enum *)calloc(ann->cascade_activation_functions_count, sizeof(enum fann_activationfunc_enum)); if(ann->cascade_activation_functions == NULL) { fann_error(NULL, FANN_E_CANT_ALLOCATE_MEM); free(ann); return NULL; } ann->cascade_activation_functions[0] = FANN_SIGMOID; ann->cascade_activation_functions[1] = FANN_SIGMOID_SYMMETRIC; ann->cascade_activation_functions[2] = FANN_GAUSSIAN; ann->cascade_activation_functions[3] = FANN_GAUSSIAN_SYMMETRIC; ann->cascade_activation_functions[4] = FANN_ELLIOT; ann->cascade_activation_functions[5] = FANN_ELLIOT_SYMMETRIC; ann->cascade_activation_functions[6] = FANN_SIN_SYMMETRIC; ann->cascade_activation_functions[7] = FANN_COS_SYMMETRIC; ann->cascade_activation_functions[8] = FANN_SIN; ann->cascade_activation_functions[9] = FANN_COS; ann->cascade_activation_steepnesses_count = 4; ann->cascade_activation_steepnesses = (fann_type *)calloc(ann->cascade_activation_steepnesses_count, sizeof(fann_type)); if(ann->cascade_activation_steepnesses == NULL) { fann_safe_free(ann->cascade_activation_functions); fann_error(NULL, FANN_E_CANT_ALLOCATE_MEM); free(ann); return NULL; } ann->cascade_activation_steepnesses[0] = (fann_type)0.25; ann->cascade_activation_steepnesses[1] = (fann_type)0.5; ann->cascade_activation_steepnesses[2] = (fann_type)0.75; ann->cascade_activation_steepnesses[3] = (fann_type)1.0; /* 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; ann->rprop_delta_zero = 0.1f; 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 /* 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; }