From b41c0f03d9d8e933652a2ef8cac43d6dff19cfb7 Mon Sep 17 00:00:00 2001 From: "szewczyk.franciszek02" Date: Thu, 9 Nov 2023 15:18:07 +0100 Subject: [PATCH] Nesterov Accelerated Gradient --- include/ShkyeraGrad.hpp | 1 + include/core/Value.hpp | 2 ++ include/nn/optimizers/NAG.hpp | 56 +++++++++++++++++++++++++++++++++++ 3 files changed, 59 insertions(+) create mode 100644 include/nn/optimizers/NAG.hpp diff --git a/include/ShkyeraGrad.hpp b/include/ShkyeraGrad.hpp index 45541a4..fb71f5e 100644 --- a/include/ShkyeraGrad.hpp +++ b/include/ShkyeraGrad.hpp @@ -18,6 +18,7 @@ #include "nn/Sequential.hpp" #include "nn/optimizers/Adam.hpp" +#include "nn/optimizers/NAG.hpp" #include "nn/optimizers/Optimizer.hpp" #include "nn/optimizers/SGD.hpp" diff --git a/include/core/Value.hpp b/include/core/Value.hpp index ea3b0c1..454a25c 100644 --- a/include/core/Value.hpp +++ b/include/core/Value.hpp @@ -23,6 +23,7 @@ namespace shkyera { template class Optimizer; template class Adam; template class SGD; +template class NAG; template class Value; template using ValuePtr = std::shared_ptr>; @@ -47,6 +48,7 @@ template class Value : public std::enable_shared_from_this friend class Optimizer; friend class Adam; friend class SGD; + friend class NAG; static ValuePtr create(T data); diff --git a/include/nn/optimizers/NAG.hpp b/include/nn/optimizers/NAG.hpp new file mode 100644 index 0000000..3365ffd --- /dev/null +++ b/include/nn/optimizers/NAG.hpp @@ -0,0 +1,56 @@ +/** + * Copyright © 2023 Franciszek Szewczyk. None of the rights reserved. + * This code is released under the Beerware License. If you find this code useful or you appreciate the work, you are + * encouraged to buy the author a beer in return. + * Contact the author at szewczyk.franciszek02@gmail.com for inquiries and support. + */ + +#pragma once + +#include +#include + +#include "../../core/Type.hpp" +#include "../../core/Value.hpp" +#include "../Module.hpp" +#include "Optimizer.hpp" + +namespace shkyera { + +template class NAG; +using NAG32 = NAG; +using NAG64 = NAG; + +template class NAG : public Optimizer { + private: + T _momentum; + std::vector _moments; + + public: + NAG(std::vector> params, T learningRate, T momentum = 0.9); + + void step() override; +}; + +template +NAG::NAG(std::vector> params, T learningRate, T momentum) : Optimizer(params, learningRate) { + _momentum = momentum; + _moments.resize(params.size(), 0); +} + +template void NAG::step() { + static bool initialized = false; + + for (size_t i = 0; i < this->_parameters.size(); ++i) { + const ValuePtr ¶m = this->_parameters[i]; + + T gradient = param->getGradient(); + T moment = initialized ? _momentum * _moments[i] + (1 - _momentum) * gradient : gradient; + + param->_data -= this->_learningRate * (moment + _momentum * _moments[i]); + + _moments[i] = moment; + } +} + +} // namespace shkyera