diff --git a/CMakeLists.txt b/CMakeLists.txt index 0151956..1bf733a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -25,4 +25,63 @@ add_subdirectory(src/slowmokit) add_library(slowmokit src/slowmokit.hpp - src/slowmokit.cpp) \ No newline at end of file + + + # base files + src/slowmokit/base.hpp + src/slowmokit/core.hpp + src/slowmokit/prereqs.hpp + + # ducks + src/slowmokit/ducks/ducks.hpp + src/slowmokit/ducks/io/io.hpp + src/slowmokit/ducks/io/io.cpp + src/slowmokit/ducks/matrix/matrix.hpp + src/slowmokit/ducks/matrix/matrix_main.cpp + src/slowmokit/ducks/matrix/matrix_free.cpp + + # methods + src/slowmokit/models/model.hpp + src/slowmokit/methods/neighbors/knn/knn.cpp + src/slowmokit/methods/neighbors/knn/knn.hpp + src/slowmokit/methods/linear_model/linear_regression.hpp + src/slowmokit/methods/linear_model/linear_regression/linear_regression.hpp + src/slowmokit/methods/linear_model/linear_regression/linear_regression.cpp + src/slowmokit/methods/cluster/kMeans/kMeans.cpp + src/slowmokit/methods/cluster/kMeans/kMeans.hpp + src/slowmokit/methods/cluster/kMeans.hpp + src/slowmokit/methods/metrics/accuracy.hpp + src/slowmokit/methods/metrics/accuracy.cpp + src/slowmokit/methods/preprocessing/normalization.hpp + src/slowmokit/methods/preprocessing/normalization.cpp + src/slowmokit/methods/preprocessing/standardization.hpp + src/slowmokit/methods/preprocessing/standardization.cpp + src/slowmokit/methods/neighbors/bernoulli_nb.hpp + src/slowmokit/methods/neighbors/bernoulli_nb/bernoulli_nb.hpp + src/slowmokit/methods/neighbors/bernoulli_nb/bernoulli_nb.cpp + src/slowmokit/methods/linear_model/logistic_regression.hpp + src/slowmokit/methods/linear_model/logistic_regression/logistic_regression.hpp + src/slowmokit/methods/linear_model/logistic_regression/logistic_regression.cpp + src/slowmokit/methods/preprocessing/label_encoder.cpp + src/slowmokit/methods/preprocessing/label_encoder.hpp + src/slowmokit/methods/metrics/classification_report.hpp + src/slowmokit/methods/metrics/classification_report.cpp + src/slowmokit/methods/neighbors/gaussian_nb.hpp + src/slowmokit/methods/neighbors/gaussian_nb/gaussian_nb.cpp + src/slowmokit/methods/neighbors/gaussian_nb/gaussian_nb.hpp + src/slowmokit/methods/neighbors/knn.hpp + src/slowmokit/methods/neighbors/knn/knn.hpp + src/slowmokit/methods/neighbors/knn/knn.cpp + src/slowmokit/methods/preprocessing/one_hot_encoder.hpp + src/slowmokit/methods/preprocessing/one_hot_encoder.cpp + src/slowmokit/methods/metrics/precision.hpp + src/slowmokit/methods/metrics/precision.cpp + src/slowmokit/methods/metrics/recall.hpp + src/slowmokit/methods/metrics/recall.cpp + src/slowmokit/methods/metrics/f1score.hpp + src/slowmokit/methods/metrics/f1score.cpp + src/slowmokit/methods/metrics/mean_squared_error.hpp + src/slowmokit/methods/metrics/mean_squared_error.cpp + src/slowmokit/methods/metrics/silhouette_score.cpp + src/slowmokit/methods/metrics/silhouette_score.hpp) + diff --git a/docs/methods/activation_functions.md b/docs/methods/activation_functions.md new file mode 100644 index 0000000..8fe1f7e --- /dev/null +++ b/docs/methods/activation_functions.md @@ -0,0 +1,117 @@ +# Activation Functions + +Sigmoid-It is computationally expensive, causes vanishing gradient problem and not zero-centred. This method is generally used for binary classification problems. + +tanh- The Tanh activation function is a hyperbolic tangent sigmoid function that has a range of -1 to 1. It is often used in deep learning models for its ability to model nonlinear boundaries + +arctan-The ArcTan function is a sigmoid function to model accelerating and decelerating outputs but with useful output ranges.This activation function maps the input values in the range (−π/2,π/2). Its derivative converges quadratically against 0 for large input values. + +ReLU-This The ReLU activation function returns 0 if the input value to the function is less than 0 but for any positive input, the output is the same as the input. It is also continuous but non-differentiable at 0 and at values less than 0 because its derivative is 0 for any negative input. + +leakyReLU- With Leaky ReLU there is a small negative slope so instead of that firing at all, for large gradients, our neurons do output some value and that makes our layer much more optimized too. + +softmax-The softmax is a more generalised form of the sigmoid. It is used in multi-class classification problems. Similar to sigmoid, it produces values in the range of 0–1 therefore it is used as the final layer in classification models. + +binaryStep-The Step activation function is used in the perceptron network. This is usually used in single-layer networks to convert to an output that is binary (0 or 1).These are called Binary Step Function. + + +The following function definitions are defined for a single variable for making it comprehendible and are implemented for a vector of 'double' values in the original code. +## Parameters + +| Name | Definition | Type | +|--------------|--------------------------------------------|--------------| +| x | double value on which the function is applied. | `double` | + + +## Functions + +| Name | Definition | Return value | +|----------------------------------------|-----------------------------------------------|---------------| +|sigmoid(x)| 1 / (1 + e^(-x)) | `double` | +|tanh(x)| (e^x - e^(-x)) / (e^x + e^(-x)) | `double` | +|arctan(x)| the inverse of tan(x) | `double` | +|ReLU(x)| max(0, x) | `double` | +|leakyReLU(x)| max(αx, x),α=0.1 | `double` | +|binaryStep(x)| 0, if x < 0 +| | 1, if x ≥ 0 | `double` | +|softmax(x)| e^(x_i) / Σ_j e^(x_j) | `double` | + + +## Example + +```cpp +int main(){ + //sigmoid example +std::vector x = {-1,0,1}; + sigmoid(x); + for (int i = 0; i < x.size(); i++) { + std::cout << x[i] << " "; + } + return 0; + + //tanh example +std::vector x = {-1,0,1}; + tanh(x); + for (int i = 0; i < x.size(); i++) { + std::cout << x[i] << " "; + } + return 0; + + //arctan example +std::vector x = {-1,0,1}; + arctan(x); + for (int i = 0; i < x.size(); i++) { + std::cout << x[i] << " "; + } + return 0; + + //ReLU example +std::vector x = {1, 2, 3}; + ReLU(x); + for (int i = 0; i < x.size(); i++) { + std::cout << x[i] << " "; + } + return 0; + + //leakyReLU example +std::vector x = {1, 2, 3}; + leakyReLU(x); + for (int i = 0; i < x.size(); i++) { + std::cout << x[i] << " "; + } + return 0; + + //binaryStep example +std::vector x = {1, 2, 3}; + binaryStep(x); + for (int i = 0; i < x.size(); i++) { + std::cout << x[i] << " "; + } + return 0; + + //softmax example +std::vector x = {1, 2, 3}; + softmax(x); + for (int i = 0; i < x.size(); i++) { + std::cout << x[i] << " "; + } + return 0; + + //binaryToBipolar example +std::vector x = {-1,1}; + binaryToBipolar(x); + for (int i = 0; i < x.size(); i++) { + std::cout << x[i] << " "; + } + return 0; + + //bipolarToBinary example +std::vector x = {-1,1}; + bipolarToBinary(x); + for (int i = 0; i < x.size(); i++) { + std::cout << x[i] << " "; + } + return 0; + +} +``` \ No newline at end of file diff --git a/docs/methods/preprocessing/one_hot_encoder.md b/docs/methods/preprocessing/one_hot_encoder.md new file mode 100644 index 0000000..92bcb1c --- /dev/null +++ b/docs/methods/preprocessing/one_hot_encoder.md @@ -0,0 +1,36 @@ +# One Hot Encoder + +One hot encoding is a technique to represent categorical variables as numerical values.Each unique value of a categorical variable is assigned a binary code, where a "1" in the code represents the presence of that value and a "0" represents its absence. + +One hot encoding makes our training data more useful and expressive, and it can be rescaled easily. + + +## Parameters + +| Name | Definition | Type | +|--------------|--------------------------------------------|--------------| +| data | The data that has to be encoded is passed as the data parameter in the oneHotEncoder function. | `vector` | +| nClasses | This parameter is an integer that specifies the number of classes or categories in the input data. | `int` | + +## Methods + +| Name | Definition | Return value | +|----------------------------------------|-----------------------------------------------|---------------| +| `oneHotEncoder(vector data, nClasses)` | To encode the data into numerical values. | `vector>` | + +## Example + +```cpp +int main() { + std::vector data = {"apples", "banana", "mango", "pear", "mango","apples","pear"}; + int nClasses = 4; + std::vector> oneHotEncodedData = oneHotEncoder(data, nClasses); + for (const auto &row : oneHotEncodedData) { + for (const auto &column : row) { + std::cout << column << " "; + } + std::cout << std::endl; + } + return 0; +} +``` \ No newline at end of file diff --git a/examples/activation_functions_eg.cpp b/examples/activation_functions_eg.cpp new file mode 100644 index 0000000..33d9173 --- /dev/null +++ b/examples/activation_functions_eg.cpp @@ -0,0 +1,74 @@ +//int main(){ + //sigmoid example +//std::vector x = {-1,0,1}; +// sigmoid(x); +// for (int i = 0; i < x.size(); i++) { +// std::cout << x[i] << " "; +// } +// return 0; + + //tanh example +//std::vector x = {-1,0,1}; +// tanh(x); +// for (int i = 0; i < x.size(); i++) { +// std::cout << x[i] << " "; +// } +// return 0; + + //arctan example +//std::vector x = {-1,0,1}; +// arctan(x); +// for (int i = 0; i < x.size(); i++) { +// std::cout << x[i] << " "; +// } +// return 0; + + //ReLU example +//std::vector x = {1, 2, 3}; +// ReLU(x); +// for (int i = 0; i < x.size(); i++) { +// std::cout << x[i] << " "; +// } +// return 0; + + //leakyReLU example +//std::vector x = {1, 2, 3}; +// leakyReLU(x); +// for (int i = 0; i < x.size(); i++) { +// std::cout << x[i] << " "; +// } +// return 0; + + //binaryStep example +//std::vector x = {1, 2, 3}; +// binaryStep(x); +// for (int i = 0; i < x.size(); i++) { +// std::cout << x[i] << " "; +// } +// return 0; + + //softmax example +//std::vector x = {1, 2, 3}; +// softmax(x); +// for (int i = 0; i < x.size(); i++) { +// std::cout << x[i] << " "; +// } +// return 0; + + //binaryToBipolar example +//std::vector x = {-1,1}; +// binaryToBipolar(x); +// for (int i = 0; i < x.size(); i++) { +// std::cout << x[i] << " "; +// } +// return 0; + + //bipolarToBinary example +//std::vector x = {-1,1}; +// bipolarToBinary(x); +// for (int i = 0; i < x.size(); i++) { +// std::cout << x[i] << " "; +// } +// return 0; + +//} \ No newline at end of file diff --git a/src/slowmokit/methods/activation_functions.cpp b/src/slowmokit/methods/activation_functions.cpp new file mode 100644 index 0000000..ef597fd --- /dev/null +++ b/src/slowmokit/methods/activation_functions.cpp @@ -0,0 +1,106 @@ +/** + * @file methods/activation_functions.cpp + * + * Implementation of activation functions + */ +#include "activation_functions.hpp" +// sigmoid +void sigmoid(std::vector &x) +{ + for (int i = 0; i < x.size(); i++) + { + x[i] = 1 / (1 + std::exp(-x[i])); + } +} +// ReLU +void ReLU(std::vector &x) +{ + for (int i = 0; i < x.size(); i++) + { + if (x[i] <= 0.0) + { + x[i] = 0.0; + } + } +} +// tanh +void tanh(std::vector &x) +{ + for (int i = 0; i < x.size(); i++) + { + x[i] = + (std::exp(x[i]) - std::exp(-x[i])) / (std::exp(x[i]) + std::exp(-x[i])); + } +} +// arctan +void arctan(std::vector &x) +{ + for (int i = 0; i < x.size(); i++) + { + x[i] = std::atan(x[i]); + } +} + +// softmax +void softmax(std::vector &x) +{ + double sum = 0; + for (double value : x) + { + sum += std::exp(value); + } + for (int i = 0; i < x.size(); i++) + { + x[i] = std::exp(x[i]) / sum; + } +} +// binarystep +void binaryStep(std::vector &x) +{ + for (int i = 0; i < x.size(); i++) + { + if (x[i] >= 0) + { + x[i] = 1; + } // assuming threshold value to be 0 here + else + { + x[i] = 0; + } + } +} +// leakyReLU +void leakyReLU(std::vector &x, double alpha = 0.1) +{ + for (int i = 0; i < x.size(); i++) + { + if (x[i] >= 0) + { + x[i] = x[i]; + } + else + { + x[i] = alpha * x[i]; // alpha=0.1 + }; + } +} +// binaryToBipolar Conversion +// x= binary numbers entered by the user +// y= bipolar numbers to be produced as output +void binaryToBipolar(std::vector &x) +{ + for (int i = 0; i < x.size(); i++) + { + x[i] = 2 * x[i] - 1; + } +} +// bipolarToBinary Conversion +// x= bipolar numbers entered by the user +// y= binary numbers to be produced as output +void bipolarToBinary(std::vector &x) +{ + for (int i = 0; i < x.size(); i++) + { + x[i] = (x[i] + 1) / 2; + } +} \ No newline at end of file diff --git a/src/slowmokit/methods/activation_functions.hpp b/src/slowmokit/methods/activation_functions.hpp new file mode 100644 index 0000000..7d21281 --- /dev/null +++ b/src/slowmokit/methods/activation_functions.hpp @@ -0,0 +1,93 @@ +/** + * @file methods/activation_functions.hpp + * + * Easy include to add non-linearity into a neural network. + */ + +#ifndef ACTIVATION_FUNCTIONS_HPP +#define ACTIVATION_FUNCTIONS_HPP +#include "../core.hpp" +template + +/** + * @brief To calculate sigmoid(x) + * @param x {vector} - vector containing 'double' values of x whose + * sigmoid values have to be calculated. + * + */ + +void sigmoid(std::vector &); + +/** + * @brief To calculate ReLU(x) + * @param x {vector} - vector containing 'double' values of x whose ReLU + * values have to be calculated. + * + */ + +void ReLU(std::vector &); + +/** + * @brief To calculate tanh(x) + * @param x {vector} - vector containing 'double' values of x whose tanh + * values have to be calculated. + * + */ + +void tanh(std::vector &); + +/** + * @brief To calculate arctan(x) + * @param x {vector} - vector containing 'double' values of x whose + * arctan values have to be calculated. + * + */ + +void arctan(std::vector &); + +/** + * @brief To calculate softmax(x) + * @param x {vector} - vector containing 'double' values of x whose + * softmax values have to be calculated. + * + */ + +void softmax(std::vector &); + +/** + * @brief To calculate binaryStep(x) + * @param x {vector} - vector containing 'double' values of x whose + * binaryStep values have to be calculated. + * + */ + +void binaryStep(std::vector &); + +/** + * @brief To calculate leakyReLU(x) + * @param x {vector} - vector containing 'double' values of x whose + * leakyReLU values have to be calculated. + * + */ + +void leakyReLU(std::vector &, double = 0.1); + +/** + * @brief To convert binaryToBipolar(x) + * @param x {vector} - vector containing 'double' values of x who have + * to be converted to bipolar numbers. + * + */ + +void binaryToBipolar(std::vector &); + +/** + * @brief To convert bipolarToBinary(x) + * @param x {vector} - vector containing 'double' values of x who have + * to be converted to binary numbers. + * + */ + +void bipolarToBinary(std::vector &); + +#endif // ACTIVATION_FUNCTIONS_HPP \ No newline at end of file