void GazeTracker::trainNN() { std::cout << "Getting data" << std::endl; struct fann_train_data *data = fann_create_train_from_callback(_inputCount, _nnEyeWidth * _nnEyeHeight, 2, getTrainingData); //fann_save_train(data, "data.txt"); std::cout << "Getting left data" << std::endl; struct fann_train_data *dataLeft = fann_create_train_from_callback(_inputCount, _nnEyeWidth * _nnEyeHeight, 2, getTrainingDataLeft); //fann_save_train(dataLeft, "dataLeft.txt"); fann_set_training_algorithm(_ANN, FANN_TRAIN_RPROP); fann_set_learning_rate(_ANN, 0.75); fann_set_training_algorithm(_ANNLeft, FANN_TRAIN_RPROP); fann_set_learning_rate(_ANNLeft, 0.75); std::cout << "Training" << std::endl; fann_train_on_data(_ANN, data, 200, 20, 0.01); std::cout << "Training left" << std::endl; fann_train_on_data(_ANNLeft, dataLeft, 200, 20, 0.01); double mse = fann_get_MSE(_ANN); double mseLeft = fann_get_MSE(_ANNLeft); std::cout << "MSE: " << mse << ", MSE left: " << mseLeft << std::endl; }
void GazeTracker::trainNN() { cout << "Getting data" << endl; struct fann_train_data* data = fann_create_train_from_callback(input_count, nn_eyewidth * nn_eyeheight, 2, getTrainingData); //fann_save_train(data, "data.txt"); cout << "Getting left data" << endl; struct fann_train_data* data_left = fann_create_train_from_callback(input_count, nn_eyewidth * nn_eyeheight, 2, getTrainingData_left); //fann_save_train(data_left, "data_left.txt"); fann_set_training_algorithm(ANN, FANN_TRAIN_RPROP); fann_set_learning_rate(ANN, 0.75); fann_set_training_algorithm(ANN_left, FANN_TRAIN_RPROP); fann_set_learning_rate(ANN_left, 0.75); cout << "Training" << endl; fann_train_on_data(ANN, data, 200, 20, 0.01); cout << "Training left" << endl; fann_train_on_data(ANN_left, data_left, 200, 20, 0.01); double mse = fann_get_MSE(ANN); double mse_left = fann_get_MSE(ANN_left); cout << "MSE: " << mse << ", MSE left: " << mse_left << endl; }
/* * Internal train function */ float fann_train_epoch_sarprop(struct fann *ann, struct fann_train_data *data) { unsigned int i; if(ann->prev_train_slopes == NULL) { fann_clear_train_arrays(ann); } fann_reset_MSE(ann); for(i = 0; i < data->num_data; i++) { fann_run(ann, data->input[i]); fann_compute_MSE(ann, data->output[i]); fann_backpropagate_MSE(ann); fann_update_slopes_batch(ann, ann->first_layer + 1, ann->last_layer - 1); } fann_update_weights_sarprop(ann, ann->sarprop_epoch, 0, ann->total_connections); ++(ann->sarprop_epoch); return fann_get_MSE(ann); }
int FANN_API test_callback(struct fann *ann, struct fann_train_data *train, unsigned int max_epochs, unsigned int epochs_between_reports, float desired_error, unsigned int epochs) { printf("Epochs %8d. MSE: %.5f. Desired-MSE: %.5f\n", epochs, fann_get_MSE(ann), desired_error); return 0; }
static void * lua_fann_train_thread (void *ud) { struct lua_fann_train_cbdata *cbdata = ud; struct lua_fann_train_reply rep; gchar repbuf[1]; msg_info ("start learning ANN, %d epochs are possible", cbdata->max_epochs); rspamd_socket_blocking (cbdata->pair[1]); fann_train_on_data (cbdata->f, cbdata->train, cbdata->max_epochs, 0, cbdata->desired_mse); rep.errcode = 0; rspamd_strlcpy (rep.errmsg, "OK", sizeof (rep.errmsg)); rep.mse = fann_get_MSE (cbdata->f); if (write (cbdata->pair[1], &rep, sizeof (rep)) == -1) { msg_err ("cannot write to socketpair: %s", strerror (errno)); return NULL; } if (read (cbdata->pair[1], repbuf, sizeof (repbuf)) == -1) { msg_err ("cannot read from socketpair: %s", strerror (errno)); return NULL; } return NULL; }
NeuralNet *nn_fann_Fann2NeuralNet(struct fann *ANN ) { unsigned int ANN_NLayers = fann_get_num_layers(ANN), *BiasArray = (unsigned int* ) pgm_malloc (sizeof(unsigned int)*ANN_NLayers), *ANN_NNeurons = (unsigned int* ) pgm_malloc (sizeof(unsigned int)*ANN_NLayers); double *ANN_Weights; NeuralNet *NN; fann_get_bias_array(ANN,BiasArray); fann_get_layer_array(ANN,ANN_NNeurons); ANN_Weights = nn_fann_parse_get_weights(ANN,ANN_NLayers,ANN_NNeurons); NN = nn_NeuralNetCreate( ANN_NLayers, // Na FANN, cada Neuronio tem uma função de ativação. A neuralnet usa somente a função de ativação do primeiro neuronio, // porem a primeira camada da FANN nao tem função de ativação, logo pegamos da camada seguinte (ANN->first_layer+1)->first_neuron->activation_function, ANN->BiperbolicLambda,ANN->BiperbolicT1,ANN->BiperbolicT2, ANN_NNeurons, ANN->input_min,ANN->input_max,ANN->output_min,ANN->output_max, // Na FANN, cada Neuronio tem um steepness de ativação. A neuralnet usa somente o steepness de ativação do primeiro neuronio, // porem a primeira camada da FANN nao tem stepness, logo pegamos da camada seguinte (ANN->first_layer+1)->first_neuron->activation_steepness, // A FANN tem um bias para cada camada da rede, na NeuralNet eh usado somente o bias da primeira camada BiasArray[0], ANN_Weights ); NN->MSE = fann_get_MSE(ANN); return NN; }
/* * Internal train function */ float fann_train_epoch_incremental(struct fann *ann, struct fann_train_data *data) { unsigned int i; fann_reset_MSE(ann); for(i = 0; i != data->num_data; i++) { fann_train(ann, data->input[i], data->output[i]); } return fann_get_MSE(ann); }
/* * Test a set of training data and calculate the MSE */ FANN_EXTERNAL float FANN_API fann_test_data(struct fann *ann, struct fann_train_data *data) { unsigned int i; fann_reset_MSE(ann); for(i = 0; i != data->num_data; i++) { fann_test(ann, data->input[i], data->output[i]); } return fann_get_MSE(ann); }
int main() { const unsigned int num_layers = 3; const unsigned int num_neurons_hidden = 32; const float desired_error = (const float) 0.0001; const unsigned int max_epochs = 300; const unsigned int epochs_between_reports = 10; struct fann *ann; struct fann_train_data *train_data, *test_data; unsigned int i = 0; printf("Creating network.\n"); train_data = fann_read_train_from_file("../datasets/mushroom.train"); ann = fann_create_standard(num_layers, train_data->num_input, num_neurons_hidden, train_data->num_output); printf("Training network.\n"); fann_set_activation_function_hidden(ann, FANN_SIGMOID_SYMMETRIC_STEPWISE); fann_set_activation_function_output(ann, FANN_SIGMOID_STEPWISE); /*fann_set_training_algorithm(ann, FANN_TRAIN_INCREMENTAL); */ fann_train_on_data(ann, train_data, max_epochs, epochs_between_reports, desired_error); printf("Testing network.\n"); test_data = fann_read_train_from_file("../datasets/mushroom.test"); fann_reset_MSE(ann); for(i = 0; i < fann_length_train_data(test_data); i++) { fann_test(ann, test_data->input[i], test_data->output[i]); } printf("MSE error on test data: %f\n", fann_get_MSE(ann)); printf("Saving network.\n"); fann_save(ann, "mushroom_float.net"); printf("Cleaning up.\n"); fann_destroy_train(train_data); fann_destroy_train(test_data); fann_destroy(ann); return 0; }
float train_epoch_debug(struct fann *ann, struct fann_train_data* data, unsigned int iter) { unsigned int i; #if VERBOSE>=2 static unsigned int j=0; #endif #if ! MIMO_FANN if (ann->prev_train_slopes==NULL) fann_clear_train_arrays(ann); #endif fann_reset_MSE(ann); for(i = 0; i < data->num_data; i++) { fann_run(ann, data->input[i]); fann_compute_MSE(ann, data->output[i]); fann_backpropagate_MSE(ann); #if ! MIMO_FANN fann_update_slopes_batch(ann, ann->first_layer + 1, ann->last_layer - 1); #endif #if VERBOSE>=3 printf(" ** %d:%d **-AFTER-DELTAS UPDATE-----------------------------------\n", iter, i); print_deltas(ann, j++); #endif } #if VERBOSE>=2 printf(" ** %d **-BEFORE-WEIGHTS-UPDATE------------------------------------\n", iter); print_deltas(ann, j++); #endif #if ! MIMO_FANN #if USE_RPROP fann_update_weights_irpropm(ann, 0, ann->total_connections); #else fann_update_weights_batch(ann, data->num_data, 0, ann->total_connections); #endif #else /* MIMO_FANN */ fann_update_weights(ann); #endif #if VERBOSE>=1 printf(" ** %d **-AFTER-WEIGHTS-UPDATE-------------------------------------\n", iter); print_deltas(ann, j++); #endif return fann_get_MSE(ann); }
void NeuralNet::runNet(char* ptrDataFileName){ struct fann_train_data *ptrDataTest = fann_read_train_from_file(ptrDataFileName); fann_reset_MSE(this->ptrNeuralNet); fann_test_data(this->ptrNeuralNet, ptrDataTest); printf("Mean Square Error: %f\n", fann_get_MSE(this->ptrNeuralNet)); fann_type *calc_out; for(int i = 0; i < fann_length_train_data(ptrDataTest); i++){ calc_out = fann_run(this->ptrNeuralNet, ptrDataTest->input[i]); cout << "Sample testing: "<< calc_out[0] << " " << ptrDataTest->output[i][0] << " " << fann_abs(calc_out[0] - ptrDataTest->output[i][0]) << endl; } fann_destroy_train(ptrDataTest); }
int ViFann::trainCallback(fann* network, fann_train_data *data, unsigned int maxEpochs, unsigned int epochReports, float desiredMse, unsigned int epochs) { if(mMseTotal.size() <= epochs) { for(int i = mMseTotal.size(); i <= epochs; ++i) { mMseTotal.append(0); } } mMseTotal[epochs] += fann_get_MSE(network); if(epochs == 1) ++mMseCount; return 0; }
/* * INTERNAL FUNCTION returns 0 if the desired error is reached and -1 if it is not reached */ int fann_desired_error_reached(struct fann *ann, float desired_error) { switch (ann->train_stop_function) { case FANN_STOPFUNC_MSE: if(fann_get_MSE(ann) <= desired_error) return 0; break; case FANN_STOPFUNC_BIT: if(ann->num_bit_fail <= (unsigned int)desired_error) return 0; break; } return -1; }
float test_data_parallel(struct fann *ann, struct fann_train_data *data, const unsigned int threadnumb, vector< vector<fann_type> >& predicted_outputs) { if(fann_check_input_output_sizes(ann, data) == -1) return 0; predicted_outputs.resize(data->num_data,vector<fann_type> (data->num_output)); fann_reset_MSE(ann); vector<struct fann *> ann_vect(threadnumb); int i=0,j=0; //generate copies of the ann omp_set_dynamic(0); omp_set_num_threads(threadnumb); #pragma omp parallel private(j) { #pragma omp for schedule(static) for(i=0; i<(int)threadnumb; i++) { ann_vect[i]=fann_copy(ann); } //parallel computing of the updates #pragma omp for schedule(static) for(i = 0; i < (int)data->num_data; ++i) { j=omp_get_thread_num(); fann_type* temp_predicted_output=fann_test(ann_vect[j], data->input[i],data->output[i]); for(unsigned int k=0;k<data->num_output;++k) { predicted_outputs[i][k]=temp_predicted_output[k]; } } } //merge of MSEs for(i=0;i<(int)threadnumb;++i) { ann->MSE_value+= ann_vect[i]->MSE_value; ann->num_MSE+=ann_vect[i]->num_MSE; fann_destroy(ann_vect[i]); } return fann_get_MSE(ann); }
/* * Internal train function */ float fann_train_epoch_batch(struct fann *ann, struct fann_train_data *data) { unsigned int i; fann_reset_MSE(ann); for(i = 0; i < data->num_data; i++) { fann_run(ann, data->input[i]); fann_compute_MSE(ann, data->output[i]); fann_backpropagate_MSE(ann); fann_update_slopes_batch(ann, ann->first_layer + 1, ann->last_layer - 1); } fann_update_weights_batch(ann, data->num_data, 0, ann->total_connections); return fann_get_MSE(ann); }
/*** * @method rspamd_fann:get_mse() * Returns mean square error for ANN * @return {number} MSE value */ static gint lua_fann_get_mse (lua_State *L) { #ifndef WITH_FANN return 0; #else struct fann *f = rspamd_lua_check_fann (L, 1); if (f != NULL) { lua_pushnumber (L, fann_get_MSE (f)); } else { lua_pushnil (L); } return 1; #endif }
/* Creer le meilleur fichier .net (apprentissage) possible basé sur des tests effectués au cours de l'apprentissage en fonction du nombre de neuronnes cachés choisis en entrée. */ void train(struct fann *ann, char* trainFile, char *testFile, char *netFile , unsigned int max_epochs, unsigned int epochs_between_reports, float desired_error, const unsigned int num_neurons_hidden) { struct fann_train_data *trainData, *testData; struct fann *annBest = fann_copy(ann); float error; unsigned int i; char buffer[1024]; float testError = 1; float testErrorBest = 1; trainData = fann_read_train_from_file(trainFile); testData = fann_read_train_from_file(testFile); for(i = 1; i <= max_epochs; i++){ fann_shuffle_train_data(trainData); //melange les données error = fann_train_epoch(ann, trainData); //fait une epoque, ann : le réseaux créer, erreur : l'erreur d'apprentissage //Toute les 5 epoques if(i % epochs_between_reports == 0 || error < desired_error){ fann_test_data(ann,testData);// teste le reseau sur les donnée de test testError = fann_get_MSE(ann); if (testError < testErrorBest) { testErrorBest = testError; annBest = fann_copy(ann); printf("Epochs %8d; trainError : %f; testError : %f;\n", i, error,testError); sprintf(buffer,"%s_%u_%d.net",netFile,num_neurons_hidden,i); fann_save(annBest, buffer); } } if(error < desired_error){ break; } } sprintf(buffer,"%s_%u.net",netFile,num_neurons_hidden); fann_save(annBest, buffer); fann_destroy_train(trainData); fann_destroy_train(testData); }
float train_epoch_incremental_mod(struct fann *ann, struct fann_train_data *data, vector< vector<fann_type> >& predicted_outputs) { predicted_outputs.resize(data->num_data,vector<fann_type> (data->num_output)); fann_reset_MSE(ann); for(unsigned int i = 0; i < data->num_data; ++i) { fann_type* temp_predicted_output=fann_run(ann, data->input[i]); for(unsigned int k=0;k<data->num_output;++k) { predicted_outputs[i][k]=temp_predicted_output[k]; } fann_compute_MSE(ann, data->output[i]); fann_backpropagate_MSE(ann); fann_update_weights(ann); } return fann_get_MSE(ann); }
float fann_train_outputs_epoch(struct fann *ann, struct fann_train_data *data) { unsigned int i; fann_reset_MSE(ann); for(i = 0; i < data->num_data; i++) { fann_run(ann, data->input[i]); fann_compute_MSE(ann, data->output[i]); fann_update_slopes_batch(ann, ann->last_layer - 1, ann->last_layer - 1); } switch (ann->training_algorithm) { case FANN_TRAIN_RPROP: fann_update_weights_irpropm(ann, (ann->last_layer - 1)->first_neuron->first_con, ann->total_connections); break; case FANN_TRAIN_SARPROP: fann_update_weights_sarprop(ann, ann->sarprop_epoch, (ann->last_layer - 1)->first_neuron->first_con, ann->total_connections); ++(ann->sarprop_epoch); break; case FANN_TRAIN_QUICKPROP: fann_update_weights_quickprop(ann, data->num_data, (ann->last_layer - 1)->first_neuron->first_con, ann->total_connections); break; case FANN_TRAIN_BATCH: case FANN_TRAIN_INCREMENTAL: fann_error((struct fann_error *) ann, FANN_E_CANT_USE_TRAIN_ALG); } return fann_get_MSE(ann); }
void MainWindow::onLearnPericarditis() { QString trainFileName = QFileDialog::getOpenFileName(this, tr("Open training file"), "", tr("Training file (*.data)")); if(trainFileName.isEmpty()) return; if(pAnn != 0) fann_destroy(pAnn); const unsigned int num_input = 1; const unsigned int num_output = 1; const unsigned int num_layers = 3; const unsigned int num_neurons_hidden = 4; const float desired_error = 0.001f; const unsigned int max_epochs = 50000; const unsigned int epochs_between_reports = 0; pAnn= fann_create_standard(num_layers, num_input, num_neurons_hidden, num_output); fann_set_activation_function_hidden(pAnn, FANN_SIGMOID_SYMMETRIC); fann_set_activation_function_output(pAnn, FANN_SIGMOID_SYMMETRIC); QByteArray ba = trainFileName.toLocal8Bit(); std::cout << ba.data(); fann_train_on_file(pAnn, ba.data(), max_epochs, epochs_between_reports, desired_error); QMessageBox::information(this, "Training Complete", QString("Training error = ") + QString::number(fann_get_MSE(pAnn))); ui->tabWidget->setTabEnabled(2, true); }
bool Trainer::Test(const AnnData& data, float* mse, std::size_t* bit_fail) { float mse_tmp = fann_test_data(ann_, data.data()); BOOST_ASSERT(fabs(mse_tmp - fann_get_MSE(ann_)) < 0.0001); return GetMseAndBitFail(ann_, &mse, &bit_fail); }
/* arguments (all required): - data filename - topology, as number of neurons per layer separated by dashes - epochs (integer) - learning rate (0.0-1.0 float) - output filename */ int main(int argc, char **argv) { // Argument 1: data filename. const char *datafn = argv[1]; // Argument 2: topology. unsigned int layer_sizes[MAX_LAYERS]; unsigned int num_layers = 0; char *token = strtok(argv[2], "-"); while (token != NULL) { layer_sizes[num_layers] = atoi(token); ++num_layers; token = strtok(NULL, "-"); } // Argument 3: epoch count. unsigned int max_epochs = atoi(argv[3]); // Argument 4: learning rate. float learning_rate = atof(argv[4]); // Argument 5: output filename. const char *outfn = argv[5]; struct fann *ann; ann = fann_create_standard_array(num_layers, layer_sizes); // Misc parameters. fann_set_training_algorithm(ann, FANN_TRAIN_RPROP); fann_set_activation_steepness_hidden(ann, 0.5); fann_set_activation_steepness_output(ann, 0.5); fann_set_activation_function_hidden(ann, FANN_SIGMOID); fann_set_activation_function_output(ann, FANN_SIGMOID); //fann_set_train_stop_function(ann, FANN_STOPFUNC_BIT); //fann_set_bit_fail_limit(ann, 0.01f); struct fann_train_data *data; data = fann_read_train_from_file(datafn); fann_init_weights(ann, data); fann_set_learning_rate(ann, learning_rate); fann_train_on_data( ann, data, max_epochs, 10, // epochs between reports DESIRED_ERROR ); printf("Testing network. %f\n", fann_test_data(ann, data)); fann_type *calc_out; for(unsigned int i = 0; i < fann_length_train_data(data); ++i) { calc_out = fann_run(ann, data->input[i]); } printf("RMSE = %f\n", sqrt(fann_get_MSE(ann))); fann_save(ann, outfn); fann_destroy_train(data); fann_destroy(ann); return 0; }
int main(int argc, char *argv[]) { double l, R = 0, H = 0, mse = 0.25; ssv_t *x, *y, *z, *e, *u, *r; struct fann *h = 0; long d, k, t = 0; int status; pid_t pid; START: if ((pid = asc_ptrace_start(argc - 1, argv + 1)) < 0) goto EXIT; ALLOCATE: if ((x = (asc_ssv_gather(0, pid))) == 0) goto PANIC; if ((y = (asc_ssv_gather(0, pid))) == 0) goto PANIC; if ((z = (asc_ssv_gather(0, pid))) == 0) goto PANIC; if ((u = (asc_ssv_gather(0, pid))) == 0) goto PANIC; if ((e = (asc_ssv_gather(0, pid))) == 0) goto PANIC; if ((r = (asc_ssv_gather(0, pid))) == 0) goto PANIC; CLEAR: asc_ssv_xor(x, x, x); asc_ssv_xor(z, z, z); asc_ssv_xor(u, u, u); asc_ssv_xor(e, e, e); asc_ssv_xor(r, r, r); goto TRANSITION; WAIT: if (waitpid(-1, &status, 0) != pid) goto PANIC; SWAP: asc_ssv_swap(x, y); GATHER: if ((asc_ssv_gather(y, pid)) == 0) goto PANIC; TRANSITION: if (ptrace(PTRACE_SYSEMU_SINGLESTEP, pid, 0, 0) < 0) goto PANIC; asc_ssv_xor(r, u, y); LOSS: l = asc_ssv_popcount(r); REGRET: if (t > 1) R += l; HITS: H += l == 0; DIFF: asc_ssv_xor(z, x, y); HAMMING: d = asc_ssv_popcount(z); EXCITE: if (t > 1) asc_ssv_ior(e, e, z); DEGREES: k = asc_ssv_popcount(e); UPDATE: h = asc_update(h, 0, z, x, e); MSE: if (h) mse = fann_get_MSE(h); PREDICT: asc_online_predict(u, y, e, h); READOUT: if (t++ == 0) printf("%7s\t%7s\t%7s\t%7s\t%7s\t%7s\n", "round", "|e|", "|y-x|", "|y-u|", "regret", "MSE"); printf("%7ld\t%7ld\t%7ld\t%7.0f\t%.4f\t%.4f\t%7.3f\n", t, k, d, l, R / t, mse, 100 * (1 - H / t)); LOOP: if (t > 10) goto EXIT; goto WAIT; PANIC: fprintf(stderr, "PANIC: run aborted: %m\n"); EXIT: exit(errno); }
float train_epoch_sarprop_parallel(struct fann *ann, struct fann_train_data *data, const unsigned int threadnumb, vector< vector<fann_type> >& predicted_outputs) { if(ann->prev_train_slopes == NULL) { fann_clear_train_arrays(ann); } fann_reset_MSE(ann); predicted_outputs.resize(data->num_data,vector<fann_type> (data->num_output)); vector<struct fann *> ann_vect(threadnumb); int i=0,j=0; //generate copies of the ann omp_set_dynamic(0); omp_set_num_threads(threadnumb); #pragma omp parallel private(j) { #pragma omp for schedule(static) for(i=0; i<(int)threadnumb; i++) { ann_vect[i]=fann_copy(ann); } //parallel computing of the updates #pragma omp for schedule(static) for(i = 0; i < (int)data->num_data; i++) { j=omp_get_thread_num(); fann_type* temp_predicted_output=fann_run(ann_vect[j], data->input[i]); for(unsigned int k=0;k<data->num_output;++k) { predicted_outputs[i][k]=temp_predicted_output[k]; } fann_compute_MSE(ann_vect[j], data->output[i]); fann_backpropagate_MSE(ann_vect[j]); fann_update_slopes_batch(ann_vect[j], ann_vect[j]->first_layer + 1, ann_vect[j]->last_layer - 1); } } { fann_type *weights = ann->weights; fann_type *prev_steps = ann->prev_steps; fann_type *prev_train_slopes = ann->prev_train_slopes; const unsigned int first_weight=0; const unsigned int past_end=ann->total_connections; const unsigned int epoch=ann->sarprop_epoch; fann_type next_step; /* These should be set from variables */ const float increase_factor = ann->rprop_increase_factor; /*1.2; */ const float decrease_factor = ann->rprop_decrease_factor; /*0.5; */ /* TODO: why is delta_min 0.0 in iRprop? SARPROP uses 1x10^-6 (Braun and Riedmiller, 1993) */ const float delta_min = 0.000001f; const float delta_max = ann->rprop_delta_max; /*50.0; */ const float weight_decay_shift = ann->sarprop_weight_decay_shift; /* ld 0.01 = -6.644 */ const float step_error_threshold_factor = ann->sarprop_step_error_threshold_factor; /* 0.1 */ const float step_error_shift = ann->sarprop_step_error_shift; /* ld 3 = 1.585 */ const float T = ann->sarprop_temperature; //merge of MSEs for(i=0;i<(int)threadnumb;++i) { ann->MSE_value+= ann_vect[i]->MSE_value; ann->num_MSE+=ann_vect[i]->num_MSE; } const float MSE = fann_get_MSE(ann); const float RMSE = (float)sqrt(MSE); /* for all weights; TODO: are biases included? */ omp_set_dynamic(0); omp_set_num_threads(threadnumb); #pragma omp parallel private(next_step) { #pragma omp for schedule(static) for(i=first_weight; i < (int)past_end; i++) { /* TODO: confirm whether 1x10^-6 == delta_min is really better */ const fann_type prev_step = fann_max(prev_steps[i], (fann_type) 0.000001); /* prev_step may not be zero because then the training will stop */ /* calculate SARPROP slope; TODO: better as new error function? (see SARPROP paper)*/ fann_type temp_slopes=0.0; unsigned int k; fann_type *train_slopes; for(k=0;k<threadnumb;++k) { train_slopes=ann_vect[k]->train_slopes; temp_slopes+= train_slopes[i]; train_slopes[i]=0.0; } temp_slopes= -temp_slopes - weights[i] * (fann_type)fann_exp2(-T * epoch + weight_decay_shift); next_step=0.0; /* TODO: is prev_train_slopes[i] 0.0 in the beginning? */ const fann_type prev_slope = prev_train_slopes[i]; const fann_type same_sign = prev_slope * temp_slopes; if(same_sign > 0.0) { next_step = fann_min(prev_step * increase_factor, delta_max); /* TODO: are the signs inverted? see differences between SARPROP paper and iRprop */ if (temp_slopes < 0.0) weights[i] += next_step; else weights[i] -= next_step; } else if(same_sign < 0.0) { #ifndef RAND_MAX #define RAND_MAX 0x7fffffff #endif if(prev_step < step_error_threshold_factor * MSE) next_step = prev_step * decrease_factor + (float)rand() / RAND_MAX * RMSE * (fann_type)fann_exp2(-T * epoch + step_error_shift); else next_step = fann_max(prev_step * decrease_factor, delta_min); temp_slopes = 0.0; } else { if(temp_slopes < 0.0) weights[i] += prev_step; else weights[i] -= prev_step; } /* update global data arrays */ prev_steps[i] = next_step; prev_train_slopes[i] = temp_slopes; } } } ++(ann->sarprop_epoch); //already computed before /*//merge of MSEs for(i=0;i<threadnumb;++i) { ann->MSE_value+= ann_vect[i]->MSE_value; ann->num_MSE+=ann_vect[i]->num_MSE; }*/ //destroy the copies of the ann for(i=0; i<(int)threadnumb; i++) { fann_destroy(ann_vect[i]); } return fann_get_MSE(ann); }
float train_epoch_irpropm_parallel(struct fann *ann, struct fann_train_data *data, const unsigned int threadnumb) { if(ann->prev_train_slopes == NULL) { fann_clear_train_arrays(ann); } //#define THREADNUM 1 fann_reset_MSE(ann); vector<struct fann *> ann_vect(threadnumb); int i=0,j=0; //generate copies of the ann omp_set_dynamic(0); omp_set_num_threads(threadnumb); #pragma omp parallel private(j) { #pragma omp for schedule(static) for(i=0; i<(int)threadnumb; i++) { ann_vect[i]=fann_copy(ann); } //parallel computing of the updates #pragma omp for schedule(static) for(i = 0; i < (int)data->num_data; i++) { j=omp_get_thread_num(); fann_run(ann_vect[j], data->input[i]); fann_compute_MSE(ann_vect[j], data->output[i]); fann_backpropagate_MSE(ann_vect[j]); fann_update_slopes_batch(ann_vect[j], ann_vect[j]->first_layer + 1, ann_vect[j]->last_layer - 1); } } { fann_type *weights = ann->weights; fann_type *prev_steps = ann->prev_steps; fann_type *prev_train_slopes = ann->prev_train_slopes; fann_type next_step; const float increase_factor = ann->rprop_increase_factor; //1.2; const float decrease_factor = ann->rprop_decrease_factor; //0.5; const float delta_min = ann->rprop_delta_min; //0.0; const float delta_max = ann->rprop_delta_max; //50.0; const unsigned int first_weight=0; const unsigned int past_end=ann->total_connections; omp_set_dynamic(0); omp_set_num_threads(threadnumb); #pragma omp parallel private(next_step) { #pragma omp for schedule(static) for(i=first_weight; i < (int)past_end; i++) { const fann_type prev_step = fann_max(prev_steps[i], (fann_type) 0.0001); // prev_step may not be zero because then the training will stop fann_type temp_slopes=0.0; unsigned int k; fann_type *train_slopes; for(k=0;k<threadnumb;++k) { train_slopes=ann_vect[k]->train_slopes; temp_slopes+= train_slopes[i]; train_slopes[i]=0.0; } const fann_type prev_slope = prev_train_slopes[i]; const fann_type same_sign = prev_slope * temp_slopes; if(same_sign >= 0.0) next_step = fann_min(prev_step * increase_factor, delta_max); else { next_step = fann_max(prev_step * decrease_factor, delta_min); temp_slopes = 0; } if(temp_slopes < 0) { weights[i] -= next_step; if(weights[i] < -1500) weights[i] = -1500; } else { weights[i] += next_step; if(weights[i] > 1500) weights[i] = 1500; } // update global data arrays prev_steps[i] = next_step; prev_train_slopes[i] = temp_slopes; } } } //merge of MSEs for(i=0;i<(int)threadnumb;++i) { ann->MSE_value+= ann_vect[i]->MSE_value; ann->num_MSE+=ann_vect[i]->num_MSE; fann_destroy(ann_vect[i]); } return fann_get_MSE(ann); }
float train_epoch_quickprop_parallel(struct fann *ann, struct fann_train_data *data, const unsigned int threadnumb, vector< vector<fann_type> >& predicted_outputs) { if(ann->prev_train_slopes == NULL) { fann_clear_train_arrays(ann); } fann_reset_MSE(ann); predicted_outputs.resize(data->num_data,vector<fann_type> (data->num_output)); vector<struct fann *> ann_vect(threadnumb); int i=0,j=0; //generate copies of the ann omp_set_dynamic(0); omp_set_num_threads(threadnumb); #pragma omp parallel private(j) { #pragma omp for schedule(static) for(i=0; i<(int)threadnumb; i++) { ann_vect[i]=fann_copy(ann); } //parallel computing of the updates #pragma omp for schedule(static) for(i = 0; i < (int)data->num_data; i++) { j=omp_get_thread_num(); fann_type* temp_predicted_output=fann_run(ann_vect[j], data->input[i]); for(unsigned int k=0;k<data->num_output;++k) { predicted_outputs[i][k]=temp_predicted_output[k]; } fann_compute_MSE(ann_vect[j], data->output[i]); fann_backpropagate_MSE(ann_vect[j]); fann_update_slopes_batch(ann_vect[j], ann_vect[j]->first_layer + 1, ann_vect[j]->last_layer - 1); } } { fann_type *weights = ann->weights; fann_type *prev_steps = ann->prev_steps; fann_type *prev_train_slopes = ann->prev_train_slopes; const unsigned int first_weight=0; const unsigned int past_end=ann->total_connections; fann_type w=0.0, next_step; const float epsilon = ann->learning_rate / data->num_data; const float decay = ann->quickprop_decay; /*-0.0001;*/ const float mu = ann->quickprop_mu; /*1.75; */ const float shrink_factor = (float) (mu / (1.0 + mu)); omp_set_dynamic(0); omp_set_num_threads(threadnumb); #pragma omp parallel private(w, next_step) { #pragma omp for schedule(static) for(i=first_weight; i < (int)past_end; i++) { w = weights[i]; fann_type temp_slopes=0.0; unsigned int k; fann_type *train_slopes; for(k=0;k<threadnumb;++k) { train_slopes=ann_vect[k]->train_slopes; temp_slopes+= train_slopes[i]; train_slopes[i]=0.0; } temp_slopes+= decay * w; const fann_type prev_step = prev_steps[i]; const fann_type prev_slope = prev_train_slopes[i]; next_step = 0.0; /* The step must always be in direction opposite to the slope. */ if(prev_step > 0.001) { /* If last step was positive... */ if(temp_slopes > 0.0) /* Add in linear term if current slope is still positive. */ next_step += epsilon * temp_slopes; /*If current slope is close to or larger than prev slope... */ if(temp_slopes > (shrink_factor * prev_slope)) next_step += mu * prev_step; /* Take maximum size negative step. */ else next_step += prev_step * temp_slopes / (prev_slope - temp_slopes); /* Else, use quadratic estimate. */ } else if(prev_step < -0.001) { /* If last step was negative... */ if(temp_slopes < 0.0) /* Add in linear term if current slope is still negative. */ next_step += epsilon * temp_slopes; /* If current slope is close to or more neg than prev slope... */ if(temp_slopes < (shrink_factor * prev_slope)) next_step += mu * prev_step; /* Take maximum size negative step. */ else next_step += prev_step * temp_slopes / (prev_slope - temp_slopes); /* Else, use quadratic estimate. */ } else /* Last step was zero, so use only linear term. */ next_step += epsilon * temp_slopes; /* update global data arrays */ prev_steps[i] = next_step; prev_train_slopes[i] = temp_slopes; w += next_step; if(w > 1500) weights[i] = 1500; else if(w < -1500) weights[i] = -1500; else weights[i] = w; } } } //merge of MSEs for(i=0;i<(int)threadnumb;++i) { ann->MSE_value+= ann_vect[i]->MSE_value; ann->num_MSE+=ann_vect[i]->num_MSE; fann_destroy(ann_vect[i]); } return fann_get_MSE(ann); }
float train_epoch_batch_parallel(struct fann *ann, struct fann_train_data *data, const unsigned int threadnumb,vector< vector<fann_type> >& predicted_outputs) { fann_reset_MSE(ann); predicted_outputs.resize(data->num_data,vector<fann_type> (data->num_output)); vector<struct fann *> ann_vect(threadnumb); int i=0,j=0; //generate copies of the ann omp_set_dynamic(0); omp_set_num_threads(threadnumb); #pragma omp parallel private(j) { #pragma omp for schedule(static) for(i=0; i<(int)threadnumb; i++) { ann_vect[i]=fann_copy(ann); } //parallel computing of the updates #pragma omp for schedule(static) for(i = 0; i < (int)data->num_data; i++) { j=omp_get_thread_num(); fann_type* temp_predicted_output=fann_run(ann_vect[j], data->input[i]); for(unsigned int k=0;k<data->num_output;++k) { predicted_outputs[i][k]=temp_predicted_output[k]; } fann_compute_MSE(ann_vect[j], data->output[i]); fann_backpropagate_MSE(ann_vect[j]); fann_update_slopes_batch(ann_vect[j], ann_vect[j]->first_layer + 1, ann_vect[j]->last_layer - 1); } } //parallel update of the weights { const unsigned int num_data=data->num_data; const unsigned int first_weight=0; const unsigned int past_end=ann->total_connections; fann_type *weights = ann->weights; const fann_type epsilon = ann->learning_rate / num_data; omp_set_dynamic(0); omp_set_num_threads(threadnumb); #pragma omp parallel { #pragma omp for schedule(static) for(i=first_weight; i < (int)past_end; i++) { fann_type temp_slopes=0.0; unsigned int k; fann_type *train_slopes; for(k=0;k<threadnumb;++k) { train_slopes=ann_vect[k]->train_slopes; temp_slopes+= train_slopes[i]; train_slopes[i]=0.0; } weights[i] += temp_slopes*epsilon; } } } //merge of MSEs for(i=0;i<(int)threadnumb;++i) { ann->MSE_value+= ann_vect[i]->MSE_value; ann->num_MSE+=ann_vect[i]->num_MSE; fann_destroy(ann_vect[i]); } return fann_get_MSE(ann); }
/************************************************** REAL-TIME RECURRENT LEARNING Williams and Zipser, "A Learning Algorithm for Continually Running Fully Recurrent Neural Networks," Neural Computation, 1. (1989) NOTE: This function is still being debugged. MSE does not decrease properly. *************************************************/ FANN_EXTERNAL void FANN_API fann_train_rtrl(struct fann *ann, struct fann_train_data *pattern, float max_MSE, unsigned int max_iters, float rate) { struct fann_neuron *neuron = NULL; struct fann_layer *layer = NULL; fann_type *curr_outputs = NULL; fann_type *curr_weight = NULL; unsigned int num_neurons = 0; unsigned int curr_neuron = 0; unsigned int num_iters = 0; unsigned int i = 0, j = 0, l = 0; float *dodw = NULL; /* deriv of output wrt weight*/ float *curr_dodw = NULL; float *next_dodw = NULL; /* dodw for time 'n+1'*/ float *curr_next_dodw = NULL; float *start_dodw = NULL; float *temp_swap = NULL; /* for swapping dodw pointers*/ float dw = 0.0; /* change in weight*/ assert(ann != NULL); assert(pattern != NULL); /* Only one MIMO neuron and layer in recurrent nets*/ layer = ann->first_layer; neuron = layer->first_neuron; memset(layer->outputs, 0, num_neurons * sizeof(fann_type)); /* Allocate memory for new outputs*/ /* TODO: Return an error*/ num_neurons = layer->num_outputs; if ((curr_outputs = calloc(num_neurons, sizeof(fann_type))) == NULL) { /*fann_error((struct fann_error *) orig, FANN_E_CANT_ALLOCATE_MEM);*/ printf("RTRL: Could not allocate 'curr_outputs'\n"); return; } /* Allocate memory for derivatives do_k(t)/dw_i,j*/ /* TODO: Return an error*/ if ((dodw = calloc(ann->num_output * neuron->num_weights * neuron->num_weights, sizeof(float))) == NULL) { /*fann_error((struct fann_error *) orig, FANN_E_CANT_ALLOCATE_MEM);*/ printf("RTRL: Could not allocate 'dodw'\n"); return; } /* Allocate memory for derivatives do_k(t)/dw_i,j*/ /* TODO: Return an error*/ if ((next_dodw = calloc(neuron->num_weights * num_neurons, sizeof(float))) == NULL) { /*fann_error((struct fann_error *) orig, FANN_E_CANT_ALLOCATE_MEM);*/ printf("RTRL: Could not allocate 'next_dodw'\n"); return; } /* Randomize weights, initialize for training*/ fann_randomize_weights(ann, -0.5, 0.5); if (layer->train_errors==NULL) { layer->initialize_train_errors(ann, ann->first_layer); } /* RTRL: Continue learning until MSE low enough or reach*/ /* max iterations*/ num_iters = 0; ann->training_params->MSE_value = 100; while (ann->training_params->MSE_value > max_MSE && num_iters <= max_iters) { /* Set the input lines for this time step*/ /*printf("%d inputs: ", ann->num_input);*/ for (i=0; i<ann->num_input; i++) { ann->inputs[i] = pattern->input[num_iters][i]; printf("%f ", (double) ann->inputs[i]); } /*printf("(output: %f) (bias: %f) \n", pattern->output[num_iters][0], ann->inputs[ann->num_input]);*/ /* Copy the outputs of each neuron before they're updated*/ memcpy(curr_outputs, layer->outputs, num_neurons * sizeof(fann_type)); /* Update the output of all nodes*/ layer->run(ann, layer); /*printf("NEW OUTPUTS: %f %f %f\n", layer->outputs[0], layer->outputs[1], layer->outputs[2]);*/ /*printf("ANN OUTPUTS: %f\n", ann->output[0]);*/ /*curr_weight = neuron->weights; for (i=0; i<num_neurons; i++) { for (j=0; j<layer->num_inputs + num_neurons; j++) { printf("weight_prev (%d,%d): %f ", i, j, *curr_weight); curr_weight++; } } printf("\n");*/ /* Compute new MSE*/ fann_reset_MSE(ann); fann_compute_MSE(ann, pattern->output[num_iters]); printf("%d MSE: %f\n", num_iters, fann_get_MSE(ann)); /* Modify the weights*/ start_dodw = dodw + (num_neurons - ann->num_output) * neuron->num_weights; for (i=0; i<num_neurons; i++) { curr_weight = neuron[i].weights; for (j=0; j<layer->num_inputs + num_neurons; j++) { dw = 0.0; curr_dodw = start_dodw; /* For each neuron in which is not an input node*/ for (curr_neuron=num_neurons - ann->num_output; curr_neuron<num_neurons; curr_neuron++) { dw += (pattern->output[num_iters][curr_neuron - (num_neurons - ann->num_output)] - curr_outputs[curr_neuron]) * *curr_dodw; curr_dodw += neuron->num_weights; } *curr_weight += dw * rate; /*printf("weight (%d,%d): %f\n", i, j, *curr_weight);*/ curr_weight++; start_dodw++; } } /* Compute next dodw derivatives*/ curr_next_dodw = next_dodw; for (curr_neuron=0; curr_neuron<num_neurons; curr_neuron++) { start_dodw = dodw; curr_weight = neuron->weights; for (i=0; i<num_neurons; i++) { for (j=0; j<layer->num_inputs + num_neurons; j++) { curr_dodw = start_dodw; *curr_next_dodw = 0.0; for (l=0; l<num_neurons; l++) { *curr_next_dodw += *curr_dodw * neuron->weights[curr_neuron * (layer->num_inputs + num_neurons) + l + layer->num_inputs]; curr_dodw += neuron->num_weights; } /* kronecker_{i,k} * z_j(t)*/ *curr_next_dodw += (i != curr_neuron) ? 0 : ((j < layer->num_inputs) ? ann->inputs[j] : curr_outputs[j - layer->num_inputs]); *curr_next_dodw *= layer->outputs[curr_neuron]*(1 - layer->outputs[curr_neuron]); /*printf("(%d,%d): %f\n", i, j, *curr_next_dodw);*/ curr_next_dodw++; curr_weight++; start_dodw++; } } } /* Swap the next and the current dodw*/ /* (to avoid a costly memory transfer)*/ temp_swap = dodw; dodw = next_dodw; next_dodw = temp_swap; num_iters++; } fann_safe_free(dodw); fann_safe_free(curr_outputs); }
/* INTERNAL FUNCTION The SARprop- algorithm */ void fann_update_weights_sarprop(struct fann *ann, unsigned int epoch, unsigned int first_weight, unsigned int past_end) { fann_type *train_slopes = ann->train_slopes; fann_type *weights = ann->weights; fann_type *prev_steps = ann->prev_steps; fann_type *prev_train_slopes = ann->prev_train_slopes; fann_type prev_step, slope, prev_slope, next_step = 0, same_sign; /* These should be set from variables */ float increase_factor = ann->rprop_increase_factor; /*1.2; */ float decrease_factor = ann->rprop_decrease_factor; /*0.5; */ /* TODO: why is delta_min 0.0 in iRprop? SARPROP uses 1x10^-6 (Braun and Riedmiller, 1993) */ float delta_min = 0.000001f; float delta_max = ann->rprop_delta_max; /*50.0; */ float weight_decay_shift = ann->sarprop_weight_decay_shift; /* ld 0.01 = -6.644 */ float step_error_threshold_factor = ann->sarprop_step_error_threshold_factor; /* 0.1 */ float step_error_shift = ann->sarprop_step_error_shift; /* ld 3 = 1.585 */ float T = ann->sarprop_temperature; float MSE = fann_get_MSE(ann); float RMSE = (float)sqrt(MSE); unsigned int i = first_weight; /* for all weights; TODO: are biases included? */ for(; i != past_end; i++) { /* TODO: confirm whether 1x10^-6 == delta_min is really better */ prev_step = fann_max(prev_steps[i], (fann_type) 0.000001); /* prev_step may not be zero because then the training will stop */ /* calculate SARPROP slope; TODO: better as new error function? (see SARPROP paper)*/ slope = -train_slopes[i] - weights[i] * (fann_type)fann_exp2(-T * epoch + weight_decay_shift); /* TODO: is prev_train_slopes[i] 0.0 in the beginning? */ prev_slope = prev_train_slopes[i]; same_sign = prev_slope * slope; if(same_sign > 0.0) { next_step = fann_min(prev_step * increase_factor, delta_max); /* TODO: are the signs inverted? see differences between SARPROP paper and iRprop */ if (slope < 0.0) weights[i] += next_step; else weights[i] -= next_step; } else if(same_sign < 0.0) { if(prev_step < step_error_threshold_factor * MSE) next_step = prev_step * decrease_factor + (float)rand() / RAND_MAX * RMSE * (fann_type)fann_exp2(-T * epoch + step_error_shift); else next_step = fann_max(prev_step * decrease_factor, delta_min); slope = 0.0; } else { if(slope < 0.0) weights[i] += prev_step; else weights[i] -= prev_step; } /*if(i == 2){ * printf("weight=%f, slope=%f, next_step=%f, prev_step=%f\n", weights[i], slope, next_step, prev_step); * } */ /* update global data arrays */ prev_steps[i] = next_step; prev_train_slopes[i] = slope; train_slopes[i] = 0.0; } }
/* Cascade training directly on the training data. The connected_neurons pointers are not valid during training, but they will be again after training. */ FANN_EXTERNAL void FANN_API fann_cascadetrain_on_data(struct fann *ann, struct fann_train_data *data, unsigned int max_neurons, unsigned int neurons_between_reports, float desired_error) { float error; unsigned int i; unsigned int total_epochs = 0; int desired_error_reached; if(neurons_between_reports && ann->callback == NULL) { printf("Max neurons %3d. Desired error: %.6f\n", max_neurons, desired_error); } for(i = 1; i <= max_neurons; i++) { /* train output neurons */ total_epochs += fann_train_outputs(ann, data, desired_error); error = fann_get_MSE(ann); desired_error_reached = fann_desired_error_reached(ann, desired_error); /* print current error */ if(neurons_between_reports && (i % neurons_between_reports == 0 || i == max_neurons || i == 1 || desired_error_reached == 0)) { if(ann->callback == NULL) { printf ("Neurons %3d. Current error: %.6f. Total error:%8.4f. Epochs %5d. Bit fail %3d", i-1, error, ann->MSE_value, total_epochs, ann->num_bit_fail); if((ann->last_layer-2) != ann->first_layer) { printf(". candidate steepness %.2f. function %s", (ann->last_layer-2)->first_neuron->activation_steepness, FANN_ACTIVATIONFUNC_NAMES[(ann->last_layer-2)->first_neuron->activation_function]); } printf("\n"); } else if((*ann->callback) (ann, data, max_neurons, neurons_between_reports, desired_error, total_epochs) == -1) { /* you can break the training by returning -1 */ break; } } if(desired_error_reached == 0) break; if(fann_initialize_candidates(ann) == -1) { /* Unable to initialize room for candidates */ break; } /* train new candidates */ total_epochs += fann_train_candidates(ann, data); /* this installs the best candidate */ fann_install_candidate(ann); } /* Train outputs one last time but without any desired error */ total_epochs += fann_train_outputs(ann, data, 0.0); if(neurons_between_reports && ann->callback == NULL) { printf("Train outputs Current error: %.6f. Epochs %6d\n", fann_get_MSE(ann), total_epochs); } /* Set pointers in connected_neurons * This is ONLY done in the end of cascade training, * since there is no need for them during training. */ fann_set_shortcut_connections(ann); }