NN_in_Trading/Experts/Unsupervised/AE/VAE.mqh
2026-03-11 20:55:49 +02:00

185 lines
16 KiB
MQL5

//+------------------------------------------------------------------+
//| VAE.mqh |
//| Copyright DNG® |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright DNG®"
#property link "https://www.mql5.com/ru/users/dng"
#property version "1.00"
//---
#ifndef lr
#include "..\..\NeuroNet_DNG\NeuroNet.mqh"
#endif
#define class_vae
//---
class CVAE : public CNeuronBaseOCL
{
protected:
float m_fKLD_Mult;
CBufferFloat* m_cRandom;
///\ingroup neuron_base_ff
virtual bool feedForward(CNeuronBaseOCL *NeuronOCL); ///< \brief Feed Forward method of calling kernel ::VAE().@param NeuronOCL Pointer to previos layer.
///\ingroup neuron_base_opt
virtual bool updateInputWeights(CNeuronBaseOCL *NeuronOCL) { return true; } ///< Method for updating weights.\details Calling one of kernels ::UpdateWeightsMomentum() or ::UpdateWeightsAdam() in depends of optimization type (#ENUM_OPTIMIZATION).@param NeuronOCL Pointer to previos layer.
public:
CVAE();
~CVAE();
virtual bool Init(uint numOutputs, uint myIndex, COpenCLMy *open_cl, uint numNeurons, ENUM_OPTIMIZATION optimization_type, uint batch);
//---
virtual void SetKLDMult(float value) { m_fKLD_Mult = value;}
///< Method of initialization class.@param[in] numOutputs Number of connections to next layer.@param[in] myIndex Index of neuron in layer.@param[in] open_cl Pointer to #COpenCLMy object. #param[in] numNeurons Number of neurons in layer @param optimization_type Optimization type (#ENUM_OPTIMIZATION)@return Boolen result of operations.
///\ingroup neuron_base_gr
///@{
virtual bool calcInputGradients(CNeuronBaseOCL *NeuronOCL); ///< Method to transfer gradient to previous layer by calling kernel ::CalcHiddenGradient(). @param NeuronOCL Pointer to next layer.
///@}
//---
virtual bool Save(int const file_handle);///< Save method @param[in] file_handle handle of file @return logical result of operation
virtual bool Load(int const file_handle);///< Load method @param[in] file_handle handle of file @return logical result of operation
//---
virtual int Type(void) const { return defNeuronVAEOCL; }///< Identificator of class.@return Type of class
virtual void SetOpenCL(COpenCLMy *obj);
};
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
CVAE::CVAE() : m_fKLD_Mult(0.01f)
{
m_cRandom = new CBufferFloat();
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
CVAE::~CVAE()
{
if(!!m_cRandom)
delete m_cRandom;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CVAE::Init(uint numOutputs, uint myIndex, COpenCLMy *open_cl, uint numNeurons, ENUM_OPTIMIZATION optimization_type, uint batch)
{
if(!CNeuronBaseOCL::Init(numOutputs, myIndex, open_cl, numNeurons, optimization_type, batch))
return false;
//---
if(!m_cRandom)
{
m_cRandom = new CBufferFloat();
if(!m_cRandom)
return false;
}
if(!m_cRandom.BufferInit(numNeurons, 0.0))
return false;
if(!m_cRandom.BufferCreate(OpenCL))
return false;
//---
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CVAE::feedForward(CNeuronBaseOCL *NeuronOCL)
{
if(!OpenCL || !NeuronOCL)
return false;
if(NeuronOCL.Neurons() % 2 != 0 ||
NeuronOCL.Neurons() / 2 != Neurons())
return false;
//---
double random[];
if(!MathRandomNormal(0, 1, m_cRandom.Total(), random))
return false;
if(!m_cRandom.AssignArray(random))
return false;
if(!m_cRandom.BufferWrite())
return false;
//---
if(!OpenCL.SetArgumentBuffer(def_k_VAEFeedForward, def_k_vaeff_inputs, NeuronOCL.getOutput().GetIndex()))
return false;
if(!OpenCL.SetArgumentBuffer(def_k_VAEFeedForward, def_k_vaeff_random, m_cRandom.GetIndex()))
return false;
if(!OpenCL.SetArgumentBuffer(def_k_VAEFeedForward, def_k_vaeff_outputd, Output.GetIndex()))
return false;
uint off_set[] = {0};
uint NDrange[] = {Neurons()};
if(!OpenCL.Execute(def_k_VAEFeedForward, 1, off_set, NDrange))
return false;
//if(!Output.BufferRead())
// return false;
//---
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CVAE::calcInputGradients(CNeuronBaseOCL *NeuronOCL)
{
if(!OpenCL || !NeuronOCL)
return false;
//---
if(!OpenCL.SetArgumentBuffer(def_k_VAECalcHiddenGradient, def_k_vaehg_input, NeuronOCL.getOutput().GetIndex()))
return false;
if(!OpenCL.SetArgumentBuffer(def_k_VAECalcHiddenGradient, def_k_vaehg_inp_grad, NeuronOCL.getGradient().GetIndex()))
return false;
if(!OpenCL.SetArgumentBuffer(def_k_VAECalcHiddenGradient, def_k_vaehg_random, m_cRandom.GetIndex()))
return false;
if(!OpenCL.SetArgumentBuffer(def_k_VAECalcHiddenGradient, def_k_vaehg_gradient, Gradient.GetIndex()))
return false;
if(!OpenCL.SetArgument(def_k_VAECalcHiddenGradient, def_k_vaehg_kld_mult, m_fKLD_Mult))
return false;
uint off_set[] = {0};
uint NDrange[] = {Neurons()};
if(!OpenCL.Execute(def_k_VAECalcHiddenGradient, 1, off_set, NDrange))
return false;
//---
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CVAE::Save(const int file_handle)
{
//---
if(!CNeuronBaseOCL::Save(file_handle))
return false;
if(FileWriteFloat(file_handle, m_fKLD_Mult) < sizeof(m_fKLD_Mult))
return false;
//---
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CVAE::Load(const int file_handle)
{
if(!CNeuronBaseOCL::Load(file_handle))
return false;
m_fKLD_Mult = FileReadFloat(file_handle);
//---
if(!m_cRandom)
{
m_cRandom = new CBufferFloat();
if(!m_cRandom)
return false;
}
m_cRandom.BufferFree();
if(!m_cRandom.BufferInit(Neurons(), 0.0))
return false;
if(!m_cRandom.BufferCreate(OpenCL))
return false;
//---
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CVAE::SetOpenCL(COpenCLMy *obj)
{
CNeuronBaseOCL::SetOpenCL(obj);
if(!!m_cRandom)
m_cRandom.BufferCreate(obj);
}
//+------------------------------------------------------------------+