diff --git a/src/Network/NeuralNetwork.cpp b/src/Network/NeuralNetwork.cpp index b2e00d76142ffbd121331a99b21532f6f4569fde..e0e2cb760f812908b4936e4d58c719b534dbdd89 100644 --- a/src/Network/NeuralNetwork.cpp +++ b/src/Network/NeuralNetwork.cpp @@ -18,8 +18,8 @@ namespace lib4neuro { NeuralNetwork::NeuralNetwork() { this->neurons = new ::std::vector<Neuron *>(0); - this->neuron_biases = new ::std::vector<double>(0); - this->neuron_bias_indices = new ::std::vector<int>(0); +// this->neuron_biases = new ::std::vector<double>(0); +// this->neuron_bias_indices = new ::std::vector<int>(0); // this->connection_weights = new ::std::vector<double>(0); // this->connection_list = ::std::vector<std::shared_ptr<ConnectionFunctionGeneral>>(0); @@ -29,8 +29,8 @@ namespace lib4neuro { this->neuron_layers_feedforward = new ::std::vector<std::vector<size_t> *>(0); this->neuron_layers_feedbackward = new ::std::vector<std::vector<size_t> *>(0); - this->input_neuron_indices = new ::std::vector<size_t>(0); - this->output_neuron_indices = new ::std::vector<size_t>(0); +// this->input_neuron_indices = new ::std::vector<size_t>(0); +// this->output_neuron_indices = new ::std::vector<size_t>(0); this->delete_weights = true; this->delete_biases = true; @@ -65,35 +65,35 @@ namespace lib4neuro { this->neurons = nullptr; } - if (this->neuron_potentials) { - delete this->neuron_potentials; - this->neuron_potentials = nullptr; - } - - if (this->neuron_bias_indices) { - delete this->neuron_bias_indices; - this->neuron_bias_indices = nullptr; - } - - if (this->output_neuron_indices) { - delete this->output_neuron_indices; - this->output_neuron_indices = nullptr; - } - - if (this->input_neuron_indices) { - delete this->input_neuron_indices; - this->input_neuron_indices = nullptr; - } +// if (this->neuron_potentials) { +// delete this->neuron_potentials; +// this->neuron_potentials = nullptr; +// } +// +// if (this->neuron_bias_indices) { +// delete this->neuron_bias_indices; +// this->neuron_bias_indices = nullptr; +// } +// +// if (this->output_neuron_indices) { +// delete this->output_neuron_indices; +// this->output_neuron_indices = nullptr; +// } +// +// if (this->input_neuron_indices) { +// delete this->input_neuron_indices; +// this->input_neuron_indices = nullptr; +// } // if (this->connection_weights && this->delete_weights) { // delete this->connection_weights; // this->connection_weights = nullptr; // } - if (this->neuron_biases && this->delete_biases) { - delete this->neuron_biases; - this->neuron_biases = nullptr; - } +// if (this->neuron_biases && this->delete_biases) { +// delete this->neuron_biases; +// this->neuron_biases = nullptr; +// } // if (this->connection_list) { // @@ -390,15 +390,15 @@ namespace lib4neuro { size_t NeuralNetwork::add_neuron(Neuron *n, BIAS_TYPE bt, size_t bias_idx) { if (bt == BIAS_TYPE::NO_BIAS) { - this->neuron_bias_indices->push_back(-1); + this->neuron_bias_indices.push_back(-1); } else if (bt == BIAS_TYPE::NEXT_BIAS) { - this->neuron_bias_indices->push_back((int) this->neuron_biases->size()); - this->neuron_biases->resize(this->neuron_biases->size() + 1); + this->neuron_bias_indices.push_back((int) this->neuron_biases.size()); + this->neuron_biases.resize(this->neuron_biases.size() + 1); } else if (bt == BIAS_TYPE::EXISTING_BIAS) { - if (bias_idx >= this->neuron_biases->size()) { + if (bias_idx >= this->neuron_biases.size()) { ::std::cerr << "The supplied bias index is too large!\n" << ::std::endl; } - this->neuron_bias_indices->push_back((int) bias_idx); + this->neuron_bias_indices.push_back((int) bias_idx); } this->outward_adjacency->push_back(new ::std::vector<std::pair<size_t, size_t>>(0)); @@ -412,15 +412,15 @@ namespace lib4neuro { void NeuralNetwork::eval_single_debug(::std::vector<double> &input, ::std::vector<double> &output, ::std::vector<double> *custom_weights_and_biases) { - if ((this->input_neuron_indices->size() * this->output_neuron_indices->size()) <= 0) { + if ((this->input_neuron_indices.size() * this->output_neuron_indices.size()) <= 0) { THROW_INVALID_ARGUMENT_ERROR("Input and output neurons have not been specified!"); } - if (this->input_neuron_indices->size() != input.size()) { + if (this->input_neuron_indices.size() != input.size()) { THROW_INVALID_ARGUMENT_ERROR("Data input size != Network input size"); } - if (this->output_neuron_indices->size() != output.size()) { + if (this->output_neuron_indices.size() != output.size()) { THROW_INVALID_ARGUMENT_ERROR("Data output size != Network output size"); } @@ -433,12 +433,12 @@ namespace lib4neuro { /* reset of the output and the neuron potentials */ ::std::fill(output.begin(), output.end(), 0.0); - ::std::fill(this->neuron_potentials->begin(), this->neuron_potentials->end(), 0.0); + ::std::fill(this->neuron_potentials.begin(), this->neuron_potentials.end(), 0.0); /* set the potentials of the input neurons */ - for (size_t i = 0; i < this->input_neuron_indices->size(); ++i) { - this->neuron_potentials->at(this->input_neuron_indices->at(i)) = input[i]; - std::cout << this->neuron_potentials->at(this->input_neuron_indices->at(i)) << ", "; + for (size_t i = 0; i < this->input_neuron_indices.size(); ++i) { + this->neuron_potentials.at(this->input_neuron_indices.at(i)) = input[i]; + std::cout << this->neuron_potentials.at(this->input_neuron_indices.at(i)) << ", "; } std::cout << std::endl; @@ -450,18 +450,18 @@ namespace lib4neuro { for (auto si: *layer) { bias = 0.0; - bias_idx = this->neuron_bias_indices->at(si); + bias_idx = this->neuron_bias_indices.at(si); if (bias_idx >= 0) { - bias = this->neuron_biases->at(bias_idx); + bias = this->neuron_biases.at(bias_idx); } - potential = this->neurons->at(si)->activate(this->neuron_potentials->at(si), bias); - std::cout << " applying bias: " << bias << " to neuron potential: " << this->neuron_potentials->at(si) << " -> " << potential << std::endl; + potential = this->neurons->at(si)->activate(this->neuron_potentials.at(si), bias); + std::cout << " applying bias: " << bias << " to neuron potential: " << this->neuron_potentials.at(si) << " -> " << potential << std::endl; for (auto c: *this->outward_adjacency->at(si)) { size_t ti = c.first; size_t ci = c.second; - this->neuron_potentials->at(ti) += + this->neuron_potentials.at(ti) += this->connection_list.at(ci)->eval(this->connection_weights) * potential; std::cout << " adding input to neuron " << ti << " += " << this->connection_list.at(ci)->eval(this->connection_weights) << "*" << potential << std::endl; @@ -470,13 +470,13 @@ namespace lib4neuro { } unsigned int i = 0; - for (auto oi: *this->output_neuron_indices) { + for (auto oi: this->output_neuron_indices) { bias = 0.0; - bias_idx = this->neuron_bias_indices->at(oi); + bias_idx = this->neuron_bias_indices.at(oi); if (bias_idx >= 0) { - bias = this->neuron_biases->at(bias_idx); + bias = this->neuron_biases.at(bias_idx); } - output[i] = this->neurons->at(oi)->activate(this->neuron_potentials->at(oi), bias); + output[i] = this->neurons->at(oi)->activate(this->neuron_potentials.at(oi), bias); std::cout << "setting the output[" << i << "] = " << output[i] << "(bias = " << bias << ")" << std::endl; ++i; } @@ -548,8 +548,8 @@ namespace lib4neuro { this->connection_weights.at(i) = (*parameters).at(i); } - for (unsigned int i = 0; i < this->neuron_biases->size(); ++i) { - (*this->neuron_biases).at(i) = (*parameters).at(i + this->connection_weights.size()); + for (unsigned int i = 0; i < this->neuron_biases.size(); ++i) { + (this->neuron_biases).at(i) = (*parameters).at(i + this->connection_weights.size()); } } } @@ -561,9 +561,10 @@ namespace lib4neuro { this->connection_weights.clear(); } - if (this->neuron_biases) { - delete this->neuron_biases; - } + this->neuron_biases.clear(); +// if (this->neuron_biases) { +// delete this->neuron_biases; +// } this->connection_weights = parent_network.connection_weights; this->neuron_biases = parent_network.neuron_biases; @@ -576,15 +577,15 @@ namespace lib4neuro { ::std::vector<double>& output, ::std::vector<double>* custom_weights_and_biases) { - if ((this->input_neuron_indices->size() * this->output_neuron_indices->size()) <= 0) { + if ((this->input_neuron_indices.size() * this->output_neuron_indices.size()) <= 0) { THROW_INVALID_ARGUMENT_ERROR("Input and output neurons have not been specified!"); } - if (this->input_neuron_indices->size() != input.size()) { + if (this->input_neuron_indices.size() != input.size()) { THROW_INVALID_ARGUMENT_ERROR("Data input size != Network input size"); } - if (this->output_neuron_indices->size() != output.size()) { + if (this->output_neuron_indices.size() != output.size()) { THROW_INVALID_ARGUMENT_ERROR("Data output size != Network output size"); } @@ -597,11 +598,11 @@ namespace lib4neuro { /* reset of the output and the neuron potentials */ ::std::fill(output.begin(), output.end(), 0.0); - ::std::fill(this->neuron_potentials->begin(), this->neuron_potentials->end(), 0.0); + ::std::fill(this->neuron_potentials.begin(), this->neuron_potentials.end(), 0.0); /* set the potentials of the input neurons */ - for (size_t i = 0; i < this->input_neuron_indices->size(); ++i) { - this->neuron_potentials->at(this->input_neuron_indices->at(i)) = input[i]; + for (size_t i = 0; i < this->input_neuron_indices.size(); ++i) { + this->neuron_potentials.at(this->input_neuron_indices.at(i)) = input[i]; } /* we iterate through all the feed-forward layers and transfer the signals */ @@ -610,30 +611,30 @@ namespace lib4neuro { for (auto si: *layer) { bias = 0.0; - bias_idx = this->neuron_bias_indices->at(si); + bias_idx = this->neuron_bias_indices.at(si); if (bias_idx >= 0) { - bias = this->neuron_biases->at(bias_idx); + bias = this->neuron_biases.at(bias_idx); } - potential = this->neurons->at(si)->activate(this->neuron_potentials->at(si), bias); + potential = this->neurons->at(si)->activate(this->neuron_potentials.at(si), bias); for (auto c: *this->outward_adjacency->at(si)) { size_t ti = c.first; size_t ci = c.second; - this->neuron_potentials->at(ti) += + this->neuron_potentials.at(ti) += this->connection_list.at(ci)->eval(this->connection_weights) * potential; } } } unsigned int i = 0; - for (auto oi: *this->output_neuron_indices) { + for (auto oi: this->output_neuron_indices) { bias = 0.0; - bias_idx = this->neuron_bias_indices->at(oi); + bias_idx = this->neuron_bias_indices.at(oi); if (bias_idx >= 0) { - bias = this->neuron_biases->at(bias_idx); + bias = this->neuron_biases.at(bias_idx); } - output[i] = this->neurons->at(oi)->activate(this->neuron_potentials->at(oi), bias); + output[i] = this->neurons->at(oi)->activate(this->neuron_potentials.at(oi), bias); ++i; } } @@ -671,11 +672,11 @@ namespace lib4neuro { active_neuron = dynamic_cast<NeuronDifferentiable *> (this->neurons->at(neuron_idx)); if (active_neuron) { - bias_idx = this->neuron_bias_indices->at(neuron_idx); - neuron_potential = this->neuron_potentials->at(neuron_idx); + bias_idx = this->neuron_bias_indices.at(neuron_idx); + neuron_potential = this->neuron_potentials.at(neuron_idx); if (bias_idx >= 0) { - neuron_bias = this->neuron_biases->at(bias_idx); + neuron_bias = this->neuron_biases.at(bias_idx); gradient[bias_shift + bias_idx] += scaling_backprog[neuron_idx] * active_neuron->activation_function_eval_derivative_bias( neuron_potential, neuron_bias); @@ -746,11 +747,11 @@ namespace lib4neuro { if (active_neuron) { std::cout << " [backpropagation] active neuron: " << neuron_idx << std::endl; - bias_idx = this->neuron_bias_indices->at(neuron_idx); - neuron_potential = this->neuron_potentials->at(neuron_idx); + bias_idx = this->neuron_bias_indices.at(neuron_idx); + neuron_potential = this->neuron_potentials.at(neuron_idx); if (bias_idx >= 0) { - neuron_bias = this->neuron_biases->at(bias_idx); + neuron_bias = this->neuron_biases.at(bias_idx); gradient[bias_shift + bias_idx] += scaling_backprog[neuron_idx] * active_neuron->activation_function_eval_derivative_bias( neuron_potential, neuron_bias); @@ -808,8 +809,8 @@ namespace lib4neuro { // Init weight guess ("optimal" for logistic activation functions) boost::random::uniform_real_distribution<> dist(-1, 1); - for (size_t i = 0; i < this->neuron_biases->size(); i++) { - this->neuron_biases->at(i) = dist(gen); + for (size_t i = 0; i < this->neuron_biases.size(); i++) { + this->neuron_biases.at(i) = dist(gen); } } @@ -820,7 +821,7 @@ namespace lib4neuro { void NeuralNetwork::scale_biases(double alpha) { for(size_t i = 0; i < this->get_n_biases(); ++i){ - this->neuron_biases->at( i ) *= alpha; + this->neuron_biases.at( i ) *= alpha; } } @@ -836,11 +837,11 @@ namespace lib4neuro { } size_t NeuralNetwork::get_n_inputs() { - return this->input_neuron_indices->size(); + return this->input_neuron_indices.size(); } size_t NeuralNetwork::get_n_outputs() { - return this->output_neuron_indices->size(); + return this->output_neuron_indices.size(); } size_t NeuralNetwork::get_n_weights() { @@ -848,11 +849,11 @@ namespace lib4neuro { } size_t NeuralNetwork::get_n_biases() { - return this->neuron_biases->size(); + return this->neuron_biases.size(); } int NeuralNetwork::get_neuron_bias_index(size_t neuron_idx) { - return this->neuron_bias_indices->at(neuron_idx); + return this->neuron_bias_indices.at(neuron_idx); } size_t NeuralNetwork::get_n_neurons() { @@ -860,21 +861,24 @@ namespace lib4neuro { } void NeuralNetwork::specify_input_neurons(std::vector<size_t> &input_neurons_indices) { - if (!this->input_neuron_indices) { - this->input_neuron_indices = new ::std::vector<size_t>(input_neurons_indices); - } else { - delete this->input_neuron_indices; - this->input_neuron_indices = new ::std::vector<size_t>(input_neurons_indices); - } + this->input_neuron_indices = input_neurons_indices; + +// if (!this->input_neuron_indices) { +// this->input_neuron_indices = new ::std::vector<size_t>(input_neurons_indices); +// } else { +// delete this->input_neuron_indices; +// this->input_neuron_indices = new ::std::vector<size_t>(input_neurons_indices); +// } } void NeuralNetwork::specify_output_neurons(std::vector<size_t> &output_neurons_indices) { - if (!this->output_neuron_indices) { - this->output_neuron_indices = new ::std::vector<size_t>(output_neurons_indices); - } else { - delete this->output_neuron_indices; - this->output_neuron_indices = new ::std::vector<size_t>(output_neurons_indices); - } + this->output_neuron_indices = output_neurons_indices; +// if (!this->output_neuron_indices) { +// this->output_neuron_indices = new ::std::vector<size_t>(output_neurons_indices); +// } else { +// delete this->output_neuron_indices; +// this->output_neuron_indices = new ::std::vector<size_t>(output_neurons_indices); +// } } void NeuralNetwork::write_weights() { @@ -918,11 +922,11 @@ namespace lib4neuro { void NeuralNetwork::write_biases() { std::cout << "Network biases: "; - if(this->neuron_biases) { - for(unsigned int i = 0; i < this->neuron_biases->size() - 1; i++) { - std::cout << this->neuron_biases->at(i) << ", "; + if(!this->neuron_biases.empty()) { + for(unsigned int i = 0; i < this->neuron_biases.size() - 1; i++) { + std::cout << this->neuron_biases.at(i) << ", "; } - std::cout << this->neuron_biases->at(this->neuron_biases->size() - 1) << std::endl; + std::cout << this->neuron_biases.at(this->neuron_biases.size() - 1) << std::endl; } } @@ -935,22 +939,22 @@ namespace lib4neuro { ofs << "Network biases: "; - if(this->neuron_biases) { - for(unsigned int i = 0; i < this->neuron_biases->size() - 1; i++) { - ofs << this->neuron_biases->at(i) << ", "; + if(!this->neuron_biases.empty()) { + for(unsigned int i = 0; i < this->neuron_biases.size() - 1; i++) { + ofs << this->neuron_biases.at(i) << ", "; } - ofs << this->neuron_biases->at(this->neuron_biases->size() - 1) << std::endl; + ofs << this->neuron_biases.at(this->neuron_biases.size() - 1) << std::endl; } } void NeuralNetwork::write_biases(std::ofstream* file_path) { *file_path << "Network biases: "; - if(this->neuron_biases) { - for(unsigned int i = 0; i < this->neuron_biases->size() - 1; i++) { - *file_path << this->neuron_biases->at(i) << ", "; + if(!this->neuron_biases.empty()) { + for(unsigned int i = 0; i < this->neuron_biases.size() - 1; i++) { + *file_path << this->neuron_biases.at(i) << ", "; } - *file_path << this->neuron_biases->at(this->neuron_biases->size() - 1) << std::endl; + *file_path << this->neuron_biases.at(this->neuron_biases.size() - 1) << std::endl; } } @@ -959,7 +963,7 @@ namespace lib4neuro { << "Number of neurons: " << this->neurons->size() << ::std::endl << "Number of connections: " << this->connection_list.size() << ::std::endl << "Number of active weights: " << this->connection_weights.size() << ::std::endl - << "Number of active biases: " << this->neuron_biases->size() << ::std::endl; + << "Number of active biases: " << this->neuron_biases.size() << ::std::endl; if(this->normalization_strategy) { ::std::cout << std::flush @@ -981,7 +985,7 @@ namespace lib4neuro { ofs << "Number of neurons: " << this->neurons->size() << ::std::endl << "Number of connections: " << this->connection_list.size() << ::std::endl << "Number of active weights: " << this->connection_weights.size() << ::std::endl - << "Number of active biases: " << this->neuron_biases->size() << ::std::endl; + << "Number of active biases: " << this->neuron_biases.size() << ::std::endl; if(this->normalization_strategy) { ofs << "Normalization strategy maximum value: " @@ -998,7 +1002,7 @@ namespace lib4neuro { *file_path << "Number of neurons: " << this->neurons->size() << ::std::endl << "Number of connections: " << this->connection_list.size() << ::std::endl << "Number of active weights: " << this->connection_weights.size() << ::std::endl - << "Number of active biases: " << this->neuron_biases->size() << ::std::endl; + << "Number of active biases: " << this->neuron_biases.size() << ::std::endl; if(this->normalization_strategy) { *file_path << "Normalization strategy maximum value: " @@ -1010,7 +1014,7 @@ namespace lib4neuro { } std::vector<double>* NeuralNetwork::get_parameter_ptr_biases() { - return this->neuron_biases; + return &this->neuron_biases; } std::vector<double>* NeuralNetwork::get_parameter_ptr_weights() { @@ -1049,7 +1053,7 @@ namespace lib4neuro { } /* buffer preparation */ - this->neuron_potentials->resize(this->get_n_neurons()); + this->neuron_potentials.resize(this->get_n_neurons()); /* space allocation */ if (this->neuron_layers_feedforward) { @@ -1104,7 +1108,7 @@ namespace lib4neuro { active_set_size[0] = this->get_n_inputs(); size_t i = 0; for (i = 0; i < this->get_n_inputs(); ++i) { - active_eval_set[i] = this->input_neuron_indices->at(i); + active_eval_set[i] = this->input_neuron_indices.at(i); } size_t active_ni; @@ -1149,7 +1153,7 @@ namespace lib4neuro { // // active_set_size[0] = this->get_n_outputs(); // for(i = 0; i < this->get_n_outputs(); ++i){ -// active_eval_set[i] = this->output_neuron_indices->at(i); +// active_eval_set[i] = this->output_neuron_indices.at(i); // } // // while(active_set_size[idx1] > 0){ @@ -1233,9 +1237,9 @@ namespace lib4neuro { } this->neurons = new ::std::vector<Neuron *>(0); - this->neuron_biases = new ::std::vector<double>(0); - this->neuron_potentials = new ::std::vector<double>(0); - this->neuron_bias_indices = new ::std::vector<int>(0); +// this->neuron_biases = new ::std::vector<double>(0); +// this->neuron_potentials = new ::std::vector<double>(0); +// this->neuron_bias_indices = new ::std::vector<int>(0); // this->connection_weights = new ::std::vector<double>(0); this->connection_list = ::std::vector<std::shared_ptr<ConnectionFunctionGeneral>>(0); @@ -1245,8 +1249,8 @@ namespace lib4neuro { this->neuron_layers_feedforward = new ::std::vector<std::vector<size_t> *>(0); this->neuron_layers_feedbackward = new ::std::vector<std::vector<size_t> *>(0); - this->input_neuron_indices = new ::std::vector<size_t>(0); - this->output_neuron_indices = new ::std::vector<size_t>(0); +// this->input_neuron_indices = new ::std::vector<size_t>(0); +// this->output_neuron_indices = new ::std::vector<size_t>(0); this->delete_weights = true; this->delete_biases = true; @@ -1344,11 +1348,11 @@ namespace lib4neuro { } /* Init variables containing indices of INPUT nad OUTPUT neurons */ - this->input_neuron_indices = new ::std::vector<size_t>(inp_dim); - this->output_neuron_indices = new ::std::vector<size_t>(out_dim); +// this->input_neuron_indices = new ::std::vector<size_t>(inp_dim); +// this->output_neuron_indices = new ::std::vector<size_t>(out_dim); - *this->input_neuron_indices = input_layer_neuron_indices; - *this->output_neuron_indices = current_layer_neuron_indices; + this->input_neuron_indices = input_layer_neuron_indices; + this->output_neuron_indices = current_layer_neuron_indices; this->analyze_layer_structure(); } diff --git a/src/Network/NeuralNetwork.h b/src/Network/NeuralNetwork.h index 9f69eb331cf787f38d0d1801c7eadb305632463a..ad2d36f351501d1f657ca0fc31595e3889335251 100644 --- a/src/Network/NeuralNetwork.h +++ b/src/Network/NeuralNetwork.h @@ -60,12 +60,12 @@ namespace lib4neuro { /** * */ - std::vector<size_t> *input_neuron_indices = nullptr; + std::vector<size_t> input_neuron_indices; // = nullptr; /** * */ - std::vector<size_t> *output_neuron_indices = nullptr; + std::vector<size_t> output_neuron_indices; // = nullptr; /** * @@ -75,17 +75,17 @@ namespace lib4neuro { /** * */ - std::vector<double> *neuron_biases = nullptr; + std::vector<double> neuron_biases; // = nullptr; /** * */ - std::vector<int> *neuron_bias_indices = nullptr; + std::vector<int> neuron_bias_indices; // = nullptr; /** * */ - std::vector<double> *neuron_potentials = nullptr; + std::vector<double> neuron_potentials; // = nullptr; /** *