mirror of
https://github.com/TheAlgorithms/C-Plus-Plus.git
synced 2026-07-01 01:26:48 +08:00
Improved Overall Error handling and reporting
This commit is contained in:
@@ -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 <std::vector<std::valarray<double>>> &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 <std::pair<int, std::string>> &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 <std::vector<std::valarray<double>>> 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 <std::valarray<double>>> 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 <std::pair<int, std::string>> 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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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<T, T> &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<T> &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 <std::valarray<T>> > &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<size_t, size_t> get_shape(const std::vector<std::valarray<T>> &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<std::vector<std::valarray<T>>> &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<std::valarray<T>> &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 <std::valarray <T> > operator + (const std::vector<std::valarray<T>>
|
||||
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 <std::valarray <T>> operator - (const std::vector<std::valarray<T>>
|
||||
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 <std::valarray <T>> multiply(const std::vector<std::valarray<T>> &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 <std::valarray <T>> hadamard_product(const std::vector<std::valarray
|
||||
const auto shape_b = get_shape(B);
|
||||
// If vectors are not eligible for hadamard product
|
||||
if(shape_a.first != shape_b.first || shape_a.second != shape_b.second) {
|
||||
std::cerr << "ERROR: (hadamard_product) Supplied vectors have different shapes ";
|
||||
std::cerr << "ERROR (" << __func__ << ") : ";
|
||||
std::cerr << "Vectors have different shapes ";
|
||||
std::cerr << shape_a << " and " << shape_b << std::endl;
|
||||
std::exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user