From df75dc8e7f3cd5d70c1c480eea203b5016715ff5 Mon Sep 17 00:00:00 2001 From: Relintai Date: Sat, 4 Feb 2023 13:53:36 +0100 Subject: [PATCH] Added a new MultiOutputLayer implementation. --- .../multi_output_layer/multi_output_layer.cpp | 271 +++++++++++++++++- mlpp/multi_output_layer/multi_output_layer.h | 89 +++++- register_types.cpp | 2 + 3 files changed, 357 insertions(+), 5 deletions(-) diff --git a/mlpp/multi_output_layer/multi_output_layer.cpp b/mlpp/multi_output_layer/multi_output_layer.cpp index e85987a..1653b9d 100644 --- a/mlpp/multi_output_layer/multi_output_layer.cpp +++ b/mlpp/multi_output_layer/multi_output_layer.cpp @@ -11,9 +11,272 @@ #include #include +int MLPPMultiOutputLayer::get_n_output() { + return n_output; +} +void MLPPMultiOutputLayer::set_n_output(const int val) { + n_output = val; +} + +int MLPPMultiOutputLayer::get_n_hidden() { + return n_hidden; +} +void MLPPMultiOutputLayer::set_n_hidden(const int val) { + n_hidden = val; +} + +MLPPActivation::ActivationFunction MLPPMultiOutputLayer::get_activation() { + return activation; +} +void MLPPMultiOutputLayer::set_activation(const MLPPActivation::ActivationFunction val) { + activation = val; +} + +MLPPCost::CostTypes MLPPMultiOutputLayer::get_cost() { + return cost; +} +void MLPPMultiOutputLayer::set_cost(const MLPPCost::CostTypes val) { + cost = val; +} + +Ref MLPPMultiOutputLayer::get_input() { + return input; +} +void MLPPMultiOutputLayer::set_input(const Ref &val) { + input = val; +} + +Ref MLPPMultiOutputLayer::get_weights() { + return weights; +} +void MLPPMultiOutputLayer::set_weights(const Ref &val) { + weights = val; +} + +Ref MLPPMultiOutputLayer::get_bias() { + return bias; +} +void MLPPMultiOutputLayer::set_bias(const Ref &val) { + bias = val; +} + +Ref MLPPMultiOutputLayer::get_z() { + return z; +} +void MLPPMultiOutputLayer::set_z(const Ref &val) { + z = val; +} + +Ref MLPPMultiOutputLayer::get_a() { + return a; +} +void MLPPMultiOutputLayer::set_a(const Ref &val) { + a = val; +} + +Ref MLPPMultiOutputLayer::get_z_test() { + return z_test; +} +void MLPPMultiOutputLayer::set_z_test(const Ref &val) { + z_test = val; +} + +Ref MLPPMultiOutputLayer::get_a_test() { + return a_test; +} +void MLPPMultiOutputLayer::set_a_test(const Ref &val) { + a_test = val; +} + +Ref MLPPMultiOutputLayer::get_delta() { + return delta; +} +void MLPPMultiOutputLayer::set_delta(const Ref &val) { + delta = val; +} + +MLPPReg::RegularizationType MLPPMultiOutputLayer::get_reg() { + return reg; +} +void MLPPMultiOutputLayer::set_reg(const MLPPReg::RegularizationType val) { + reg = val; +} + +real_t MLPPMultiOutputLayer::get_lambda() { + return lambda; +} +void MLPPMultiOutputLayer::set_lambda(const real_t val) { + lambda = val; +} + +real_t MLPPMultiOutputLayer::get_alpha() { + return alpha; +} +void MLPPMultiOutputLayer::set_alpha(const real_t val) { + alpha = val; +} + +MLPPUtilities::WeightDistributionType MLPPMultiOutputLayer::get_weight_init() { + return weight_init; +} +void MLPPMultiOutputLayer::set_weight_init(const MLPPUtilities::WeightDistributionType val) { + weight_init = val; +} + +void MLPPMultiOutputLayer::forward_pass() { + MLPPLinAlg alg; + MLPPActivation avn; + + z = alg.mat_vec_addv(alg.matmultm(input, weights), bias); + a = avn.run_activation_norm_matrix(activation, z); +} + +void MLPPMultiOutputLayer::test(const Ref &x) { + MLPPLinAlg alg; + MLPPActivation avn; + + z_test = alg.additionm(alg.mat_vec_multv(alg.transposem(weights), x), bias); + a_test = avn.run_activation_norm_vector(activation, z_test); +} + +MLPPMultiOutputLayer::MLPPMultiOutputLayer(int p_n_hidden, MLPPActivation::ActivationFunction p_activation, Ref p_input, MLPPUtilities::WeightDistributionType p_weight_init, MLPPReg::RegularizationType p_reg, real_t p_lambda, real_t p_alpha) { + n_hidden = p_n_hidden; + activation = p_activation; + + input = p_input; + + // Regularization Params + reg = p_reg; + lambda = p_lambda; /* Regularization Parameter */ + alpha = p_alpha; /* This is the controlling param for Elastic Net*/ + + weight_init = p_weight_init; + + z.instance(); + a.instance(); + + z_test.instance(); + a_test.instance(); + + delta.instance(); + + weights.instance(); + bias.instance(); + + weights->resize(Size2i(n_hidden, n_output)); + bias->resize(n_output); + + MLPPUtilities utils; + + utils.weight_initializationm(weights, weight_init); + utils.bias_initializationv(bias); +} + +MLPPMultiOutputLayer::MLPPMultiOutputLayer() { + n_hidden = 0; + activation = MLPPActivation::ACTIVATION_FUNCTION_LINEAR; + + // Regularization Params + //reg = 0; + lambda = 0; /* Regularization Parameter */ + alpha = 0; /* This is the controlling param for Elastic Net*/ + + weight_init = MLPPUtilities::WEIGHT_DISTRIBUTION_TYPE_DEFAULT; + + z.instance(); + a.instance(); + + z_test.instance(); + a_test.instance(); + + delta.instance(); + + weights.instance(); + bias.instance(); +} +MLPPMultiOutputLayer::~MLPPMultiOutputLayer() { +} + +void MLPPMultiOutputLayer::_bind_methods() { + ClassDB::bind_method(D_METHOD("get_n_output"), &MLPPMultiOutputLayer::get_n_output); + ClassDB::bind_method(D_METHOD("set_n_output", "val"), &MLPPMultiOutputLayer::set_n_output); + ADD_PROPERTY(PropertyInfo(Variant::INT, "n_output"), "set_n_output", "get_n_output"); + + ClassDB::bind_method(D_METHOD("get_n_hidden"), &MLPPMultiOutputLayer::get_n_hidden); + ClassDB::bind_method(D_METHOD("set_n_hidden", "val"), &MLPPMultiOutputLayer::set_n_hidden); + ADD_PROPERTY(PropertyInfo(Variant::INT, "n_hidden"), "set_n_hidden", "get_n_hidden"); + + ClassDB::bind_method(D_METHOD("get_activation"), &MLPPMultiOutputLayer::get_activation); + ClassDB::bind_method(D_METHOD("set_activation", "val"), &MLPPMultiOutputLayer::set_activation); + ADD_PROPERTY(PropertyInfo(Variant::INT, "activation"), "set_activation", "get_activation"); + + ClassDB::bind_method(D_METHOD("get_cost"), &MLPPMultiOutputLayer::get_cost); + ClassDB::bind_method(D_METHOD("set_cost", "val"), &MLPPMultiOutputLayer::set_cost); + ADD_PROPERTY(PropertyInfo(Variant::INT, "cost"), "set_cost", "get_cost"); + + ClassDB::bind_method(D_METHOD("get_input"), &MLPPMultiOutputLayer::get_input); + ClassDB::bind_method(D_METHOD("set_input", "val"), &MLPPMultiOutputLayer::set_input); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "input", PROPERTY_HINT_RESOURCE_TYPE, "MLPPMatrix"), "set_input", "get_input"); + + ClassDB::bind_method(D_METHOD("get_weights"), &MLPPMultiOutputLayer::get_weights); + ClassDB::bind_method(D_METHOD("set_weights", "val"), &MLPPMultiOutputLayer::set_weights); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "weights", PROPERTY_HINT_RESOURCE_TYPE, "MLPPMatrix"), "set_weights", "get_weights"); + + ClassDB::bind_method(D_METHOD("get_bias"), &MLPPMultiOutputLayer::get_bias); + ClassDB::bind_method(D_METHOD("set_bias", "val"), &MLPPMultiOutputLayer::set_bias); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "bias", PROPERTY_HINT_RESOURCE_TYPE, "MLPPVector"), "set_bias", "get_bias"); + + ClassDB::bind_method(D_METHOD("get_z"), &MLPPMultiOutputLayer::get_z); + ClassDB::bind_method(D_METHOD("set_z", "val"), &MLPPMultiOutputLayer::set_z); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "z", PROPERTY_HINT_RESOURCE_TYPE, "MLPPMatrix"), "set_z", "get_z"); + + ClassDB::bind_method(D_METHOD("get_a"), &MLPPMultiOutputLayer::get_a); + ClassDB::bind_method(D_METHOD("set_a", "val"), &MLPPMultiOutputLayer::set_a); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "a", PROPERTY_HINT_RESOURCE_TYPE, "MLPPMatrix"), "set_a", "get_a"); + + ClassDB::bind_method(D_METHOD("get_z_test"), &MLPPMultiOutputLayer::get_z_test); + ClassDB::bind_method(D_METHOD("set_z_test", "val"), &MLPPMultiOutputLayer::set_z_test); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "z_test", PROPERTY_HINT_RESOURCE_TYPE, "MLPPVector"), "set_z_test", "get_z_test"); + + ClassDB::bind_method(D_METHOD("get_a_test"), &MLPPMultiOutputLayer::get_a_test); + ClassDB::bind_method(D_METHOD("set_a_test", "val"), &MLPPMultiOutputLayer::set_a_test); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "a_test", PROPERTY_HINT_RESOURCE_TYPE, "MLPPVector"), "set_a_test", "get_a_test"); + + ClassDB::bind_method(D_METHOD("get_delta"), &MLPPMultiOutputLayer::get_delta); + ClassDB::bind_method(D_METHOD("set_delta", "val"), &MLPPMultiOutputLayer::set_delta); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "delta", PROPERTY_HINT_RESOURCE_TYPE, "MLPPMatrix"), "set_delta", "get_delta"); + + ClassDB::bind_method(D_METHOD("get_reg"), &MLPPMultiOutputLayer::get_reg); + ClassDB::bind_method(D_METHOD("set_reg", "val"), &MLPPMultiOutputLayer::set_reg); + ADD_PROPERTY(PropertyInfo(Variant::INT, "reg"), "set_reg", "get_reg"); + + ClassDB::bind_method(D_METHOD("get_lambda"), &MLPPMultiOutputLayer::get_lambda); + ClassDB::bind_method(D_METHOD("set_lambda", "val"), &MLPPMultiOutputLayer::set_lambda); + ADD_PROPERTY(PropertyInfo(Variant::REAL, "lambda"), "set_lambda", "get_lambda"); + + ClassDB::bind_method(D_METHOD("get_alpha"), &MLPPMultiOutputLayer::get_alpha); + ClassDB::bind_method(D_METHOD("set_alpha", "val"), &MLPPMultiOutputLayer::set_alpha); + ADD_PROPERTY(PropertyInfo(Variant::REAL, "alpha"), "set_alpha", "get_alpha"); + + ClassDB::bind_method(D_METHOD("get_weight_init"), &MLPPMultiOutputLayer::get_weight_init); + ClassDB::bind_method(D_METHOD("set_weight_init", "val"), &MLPPMultiOutputLayer::set_weight_init); + ADD_PROPERTY(PropertyInfo(Variant::INT, "set_weight_init"), "set_weight_init", "get_weight_init"); + + ClassDB::bind_method(D_METHOD("forward_pass"), &MLPPMultiOutputLayer::forward_pass); + ClassDB::bind_method(D_METHOD("test", "x"), &MLPPMultiOutputLayer::test); +} + +MLPPOldMultiOutputLayer::MLPPOldMultiOutputLayer(int p_n_output, int p_n_hidden, std::string p_activation, std::string p_cost, std::vector> p_input, std::string p_weightInit, std::string p_reg, real_t p_lambda, real_t p_alpha) { + n_output = p_n_output; + n_hidden = p_n_hidden; + activation = p_activation; + cost = p_cost; + input = p_input; + weightInit = p_weightInit; + reg = p_reg; + lambda = p_lambda; + alpha = p_alpha; -MLPPOldMultiOutputLayer::MLPPOldMultiOutputLayer(int n_output, int n_hidden, std::string activation, std::string cost, std::vector> input, std::string weightInit, std::string reg, real_t lambda, real_t alpha) : - n_output(n_output), n_hidden(n_hidden), activation(activation), cost(cost), input(input), weightInit(weightInit), reg(reg), lambda(lambda), alpha(alpha) { weights = MLPPUtilities::weightInitialization(n_hidden, n_output, weightInit); bias = MLPPUtilities::biasInitialization(n_output); @@ -120,12 +383,12 @@ void MLPPOldMultiOutputLayer::forwardPass() { MLPPLinAlg alg; MLPPActivation avn; z = alg.mat_vec_add(alg.matmult(input, weights), bias); - a = (avn.*activation_map[activation])(z, 0); + a = (avn.*activation_map[activation])(z, false); } void MLPPOldMultiOutputLayer::Test(std::vector x) { MLPPLinAlg alg; MLPPActivation avn; z_test = alg.addition(alg.mat_vec_mult(alg.transpose(weights), x), bias); - a_test = (avn.*activationTest_map[activation])(z_test, 0); + a_test = (avn.*activationTest_map[activation])(z_test, false); } diff --git a/mlpp/multi_output_layer/multi_output_layer.h b/mlpp/multi_output_layer/multi_output_layer.h index 79e9a71..dc01457 100644 --- a/mlpp/multi_output_layer/multi_output_layer.h +++ b/mlpp/multi_output_layer/multi_output_layer.h @@ -25,6 +25,94 @@ #include #include +class MLPPMultiOutputLayer : public Reference { + GDCLASS(MLPPMultiOutputLayer, Reference); + +public: + int get_n_output(); + void set_n_output(const int val); + + int get_n_hidden(); + void set_n_hidden(const int val); + + MLPPActivation::ActivationFunction get_activation(); + void set_activation(const MLPPActivation::ActivationFunction val); + + MLPPCost::CostTypes get_cost(); + void set_cost(const MLPPCost::CostTypes val); + + Ref get_input(); + void set_input(const Ref &val); + + Ref get_weights(); + void set_weights(const Ref &val); + + Ref get_bias(); + void set_bias(const Ref &val); + + Ref get_z(); + void set_z(const Ref &val); + + Ref get_a(); + void set_a(const Ref &val); + + Ref get_z_test(); + void set_z_test(const Ref &val); + + Ref get_a_test(); + void set_a_test(const Ref &val); + + Ref get_delta(); + void set_delta(const Ref &val); + + MLPPReg::RegularizationType get_reg(); + void set_reg(const MLPPReg::RegularizationType val); + + real_t get_lambda(); + void set_lambda(const real_t val); + + real_t get_alpha(); + void set_alpha(const real_t val); + + MLPPUtilities::WeightDistributionType get_weight_init(); + void set_weight_init(const MLPPUtilities::WeightDistributionType val); + + void forward_pass(); + void test(const Ref &x); + + MLPPMultiOutputLayer(int p_n_hidden, MLPPActivation::ActivationFunction p_activation, Ref p_input, MLPPUtilities::WeightDistributionType p_weight_init, MLPPReg::RegularizationType p_reg, real_t p_lambda, real_t p_alpha); + + MLPPMultiOutputLayer(); + ~MLPPMultiOutputLayer(); + +protected: + static void _bind_methods(); + + int n_output; + int n_hidden; + MLPPActivation::ActivationFunction activation; + MLPPCost::CostTypes cost; + + Ref input; + + Ref weights; + Ref bias; + + Ref z; + Ref a; + + Ref z_test; + Ref a_test; + + Ref delta; + + // Regularization Params + MLPPReg::RegularizationType reg; + real_t lambda; /* Regularization Parameter */ + real_t alpha; /* This is the controlling param for Elastic Net*/ + + MLPPUtilities::WeightDistributionType weight_init; +}; class MLPPOldMultiOutputLayer { public: @@ -64,5 +152,4 @@ public: void Test(std::vector x); }; - #endif /* MultiOutputLayer_hpp */ diff --git a/register_types.cpp b/register_types.cpp index e6dda2f..a112d92 100644 --- a/register_types.cpp +++ b/register_types.cpp @@ -33,6 +33,7 @@ SOFTWARE. #include "mlpp/utilities/utilities.h" #include "mlpp/hidden_layer/hidden_layer.h" +#include "mlpp/multi_output_layer/multi_output_layer.h" #include "mlpp/output_layer/output_layer.h" #include "mlpp/kmeans/kmeans.h" @@ -52,6 +53,7 @@ void register_pmlpp_types(ModuleRegistrationLevel p_level) { ClassDB::register_class(); ClassDB::register_class(); + ClassDB::register_class(); ClassDB::register_class(); ClassDB::register_class();