diff --git a/src/machine_learning/loss_functions/losses.h b/src/machine_learning/loss_functions/losses.h new file mode 100644 index 00000000..bcff4f7e --- /dev/null +++ b/src/machine_learning/loss_functions/losses.h @@ -0,0 +1,96 @@ +#ifndef MEAN_SQUARED_ERROR_H +#define MEAN_SQUARED_ERROR_H + +#ifdef __cplusplus +#include +#include +#include +#include +#include +#include +#endif + +/** + * @brief losses namespace that contains a couple of useful losses in machine learning + * + */ +namespace losses { + + /** + * @brief sigmoid activation function + * @param x: double, the input parameter + * @return double: the sigmoid output + */ + double sigmoid(double x) { + return 1.0 / (1.0 + exp(-x)); + } + + /** + * @brief mean squared error function + * @param y: vector, the original labels + * @param y_hat: vector, the predicted labels + * @return double: the mean squared error + */ + double mean_squared_error(std::vector const& y, std::vector const& y_hat) { + assert(y.size() == y_hat.size()); + size_t n = y.size(); + double mse = 0.0; + for(size_t i = 0; i const& y, std::vector const& y_hat) { + return std::sqrt(mean_squared_error(y, y_hat)); + } + + /** + * @brief mean absolute error function + * @param y: vector, the original labels + * @param y_hat: vector, the predicted labels + * @return double: the mean absolute error + */ + double mean_absolute_error(std::vector const& y, std::vector const& y_hat) { + assert(y.size() == y_hat.size()); + size_t n = y.size(); + double mae = 0.0; + for(size_t i = 0; i const& y, std::vector const& y_hat) { + assert(y.size() == y_hat.size()); + for(auto & x : y) { + assert(x == 0.0 || x == 1.0); + } + + size_t n = y.size(); + double bce = 0.0, eps = 1e-15; + for(size_t i = 0; i v1 { 1.23, 4.25, 4.4, 1.231, 5.567 }; + std::vector v2 { 4.56, 4.123, 1.234, 6.432, 5.555 }; + + REQUIRE(mean_squared_error(v1, v2) == Approx(9.6358263926).epsilon(1e-6)); +} + +TEST_CASE("Testing mean absolute error") { + std::vector v1 { 1.23, 4.25, 4.4, 1.231, 5.567 }; + std::vector v2 { 4.56, 4.123, 1.234, 6.432, 5.555 }; + + REQUIRE(mean_absolute_error(v1, v2) == Approx(2.36720).epsilon(1e-6)); +} + +TEST_CASE("Testing binary crossentropy loss") { + std::vector v1 { 0., 0., 0., 0., 1., 0., 0., 0., 0., 1. }; + std::vector v2 { 1.8055, 0.9193, -0.2527, 1.0489, 0.5396, -1.2046, -0.9479, 0.8274, + -0.0548, -0.1902 }; + + REQUIRE(binary_crossentropy_loss(v1, v2) == Approx(0.8834657559).epsilon(1e-6)); +} +