diff --git a/machine_learning/neural_network.cpp b/machine_learning/neural_network.cpp index 01c4f3891..ba9df5335 100644 --- a/machine_learning/neural_network.cpp +++ b/machine_learning/neural_network.cpp @@ -171,8 +171,8 @@ namespace machine_learning { } else { // If supplied activation is invalid - std::cerr << "ERROR: Invalid argument for layer -> constructor -> activation, "; - std::cerr << "Expected from {none, sigmoid, relu, tanh} got "; + std::cerr << "ERROR (" << __func__ << ") : "; + std::cerr << "Invalid argument. Expected {none, sigmoid, relu, tanh} got "; std::cerr << activation << std::endl; std::exit(EXIT_FAILURE); } @@ -215,8 +215,8 @@ namespace machine_learning { } else { // If supplied activation is invalid - std::cerr << "ERROR: Invalid argument for layer -> constructor -> activation, "; - std::cerr << "Expected from {none, sigmoid, relu, tanh} got "; + std::cerr << "ERROR (" << __func__ << ") : "; + std::cerr << "Invalid argument. Expected {none, sigmoid, relu, tanh} got "; std::cerr << activation << std::endl; std::exit(EXIT_FAILURE); } @@ -271,13 +271,15 @@ namespace machine_learning { const std::vector >> &kernals) { // First layer should not have activation if(config.begin() -> second != "none") { - std::cerr << "ERROR: First layer can't have activation other than none"; + std::cerr << "ERROR (" << __func__ << ") : "; + std::cerr << "First layer can't have activation other than none got " << config.begin() -> second; std::cerr << std::endl; std::exit(EXIT_FAILURE); } // Network should have atleast two layers if(config.size() <= 1) { - std::cerr << "ERROR: Invalid size of network, "; + std::cerr << "ERROR (" << __func__ << ") : "; + std::cerr << "Invalid size of network, "; std::cerr << "Atleast two layers are required"; std::exit(EXIT_FAILURE); } @@ -322,13 +324,15 @@ namespace machine_learning { explicit NeuralNetwork(const std::vector > &config) { // First layer should not have activation if(config.begin() -> second != "none") { - std::cerr << "ERROR: First layer can't have activation other than none"; + std::cerr << "ERROR (" << __func__ << ") : "; + std::cerr << "First layer can't have activation other than none got " << config.begin() -> second; std::cerr << std::endl; std::exit(EXIT_FAILURE); } // Network should have atleast two layers if(config.size() <= 1) { - std::cerr << "ERROR: Invalid size of network, "; + std::cerr << "ERROR (" << __func__ << ") : "; + std::cerr << "Invalid size of network, "; std::cerr << "Atleast two layers are required"; std::exit(EXIT_FAILURE); } @@ -392,7 +396,8 @@ namespace machine_learning { in_file.open(file_name.c_str(), std::ios::in); // Open file // If there is any problem in opening file if(!in_file.is_open()) { - std::cerr << "ERROR: Unable to open file: "<< file_name << std::endl; + std::cerr << "ERROR (" << __func__ << ") : "; + std::cerr << "Unable to open file: "<< file_name << std::endl; std::exit(EXIT_FAILURE); } std::vector >> X, Y; // To store X and Y @@ -440,12 +445,12 @@ namespace machine_learning { X.push_back({x_data}); Y.push_back({y_data}); } - in_file.close(); // Normalize training data if flag is set if(normalize) { // Scale data between 0 and 1 using min-max scaler X = minmax_scaler(X, 0.01, 1.0); } + in_file.close(); // Closing file return make_pair(X, Y); // Return pair of X and Y } @@ -496,7 +501,8 @@ namespace machine_learning { std::vector < std::vector >> X = X_, Y = Y_; // Both label and input data should have same size if (X.size() != Y.size()) { - std::cerr << "ERROR : X and Y in fit have different sizes" << std::endl; + std::cerr << "ERROR (" << __func__ << ") : "; + std::cerr << "X and Y in fit have different sizes" << std::endl; std::exit(EXIT_FAILURE); } std::cout << "INFO: Training Started" << std::endl; @@ -652,7 +658,8 @@ namespace machine_learning { out_file.open(file_name.c_str(), std::ofstream::out | std::ofstream::trunc); // If there is any problem in opening file if(!out_file.is_open()) { - std::cerr << "ERROR: Unable to open file: "<< file_name << std::endl; + std::cerr << "ERROR (" << __func__ << ") : "; + std::cerr << "Unable to open file: "<< file_name << std::endl; std::exit(EXIT_FAILURE); } /** @@ -710,6 +717,7 @@ namespace machine_learning { } std::cout << "INFO: Model saved successfully with name : "; std::cout << file_name << std::endl; + out_file.close(); // Closing file return; } @@ -723,7 +731,8 @@ namespace machine_learning { in_file.open(file_name.c_str()); // Openinig file // If there is any problem in opening file if(!in_file.is_open()) { - std::cerr << "ERROR: Unable to open file: "<< file_name << std::endl; + std::cerr << "ERROR (" << __func__ << ") : "; + std::cerr << "Unable to open file: "<< file_name << std::endl; std::exit(EXIT_FAILURE); } std::vector > config; // To store config @@ -748,6 +757,7 @@ namespace machine_learning { kernals.emplace_back(kernal); } std::cout << "INFO: Model loaded successfully" << std::endl; + in_file.close(); // Closing file return NeuralNetwork(config, kernals); // Return instance of NeuralNetwork class } @@ -791,9 +801,9 @@ static void test() { // Training Model myNN.fit_from_csv("iris.csv", true, 100, 0.3, false, 2, 32, true); // Testing predictions of model - assert(machine_learning::argmax(myNN.single_predict({{5,3.4,1.6,0.4}})) == 0); - assert(machine_learning::argmax(myNN.single_predict({{6.4,2.9,4.3,1.3}})) == 1); - assert(machine_learning::argmax(myNN.single_predict({{6.2,3.4,5.4,2.3}})) == 2); + assert(machine_learning::argmax(myNN.single_predict({{5, 3.4, 1.6, 0.4}})) == 0); + assert(machine_learning::argmax(myNN.single_predict({{6.4, 2.9, 4.3, 1.3}})) == 1); + assert(machine_learning::argmax(myNN.single_predict({{6.2, 3.4, 5.4, 2.3}})) == 2); return; } diff --git a/machine_learning/vector_ops.hpp b/machine_learning/vector_ops.hpp index bb70b5c4f..84e209a89 100644 --- a/machine_learning/vector_ops.hpp +++ b/machine_learning/vector_ops.hpp @@ -34,9 +34,9 @@ std::ostream &operator<<(std::ostream &out, out.precision(4); for(const auto &a : A) { // For each row in A for(const auto &x : a) { // For each element in row - std::cerr << x << ' '; // print element + std::cout << x << ' '; // print element } - std::cerr << std::endl; + std::cout << std::endl; } return out; } @@ -52,7 +52,7 @@ std::ostream &operator<<(std::ostream &out, const std::pair &A) { // Setting output precision to 4 in case of floating point numbers out.precision(4); // printing pair in the form (p, q) - std::cerr << "(" << A.first << ", " << A.second << ")"; + std::cout << "(" << A.first << ", " << A.second << ")"; return out; } @@ -67,9 +67,9 @@ std::ostream &operator<<(std::ostream &out, const std::valarray &A) { // Setting output precision to 4 in case of floating point numbers out.precision(4); for(const auto &a : A) { // For every element in the vector. - std::cerr << a << ' '; // Print element + std::cout << a << ' '; // Print element } - std::cerr << std::endl; + std::cout << std::endl; return out; } @@ -135,7 +135,8 @@ void equal_shuffle(std::vector < std::vector > > &A, // If two vectors have different sizes if(A.size() != B.size()) { - std::cerr << "ERROR : Can not equally shuffle two vectors with different sizes: "; + std::cerr << "ERROR (" << __func__ << ") : "; + std::cerr << "Can not equally shuffle two vectors with different sizes: "; std::cerr << A.size() << " and " << B.size() << std::endl; std::exit(EXIT_FAILURE); } @@ -245,7 +246,8 @@ std::pair get_shape(const std::vector> &A) { for(const auto &a : A) { // If supplied vector don't have same shape in all rows if(a.size() != sub_size) { - std::cerr << "ERROR: (get_shape) Supplied vector is not 2D Matrix" << std::endl; + std::cerr << "ERROR (" << __func__ << ") : "; + std::cerr << "Supplied vector is not 2D Matrix" << std::endl; std::exit(EXIT_FAILURE); } } @@ -267,7 +269,8 @@ minmax_scaler(const std::vector>> &A, const T &low, const auto shape = get_shape(B[0]); // Storing shape of B's every element // As this function is used for scaling training data vector should be of shape (1, X) if(shape.first != 1) { - std::cerr << "ERROR: (MinMax Scaling) Supplied vector is not supported for minmax scaling, shape: "; + std::cerr << "ERROR (" << __func__ << ") : "; + std::cerr << "Supplied vector is not supported for minmax scaling, shape: "; std::cerr << shape << std::endl; std::exit(EXIT_FAILURE); } @@ -297,7 +300,8 @@ size_t argmax(const std::vector> &A) { const auto shape = get_shape(A); // As this function is used on predicted (or target) vector, shape should be (1, X) if(shape.first != 1) { - std::cerr << "ERROR: (argmax) Supplied vector is ineligible for argmax" << std::endl; + std::cerr << "ERROR (" << __func__ << ") : "; + std::cerr << "Supplied vector is ineligible for argmax" << std::endl; std::exit(EXIT_FAILURE); } // Return distance of max element from first element (i.e. index) @@ -388,7 +392,8 @@ std::vector > operator + (const std::vector> const auto shape_b = get_shape(B); // If vectors don't have equal shape if(shape_a.first != shape_b.first || shape_a.second != shape_b.second) { - std::cerr << "ERROR: (vector addition) Supplied vectors have different shapes "; + std::cerr << "ERROR (" << __func__ << ") : "; + std::cerr << "Supplied vectors have different shapes "; std::cerr << shape_a << " and " << shape_b << std::endl; std::exit(EXIT_FAILURE); } @@ -412,7 +417,8 @@ std::vector > operator - (const std::vector> const auto shape_b = get_shape(B); // If vectors don't have equal shape if(shape_a.first != shape_b.first || shape_a.second != shape_b.second) { - std::cerr << "ERROR: (vector subtraction) Supplied vectors have different shapes "; + std::cerr << "ERROR (" << __func__ << ") : "; + std::cerr << "Supplied vectors have different shapes "; std::cerr << shape_a << " and " << shape_b << std::endl; std::exit(EXIT_FAILURE); } @@ -436,7 +442,8 @@ std::vector > multiply(const std::vector> &A, const auto shape_b = get_shape(B); // If vectors are not eligible for multiplication if(shape_a.second != shape_b.first ) { - std::cerr << "ERROR: (multiply) Supplied vectors are not eligible for multiplication "; + std::cerr << "ERROR (" << __func__ << ") : "; + std::cerr << "Vectors are not eligible for multiplication "; std::cerr << shape_a << " and " << shape_b << std::endl; std::exit(EXIT_FAILURE); } @@ -468,7 +475,8 @@ std::vector > hadamard_product(const std::vector