diff --git a/src/Network/NeuralNetwork.cpp b/src/Network/NeuralNetwork.cpp index ee9fb4739242b171b09f4b1edc826d3c56eae023..445c736ac54db4a99f772b0c04e878bcd370cbf6 100644 --- a/src/Network/NeuralNetwork.cpp +++ b/src/Network/NeuralNetwork.cpp @@ -8,10 +8,10 @@ #include <iostream> #include <4neuro.h> -#include "../message.h" +#include "message.h" #include "NeuralNetwork.h" #include "NeuralNetworkSerialization.h" -#include "../exceptions.h" +#include "exceptions.h" namespace lib4neuro { @@ -144,8 +144,11 @@ namespace lib4neuro { } - NeuralNetwork *NeuralNetwork::get_subnet(std::vector<size_t> &input_neuron_indices, + NeuralNetwork *NeuralNetwork::get_subnet(::std::vector<size_t> &input_neuron_indices, ::std::vector<size_t> &output_neuron_indices) { + + THROW_NOT_IMPLEMENTED_ERROR(); + NeuralNetwork *output_net = nullptr; // TODO rework due to the changed structure of the class // Neuron * active_neuron, * target_neuron; @@ -433,11 +436,11 @@ namespace lib4neuro { void NeuralNetwork::copy_parameter_space(std::vector<double> *parameters) { if (parameters != nullptr) { for (unsigned int i = 0; i < this->connection_weights->size(); ++i) { - (*this->connection_weights)[i] = (*parameters)[i]; + (*this->connection_weights).at(i) = (*parameters).at(i); } for (unsigned int i = 0; i < this->neuron_biases->size(); ++i) { - (*this->neuron_biases)[i] = (*parameters)[i + this->connection_weights->size()]; + (*this->neuron_biases).at(i) = (*parameters).at(i + this->connection_weights->size()); } } } @@ -459,7 +462,7 @@ namespace lib4neuro { this->delete_weights = false; } - void NeuralNetwork::eval_single(std::vector<double> &input, ::std::vector<double> &output, + void NeuralNetwork::eval_single(::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) { THROW_INVALID_ARGUMENT_ERROR("Input and output neurons have not been specified!"); @@ -681,26 +684,91 @@ namespace lib4neuro { } } - void NeuralNetwork::print_weights() { - printf("Connection weights: "); + void NeuralNetwork::write_weights() { + std::cout << "Connection weights: "; + if (this->connection_weights) { + for (size_t i = 0; i < this->connection_weights->size() - 1; ++i) { + std::cout << this->connection_weights->at(i) << ", "; + } + std::cout << this->connection_weights->at(this->connection_weights->size() - 1) << std::endl; + } + } + + void NeuralNetwork::write_weights(std::string file_path) { + std::ofstream ofs(file_path); + + if(!ofs.is_open()) { + THROW_RUNTIME_ERROR("File " + file_path + " can not be opened!"); + } + + ofs << "Connection weights: "; + + if (this->connection_weights) { + for (size_t i = 0; i < this->connection_weights->size() - 1; ++i) { + ofs << this->connection_weights->at(i) << ", "; + } + ofs << this->connection_weights->at(this->connection_weights->size() - 1) << std::endl; + } + } + + void NeuralNetwork::write_weights(std::ofstream* file_path) { + *file_path << "Connection weights: "; + if (this->connection_weights) { for (size_t i = 0; i < this->connection_weights->size() - 1; ++i) { - printf("%f, ", this->connection_weights->at(i)); + *file_path << this->connection_weights->at(i) << ", "; } - printf("%f", this->connection_weights->at(this->connection_weights->size() - 1)); + *file_path << this->connection_weights->at(this->connection_weights->size() - 1) << std::endl; } + } - printf("\n"); + 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) << ", "; + } + std::cout << this->neuron_biases->at(this->neuron_biases->size() - 1) << std::endl; + } } - void NeuralNetwork::print_stats() { + void NeuralNetwork::write_biases(std::string file_path) { + std::ofstream ofs(file_path); + + if(!ofs.is_open()) { + THROW_RUNTIME_ERROR("File " + file_path + " can not be opened!"); + } + + 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) << ", "; + } + 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) << ", "; + } + *file_path << this->neuron_biases->at(this->neuron_biases->size() - 1) << std::endl; + } + } + + void NeuralNetwork::write_stats() { ::std::cout << "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; if(this->normalization_strategy) { - ::std::cout << "Normalization stratey maximum value: " + ::std::cout << "Normalization strategy maximum value: " << this->normalization_strategy->get_max_value() << std::endl << "Normalization strategy minimum value: " << this->normalization_strategy->get_min_value() @@ -708,6 +776,44 @@ namespace lib4neuro { } } + void NeuralNetwork::write_stats(std::string file_path) { + std::ofstream ofs(file_path); + + if(!ofs.is_open()) { + THROW_RUNTIME_ERROR("File " + file_path + " can not be opened!"); + } + + 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; + + if(this->normalization_strategy) { + ofs << "Normalization strategy maximum value: " + << this->normalization_strategy->get_max_value() << std::endl + << "Normalization strategy minimum value: " + << this->normalization_strategy->get_min_value() + << std::endl; + } + + ofs.close(); + } + + void NeuralNetwork::write_stats(std::ofstream* file_path) { + *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; + + if(this->normalization_strategy) { + *file_path << "Normalization strategy maximum value: " + << this->normalization_strategy->get_max_value() << std::endl + << "Normalization strategy minimum value: " + << this->normalization_strategy->get_min_value() + << std::endl; + } + } + std::vector<double> *NeuralNetwork::get_parameter_ptr_biases() { return this->neuron_biases; } @@ -929,9 +1035,9 @@ namespace lib4neuro { unsigned int inp_dim = neuron_numbers->at(0); //!< Network input dimension unsigned int out_dim = neuron_numbers->back(); //!< Network output dimension - COUT_DEBUG(<< "Fully connected feed-forward network:" << std::endl) - COUT_DEBUG(<< "# of inputs: " << inp_dim << std::endl); - COUT_DEBUG(<< "# of outputs: " << out_dim << std::endl); + COUT_DEBUG("Fully connected feed-forward network being constructed:" << std::endl); + COUT_DEBUG("# of inputs: " << inp_dim << std::endl); + COUT_DEBUG("# of outputs: " << out_dim << std::endl); std::vector<size_t> input_layer_neuron_indices; std::vector<size_t> previous_layer_neuron_indices; @@ -947,9 +1053,8 @@ namespace lib4neuro { input_layer_neuron_indices = current_layer_neuron_indices; /* Creation of HIDDEN layers */ - for(unsigned int i = 1; i <= neuron_numbers->size()-2; i++) { - COUT_DEBUG(<< "Hidden layer #d: " << neuron_numbers->at(i) << " neurons" << std::endl); + COUT_DEBUG("Hidden layer #" << i << ": " << neuron_numbers->at(i) << " neurons" << std::endl); previous_layer_neuron_indices.reserve(neuron_numbers->at(i-1)); previous_layer_neuron_indices = current_layer_neuron_indices; current_layer_neuron_indices.clear(); @@ -967,7 +1072,7 @@ namespace lib4neuro { } case NEURON_TYPE::CONSTANT: { - neuron_id = this->add_neuron(new NeuronConstant, BIAS_TYPE::NEXT_BIAS); + THROW_INVALID_ARGUMENT_ERROR("Constant neurons can't be used in fully connected feed-forward networks!"); break; } diff --git a/src/Network/NeuralNetwork.h b/src/Network/NeuralNetwork.h index 598833aa1c890d934d20cb27701d3cc34483f1aa..ba0e7aea6559861171827b54dd21c2813b9afe4d 100644 --- a/src/Network/NeuralNetwork.h +++ b/src/Network/NeuralNetwork.h @@ -332,12 +332,52 @@ namespace lib4neuro { /** * */ - LIB4NEURO_API void print_weights(); + LIB4NEURO_API void write_weights(); /** * */ - LIB4NEURO_API void print_stats(); + LIB4NEURO_API void write_weights(std::string file_path); + + /** + * + * @param file_path + */ + LIB4NEURO_API void write_weights(std::ofstream* file_path); + + /** + * + */ + LIB4NEURO_API void write_biases(); + + /** + * + * @param file_name + */ + LIB4NEURO_API void write_biases(std::string file_path); + + /** + * + * @param file_path + */ + LIB4NEURO_API void write_biases(std::ofstream* file_path); + + /** + * + */ + LIB4NEURO_API void write_stats(); + + /** + * + * @param file_path + */ + LIB4NEURO_API void write_stats(std::string file_path); + + /** + * + * @param file_path + */ + LIB4NEURO_API void write_stats(std::ofstream* file_path); /** *