NN_in_Trading/Experts/NeuroNet_DNG/NeuroNet_GraphSparse.mqh
2026-06-18 13:05:27 +03:00

5671 lines
213 KiB
MQL5

#ifndef NEURONET_BUILDING_FACADE
#include "NeuroNet.mqh"
#endif // NEURONET_BUILDING_FACADE
//+------------------------------------------------------------------+
//| Logical method implementations generated from NeuroNet.mqh: GraphSparse
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CNeuronCGConvOCL::Init(uint numOutputs, uint myIndex, COpenCLMy * open_cl, uint window, uint numNeurons, ENUM_OPTIMIZATION optimization_type, uint batch)
{
if(!CNeuronBaseOCL::Init(numOutputs, myIndex, open_cl, numNeurons, optimization_type, batch))
ReturnFalse;
activation = None;
//---
if(!cInputF.Init(numNeurons, 0, OpenCL, window, optimization, batch))
ReturnFalse;
if(!cInputS.Init(numNeurons, 1, OpenCL, window, optimization, batch))
ReturnFalse;
cInputF.SetActivationFunction(None);
cInputS.SetActivationFunction(None);
//---
if(!cF.Init(0, 2, OpenCL, numNeurons, optimization, batch))
ReturnFalse;
cF.SetActivationFunction(SIGMOID);
if(!cS.Init(0, 3, OpenCL, numNeurons, optimization, batch))
ReturnFalse;
cS.SetActivationFunction(LReLU);
//---
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CNeuronCGConvOCL::feedForward(CNeuronBaseOCL* NeuronOCL)
{
if(!NeuronOCL || !NeuronOCL.getOutput() || NeuronOCL.getOutputIndex() < 0)
ReturnFalse;
//---
if(cInputF.getOutputIndex() != NeuronOCL.getOutputIndex())
{
if(!cInputF.getOutput().BufferSet(NeuronOCL.getOutputIndex()))
ReturnFalse;
cInputF.SetActivationFunction((ENUM_ACTIVATION)NeuronOCL.Activation());
}
if(cInputS.getOutputIndex() != NeuronOCL.getOutputIndex())
{
if(!cInputS.getOutput().BufferSet(NeuronOCL.getOutputIndex()))
ReturnFalse;
cInputS.SetActivationFunction((ENUM_ACTIVATION)NeuronOCL.Activation());
}
//---
if(!cF.FeedForward(GetPointer(cInputF)))
ReturnFalse;
if(!cS.FeedForward(GetPointer(cInputS)))
ReturnFalse;
//---
if(!ElementMult(cF.getOutput(), cS.getOutput(), Output))
ReturnFalse;
//---
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CNeuronCGConvOCL::calcInputGradients(CNeuronBaseOCL* prevLayer)
{
if(!prevLayer || !prevLayer.getGradient() || prevLayer.getGradientIndex() < 0)
ReturnFalse;
//---
if(!ElementMultGrad(cF.getOutput(), cF.getGradient(), cS.getOutput(), cS.getGradient(), Gradient, cF.Activation(), cS.Activation()))
ReturnFalse;
//---
if(!cInputF.CalcHiddenGradients((CObject *)GetPointer(cF)))
ReturnFalse;
if(!cInputS.CalcHiddenGradients((CObject *)GetPointer(cS)))
ReturnFalse;
if(!SumAndNormalize(cF.getOutput(), cS.getOutput(), prevLayer.getOutput(), 1, false))
ReturnFalse;
//---
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CNeuronCGConvOCL::updateInputWeights(CNeuronBaseOCL* NeuronOCL)
{
if(!cF.UpdateInputWeights(cInputF.AsObject()))
ReturnFalse;
if(!cS.UpdateInputWeights(cInputS.AsObject()))
ReturnFalse;
//---
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CNeuronCGConvOCL::Save(const int file_handle)
{
if(!CNeuronBaseOCL::Save(file_handle))
ReturnFalse;
if(!cInputF.Save(file_handle))
ReturnFalse;
if(!cInputS.Save(file_handle))
ReturnFalse;
if(!cF.Save(file_handle))
ReturnFalse;
if(!cS.Save(file_handle))
ReturnFalse;
//---
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CNeuronCGConvOCL::Load(const int file_handle)
{
if(!CNeuronBaseOCL::Load(file_handle))
ReturnFalse;
if(FileReadInteger(file_handle) != cInputF.Type() || !cInputF.Load(file_handle))
ReturnFalse;
if(FileReadInteger(file_handle) != cInputS.Type() || !cInputS.Load(file_handle))
ReturnFalse;
if(FileReadInteger(file_handle) != cF.Type() || !cF.Load(file_handle))
ReturnFalse;
if(FileReadInteger(file_handle) != cS.Type() || !cS.Load(file_handle))
ReturnFalse;
//---
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CNeuronCGConvOCL::WeightsUpdate(CNeuronBaseOCL* source, float tau)
{
if(!CNeuronBaseOCL::WeightsUpdate(source, tau))
ReturnFalse;
if(!cInputF.WeightsUpdate(source, tau))
ReturnFalse;
if(!cInputS.WeightsUpdate(source, tau))
ReturnFalse;
if(!cF.WeightsUpdate(source, tau))
ReturnFalse;
if(!cS.WeightsUpdate(source, tau))
ReturnFalse;
//---
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CNeuronCGConvOCL::SetOpenCL(COpenCLMy * obj)
{
CNeuronBaseOCL::SetOpenCL(obj);
cInputF.SetOpenCL(OpenCL);
cInputS.SetOpenCL(OpenCL);
cF.SetOpenCL(OpenCL);
cS.SetOpenCL(OpenCL);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CNeuronAGCN::Init(uint numOutputs, uint myIndex, COpenCLMy *open_cl,
uint units_count, uint dimension,
ENUM_OPTIMIZATION optimization_type, uint batch)
{
if(!CNeuronBaseOCL::Init(numOutputs, myIndex, open_cl,
units_count * dimension, optimization_type, batch))
ReturnFalse;
//---
int index = 0;
if(!cEa.Init(0, index, OpenCL, Neurons(), optimization, iBatch))
ReturnFalse;
cEa.SetActivationFunction(None);
index++;
if(!cWx.Init(0, index, OpenCL, dimension, dimension, dimension, units_count, 1, optimization, iBatch))
ReturnFalse;
index++;
if(!cWe.Init(0, index, OpenCL, dimension, dimension, dimension, units_count, 1, optimization, iBatch))
ReturnFalse;
index++;
if(!cWconcat_ex.Init(0, index, OpenCL, 2 * Neurons(), optimization, iBatch))
ReturnFalse;
cWconcat_ex.SetActivationFunction(None);
index++;
if(!cEn.Init(0, index, OpenCL, 2 * dimension, 2 * dimension, dimension, units_count, 1, optimization, iBatch))
ReturnFalse;
cEn.SetActivationFunction(None);
index++;
if(!cEnT.Init(0, index, OpenCL, units_count, dimension, optimization, iBatch))
ReturnFalse;
index++;
if(!cEnEnT.Init(0, index, OpenCL, units_count * units_count, optimization, iBatch))
ReturnFalse;
cEnEnT.SetActivationFunction(GELU);
index++;
if(!cAadapt.Init(0, index, OpenCL, units_count * units_count, optimization, iBatch))
ReturnFalse;
cAadapt.SetHeads(units_count);
index++;
if(!cAadaptX.Init(0, index, OpenCL, Neurons(), optimization, iBatch))
ReturnFalse;
cAadaptX.SetActivationFunction(None);
index++;
if(!cApreX.Init(0, index, OpenCL, Neurons(), optimization, iBatch))
ReturnFalse;
cApreX.SetActivationFunction(None);
index++;
if(!cWadapt.Init(0, index, OpenCL, dimension, dimension, dimension, units_count, 1, optimization, iBatch))
ReturnFalse;
cWadapt.SetActivationFunction(None);
index++;
if(!cWpre.Init(0, index, OpenCL, dimension, dimension, dimension, units_count, 1, optimization, iBatch))
ReturnFalse;
cWpre.SetActivationFunction(None);
SetActivationFunction(None);
//---
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CNeuronAGCN::feedForward(CNeuronBaseOCL *NeuronOCL, CBufferFloat *SecondInput)
{
if(!SecondInput || SecondInput.Total() < cAadapt.Neurons())
ReturnFalse;
//---
if(bTrain)
{
if(!cEa.FeedForward())
ReturnFalse;
if(!cWe.FeedForward(cEa.AsObject()))
ReturnFalse;
}
//---
if(!cWx.FeedForward(NeuronOCL))
ReturnFalse;
if(!Concat(cWx.getOutput(), cWe.getOutput(), cWconcat_ex.getOutput(), cWx.GetWindowOut(), cWe.GetWindowOut(), cWx.GetUnits()))
ReturnFalse;
if(!cEn.FeedForward(cWconcat_ex.AsObject()))
ReturnFalse;
if(!cEnT.FeedForward(cEn.AsObject()))
ReturnFalse;
if(!MatMul(cEn.getOutput(), cEnT.getOutput(), cEnEnT.getOutput(), cEnT.GetCount(), cEnT.GetWindow(), cEnT.GetCount()))
ReturnFalse;
if(cEnEnT.Activation() != None)
if(!Activation(cEnEnT.getOutput(), cEnEnT.getOutput(), cEnEnT.Activation()))
ReturnFalse;
if(!cAadapt.FeedForward(cEnEnT.AsObject()))
ReturnFalse;
if(!IdentSum(cAadapt.getOutput(), cAadapt.getOutput(), cAadapt.Heads()))
ReturnFalse;
if(!MatMul(SecondInput, NeuronOCL.getOutput(), cApreX.getOutput(),
cWpre.GetUnits(), cWpre.GetUnits(), cWpre.GetWindow()))
ReturnFalse;
if(!MatMul(cAadapt.getOutput(), NeuronOCL.getOutput(), cAadaptX.getOutput(),
cWadapt.GetUnits(), cWadapt.GetUnits(), cWadapt.GetWindow()))
ReturnFalse;
if(!cWpre.FeedForward(cApreX.AsObject()))
ReturnFalse;
if(!cWadapt.FeedForward(cAadaptX.AsObject()))
ReturnFalse;
if(!SumAndNormalize(cWadapt.getOutput(), cWpre.getOutput(), Output, cWadapt.GetWindowOut(), true))
ReturnFalse;
//---
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CNeuronAGCN::calcInputGradients(CNeuronBaseOCL *NeuronOCL,
CBufferFloat *SecondInput,
CBufferFloat *SecondGradient,
ENUM_ACTIVATION SecondActivation = None)
{
if(!NeuronOCL || !SecondInput || !SecondGradient ||
SecondInput.Total() < cAadapt.Neurons() ||
SecondGradient.Total() < cAadapt.Neurons())
ReturnFalse;
//---
if(!DeActivation(cWadapt.getOutput(), cWadapt.getGradient(), Gradient, cWadapt.Activation()))
ReturnFalse;
if(!DeActivation(cWpre.getOutput(), cWpre.getGradient(), Gradient, cWpre.Activation()))
ReturnFalse;
if(!cApreX.CalcHiddenGradients(cWpre.AsObject()))
ReturnFalse;
if(!cAadaptX.CalcHiddenGradients(cWadapt.AsObject()))
ReturnFalse;
if(!MatMulGrad(SecondInput, SecondGradient,
NeuronOCL.getOutput(), NeuronOCL.getGradient(),
cApreX.getGradient(), cWpre.GetUnits(),
cWpre.GetUnits(), cWpre.GetWindow()))
ReturnFalse;
if(SecondActivation != None)
if(!DeActivation(SecondInput, SecondGradient,
SecondGradient, SecondActivation))
ReturnFalse;
//---
if(!MatMulGrad(cAadapt.getOutput(), cAadapt.getGradient(),
NeuronOCL.getOutput(), PrevOutput,
cAadaptX.getGradient(), cWadapt.GetUnits(),
cWadapt.GetUnits(), cWadapt.GetWindow()))
ReturnFalse;
if(!SumAndNormalize(NeuronOCL.getGradient(), PrevOutput,
PrevOutput, cWx.GetWindow(), false))
ReturnFalse;
if(NeuronOCL.Activation() != None)
if(!DeActivation(NeuronOCL.getOutput(), PrevOutput,
PrevOutput, NeuronOCL.Activation()))
ReturnFalse;
if(!cEnEnT.CalcHiddenGradients(cAadapt.AsObject()))
ReturnFalse;
if(cEnEnT.Activation() != None)
if(!DeActivation(cEnEnT.getOutput(), cEnEnT.getGradient(),
cEnEnT.getGradient(), cEnEnT.Activation()))
ReturnFalse;
if(!MatMulGrad(cEn.getOutput(), cEn.getPrevOutput(),
cEnT.getOutput(), cEnT.getGradient(),
cEnEnT.getGradient(), cEnT.GetCount(),
cEnT.GetWindow(), cEnT.GetCount()))
ReturnFalse;
if(!cEn.CalcHiddenGradients(cEnT.AsObject()))
ReturnFalse;
if(!SumAndNormalize(cEn.getGradient(), cEn.getPrevOutput(),
cEn.getGradient(), cEnT.GetWindow(), false))
ReturnFalse;
if(cEn.Activation() != None)
if(!DeActivation(cEn.getOutput(), cEn.getGradient(),
cEn.getGradient(), cEn.Activation()))
ReturnFalse;
if(!cWconcat_ex.CalcHiddenGradients(cEn.AsObject()))
ReturnFalse;
if(!DeConcat(cWx.getGradient(), cWe.getGradient(), cWconcat_ex.getGradient(),
cWx.GetWindowOut(), cWe.GetWindowOut(), cWx.GetUnits()))
ReturnFalse;
if(cWx.Activation() != None)
if(!DeActivation(cWx.getOutput(), cWx.getGradient(),
cWx.getGradient(), cWx.Activation()))
ReturnFalse;
if(cWe.Activation() != None)
if(!DeActivation(cWe.getOutput(), cWe.getGradient(),
cWe.getGradient(), cWe.Activation()))
ReturnFalse;
if(!NeuronOCL.CalcHiddenGradients(cWx.AsObject()))
ReturnFalse;
if(!SumAndNormalize(NeuronOCL.getGradient(), PrevOutput,
NeuronOCL.getGradient(), cWx.GetWindow(), false))
ReturnFalse;
if(!cEa.CalcHiddenGradients(cWe.AsObject()))
ReturnFalse;
//---
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CNeuronAGCN::updateInputWeights(CNeuronBaseOCL *NeuronOCL, CBufferFloat *second)
{
if(!cEa.UpdateInputWeights())
ReturnFalse;
if(!cWe.UpdateInputWeights(cEa.AsObject()))
ReturnFalse;
if(!cWx.UpdateInputWeights(NeuronOCL))
ReturnFalse;
if(!cEn.UpdateInputWeights(cWconcat_ex.AsObject()))
ReturnFalse;
if(!cWpre.UpdateInputWeights(cApreX.AsObject()))
ReturnFalse;
if(!cWadapt.UpdateInputWeights(cAadaptX.AsObject()))
ReturnFalse;
//---
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CNeuronAGCN::WeightsUpdate(CNeuronBaseOCL *source, float tau)
{
if(!CNeuronBaseOCL::WeightsUpdate(source, tau))
ReturnFalse;
CNeuronAGCN* Source = source;
if(!cEa.WeightsUpdate(Source.cEa.AsObject(), tau))
ReturnFalse;
if(!cWe.WeightsUpdate(Source.cWe.AsObject(), tau))
ReturnFalse;
if(!cWx.WeightsUpdate(Source.cWx.AsObject(), tau))
ReturnFalse;
if(!cEn.WeightsUpdate(Source.cEn.AsObject(), tau))
ReturnFalse;
if(!cWpre.WeightsUpdate(Source.cWpre.AsObject(), tau))
ReturnFalse;
if(!cWadapt.WeightsUpdate(Source.cWadapt.AsObject(), tau))
ReturnFalse;
//---
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CNeuronAGCN::Save(const int file_handle)
{
if(!CNeuronBaseOCL::Save(file_handle))
ReturnFalse;
if(!cEa.Save(file_handle))
ReturnFalse;
if(!cWe.Save(file_handle))
ReturnFalse;
if(!cWx.Save(file_handle))
ReturnFalse;
if(!cEn.Save(file_handle))
ReturnFalse;
if(!cWpre.Save(file_handle))
ReturnFalse;
if(!cWadapt.Save(file_handle))
ReturnFalse;
//---
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CNeuronAGCN::Load(const int file_handle)
{
if(!CNeuronBaseOCL::Load(file_handle))
ReturnFalse;
if(!LoadInsideLayer(file_handle, cEa.AsObject()))
ReturnFalse;
if(!LoadInsideLayer(file_handle, cWe.AsObject()))
ReturnFalse;
if(!LoadInsideLayer(file_handle, cWx.AsObject()))
ReturnFalse;
if(!LoadInsideLayer(file_handle, cEn.AsObject()))
ReturnFalse;
if(!LoadInsideLayer(file_handle, cWpre.AsObject()))
ReturnFalse;
if(!LoadInsideLayer(file_handle, cWadapt.AsObject()))
ReturnFalse;
//---
uint units_count = GetUnits();
uint dimension = GetWindow();
//---
int index = 3;
if(!cWconcat_ex.Init(0, index, OpenCL, 2 * Neurons(), optimization, iBatch))
ReturnFalse;
cWconcat_ex.SetActivationFunction(None);
index += 2;
if(!cEnT.Init(0, index, OpenCL, units_count, dimension, optimization, iBatch))
ReturnFalse;
index++;
if(!cEnEnT.Init(0, index, OpenCL, units_count * units_count, optimization, iBatch))
ReturnFalse;
cEnEnT.SetActivationFunction(GELU);
index++;
if(!cAadapt.Init(0, index, OpenCL, units_count * units_count, optimization, iBatch))
ReturnFalse;
cAadapt.SetHeads(units_count);
index++;
if(!cAadaptX.Init(0, index, OpenCL, Neurons(), optimization, iBatch))
ReturnFalse;
cAadaptX.SetActivationFunction(None);
index++;
if(!cApreX.Init(0, index, OpenCL, Neurons(), optimization, iBatch))
ReturnFalse;
cApreX.SetActivationFunction(None);
//---
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CNeuronAGCN::SetOpenCL(COpenCLMy *obj)
{
CNeuronBaseOCL::SetOpenCL(obj);
cEa.SetOpenCL(OpenCL);
cWe.SetOpenCL(OpenCL);
cWx.SetOpenCL(OpenCL);
cEn.SetOpenCL(OpenCL);
cWpre.SetOpenCL(OpenCL);
cWadapt.SetOpenCL(OpenCL);
cWconcat_ex.SetOpenCL(OpenCL);
cEnT.SetOpenCL(OpenCL);
cEnEnT.SetOpenCL(OpenCL);
cAadapt.SetOpenCL(OpenCL);
cAadaptX.SetOpenCL(OpenCL);
cApreX.SetOpenCL(OpenCL);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CNeuronAGCN::TrainMode(bool flag)
{
CNeuronBaseOCL::TrainMode(flag);
cEa.TrainMode(bTrain);
cWe.TrainMode(bTrain);
cWx.TrainMode(bTrain);
cEn.TrainMode(bTrain);
cWpre.TrainMode(bTrain);
cWadapt.TrainMode(bTrain);
cWconcat_ex.TrainMode(bTrain);
cEnT.TrainMode(bTrain);
cEnEnT.TrainMode(bTrain);
cAadapt.TrainMode(bTrain);
cAadaptX.TrainMode(bTrain);
cApreX.TrainMode(bTrain);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CNeuronGinARCell::Init(uint numOutputs, uint myIndex, COpenCLMy *open_cl,
uint units_count, uint dimension,
ENUM_OPTIMIZATION optimization_type, uint batch)
{
if(!CNeuronBaseOCL::Init(numOutputs, myIndex, open_cl,
units_count * dimension, optimization_type, batch))
ReturnFalse;
//---
int index = 0;
if(!cX_IA.Init(0, index, OpenCL, units_count, dimension, optimization, iBatch))
ReturnFalse;
index++;
if(!cX_AGCN.Init(0, index, OpenCL, units_count, dimension, optimization, iBatch))
ReturnFalse;
index++;
if(!cForgetGate.Init(0, index, OpenCL, units_count, dimension, optimization, iBatch))
ReturnFalse;
index++;
if(!cResetGate.Init(0, index, OpenCL, units_count, dimension, optimization, iBatch))
ReturnFalse;
index++;
if(!cContext.Init(0, index, OpenCL, units_count * dimension, optimization, iBatch))
ReturnFalse;
if(!cContext.getPrevOutput().Fill(0))
ReturnFalse;
cContext.SetActivationFunction(None);
bTemp.BufferFree();
if(!bTemp.BufferInit(units_count * units_count, 0) ||
!bTemp.BufferCreate(OpenCL))
ReturnFalse;
//---
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CNeuronGinARCell::feedForward(CNeuronBaseOCL *NeuronOCL, CBufferFloat *SecondInput)
{
if(!cX_IA.FeedForward(NeuronOCL))
ReturnFalse;
if(!cX_AGCN.FeedForward(cX_IA.AsObject(), SecondInput))
ReturnFalse;
if(!cForgetGate.FeedForward(cX_IA.AsObject(), SecondInput))
ReturnFalse;
if(!cResetGate.FeedForward(cX_IA.AsObject(), SecondInput))
ReturnFalse;
if(!Activation(cForgetGate.getOutput(), cForgetGate.getOutput(), GELU))
ReturnFalse;
if(!Activation(cResetGate.getOutput(), cResetGate.getOutput(), GELU))
ReturnFalse;
//--- Context
if(!cContext.SwapOutputs())
ReturnFalse;
if(!GateElementMult(cContext.getPrevOutput(), cX_AGCN.getOutput(), cForgetGate.getOutput(), cContext.getOutput()))
ReturnFalse;
//--- Output
if(!Activation(cContext.getOutput(), cContext.getPrevOutput(), ELU))
ReturnFalse;
if(!GateElementMult(cContext.getPrevOutput(), cX_IA.getOutput(), cResetGate.getOutput(), Output))
ReturnFalse;
//---
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CNeuronGinARCell::calcInputGradients(CNeuronBaseOCL *NeuronOCL,
CBufferFloat *SecondInput,
CBufferFloat *SecondGradient,
ENUM_ACTIVATION SecondActivation = None)
{
if(!NeuronOCL || !SecondInput || !SecondGradient)
ReturnFalse;
//--- Output
if(!GateElementMultGrad(cContext.getPrevOutput(), cContext.getGradient(),
cX_IA.getOutput(), cX_IA.getPrevOutput(),
cResetGate.getOutput(), cResetGate.getGradient(),
Gradient, ELU, cX_IA.Activation(), GELU))
ReturnFalse;
//--- Context
if(!GateElementMultGrad(cContext.getOutput(), cContext.getPrevOutput(),
cX_AGCN.getOutput(), cX_AGCN.getGradient(),
cForgetGate.getOutput(), cForgetGate.getGradient(),
cContext.getGradient(), None,
cX_AGCN.Activation(), GELU))
ReturnFalse;
//--- Gradient to Interposition Attention
if(!cX_IA.CalcHiddenGradients(cX_AGCN.AsObject(), SecondInput, SecondGradient, SecondActivation) ||
!SumAndNormalize(cX_IA.getGradient(), cX_IA.getPrevOutput(), cX_IA.getPrevOutput(), cForgetGate.GetWindow(), false, 0, 0, 0, 1))
ReturnFalse;
if(!cX_IA.CalcHiddenGradients(cForgetGate.AsObject(), SecondInput, GetPointer(bTemp), SecondActivation) ||
!SumAndNormalize(cX_IA.getGradient(), cX_IA.getPrevOutput(), cX_IA.getPrevOutput(), cForgetGate.GetWindow(), false, 0, 0, 0, 1) ||
!SumAndNormalize(SecondGradient, GetPointer(bTemp), SecondGradient, cForgetGate.GetUnits(), false, 0, 0, 0, 1))
ReturnFalse;
if(!cX_IA.CalcHiddenGradients(cResetGate.AsObject(), SecondInput, GetPointer(bTemp), SecondActivation) ||
!SumAndNormalize(cX_IA.getGradient(), cX_IA.getPrevOutput(), cX_IA.getPrevOutput(), cForgetGate.GetWindow(), false, 0, 0, 0, 1) ||
!SumAndNormalize(SecondGradient, GetPointer(bTemp), SecondGradient, cForgetGate.GetUnits(), false, 0, 0, 0, 1))
ReturnFalse;
//---
if(!NeuronOCL.CalcHiddenGradients(cX_IA.AsObject()))
ReturnFalse;
//---
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CNeuronGinARCell::updateInputWeights(CNeuronBaseOCL *NeuronOCL, CBufferFloat *second)
{
if(!cX_IA.UpdateInputWeights(NeuronOCL))
ReturnFalse;
if(!cX_AGCN.UpdateInputWeights(cX_IA.AsObject(), second))
ReturnFalse;
if(!cForgetGate.UpdateInputWeights(cX_IA.AsObject(), second))
ReturnFalse;
if(!cResetGate.UpdateInputWeights(cX_IA.AsObject(), second))
ReturnFalse;
//---
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CNeuronGinARCell::WeightsUpdate(CNeuronBaseOCL *source, float tau)
{
if(!CNeuronBaseOCL::WeightsUpdate(source, tau))
ReturnFalse;
CNeuronGinARCell* Source = source;
if(!cX_IA.WeightsUpdate(Source.cX_IA.AsObject(), tau))
ReturnFalse;
if(!cX_AGCN.WeightsUpdate(Source.cX_AGCN.AsObject(), tau))
ReturnFalse;
if(!cForgetGate.WeightsUpdate(Source.cForgetGate.AsObject(), tau))
ReturnFalse;
if(!cResetGate.WeightsUpdate(Source.cResetGate.AsObject(), tau))
ReturnFalse;
//---
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CNeuronGinARCell::Save(const int file_handle)
{
if(!CNeuronBaseOCL::Save(file_handle))
ReturnFalse;
if(!cX_IA.Save(file_handle))
ReturnFalse;
if(!cX_AGCN.Save(file_handle))
ReturnFalse;
if(!cForgetGate.Save(file_handle))
ReturnFalse;
if(!cResetGate.Save(file_handle))
ReturnFalse;
//---
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CNeuronGinARCell::Load(const int file_handle)
{
if(!CNeuronBaseOCL::Load(file_handle))
ReturnFalse;
if(!LoadInsideLayer(file_handle, cX_IA.AsObject()))
ReturnFalse;
if(!LoadInsideLayer(file_handle, cX_AGCN.AsObject()))
ReturnFalse;
if(!LoadInsideLayer(file_handle, cForgetGate.AsObject()))
ReturnFalse;
if(!LoadInsideLayer(file_handle, cResetGate.AsObject()))
ReturnFalse;
//---
int index = 4;
if(!cContext.Init(0, index, OpenCL, Neurons(), optimization, iBatch))
ReturnFalse;
if(!cContext.getPrevOutput().Fill(0))
ReturnFalse;
cContext.SetActivationFunction(None);
bTemp.BufferFree();
if(!bTemp.BufferInit(uint(MathPow(cForgetGate.GetUnits(), 2)), 0) ||
!bTemp.BufferCreate(OpenCL))
ReturnFalse;
//---
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CNeuronGinARCell::SetOpenCL(COpenCLMy *obj)
{
CNeuronBaseOCL::SetOpenCL(obj);
cX_IA.SetOpenCL(OpenCL);
cX_AGCN.SetOpenCL(OpenCL);
cForgetGate.SetOpenCL(OpenCL);
cResetGate.SetOpenCL(OpenCL);
cContext.SetOpenCL(OpenCL);
bTemp.BufferFree();
bTemp.BufferInit(uint(MathPow(cForgetGate.GetUnits(), 2)), 0);
bTemp.BufferCreate(OpenCL);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CNeuronGinARCell::TrainMode(bool flag)
{
CNeuronBaseOCL::TrainMode(flag);
cX_IA.TrainMode(bTrain);
cX_AGCN.TrainMode(bTrain);
cForgetGate.TrainMode(bTrain);
cResetGate.SetOpenCL(OpenCL);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CNeuronGinARCell::Clear(void)
{
if(!CNeuronBaseOCL::Clear())
ReturnFalse;
if(!cContext.getPrevOutput() ||
!cContext.getPrevOutput().Fill(0))
ReturnFalse;
//---
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CNeuronGinAR::Init(uint numOutputs, uint myIndex, COpenCLMy *open_cl,
uint units_count, uint dimension,
ENUM_OPTIMIZATION optimization_type, uint batch)
{
if(!CNeuronSwiGLUOCL::Init(numOutputs, myIndex, open_cl, caCells.Size()*dimension,
caCells.Size()*dimension, dimension, units_count, 1,
optimization_type, batch))
ReturnFalse;
int index = 0;
if(!cEa.Init(0, index, OpenCL, Neurons(), optimization, iBatch))
ReturnFalse;
cEa.SetActivationFunction(None);
index++;
if(!cWx.Init(0, index, OpenCL, dimension, dimension, dimension, units_count, 1, optimization, iBatch))
ReturnFalse;
index++;
if(!cWe.Init(0, index, OpenCL, dimension, dimension, dimension, units_count, 1, optimization, iBatch))
ReturnFalse;
if(!cWconcat_ex.Init(0, index, OpenCL, 2 * Neurons(), optimization, iBatch))
ReturnFalse;
cWconcat_ex.SetActivationFunction(None);
index++;
if(!cEn.Init(0, index, OpenCL, 2 * dimension, 2 * dimension, dimension, units_count, 1, optimization, iBatch))
ReturnFalse;
cEn.SetActivationFunction(None);
index++;
if(!cEnT.Init(0, index, OpenCL, units_count, dimension, optimization, iBatch))
ReturnFalse;
index++;
if(!cEnEnT.Init(0, index, OpenCL, units_count * units_count, optimization, iBatch))
ReturnFalse;
cEnEnT.SetActivationFunction(GELU);
index++;
if(!cApre.Init(0, index, OpenCL, units_count * units_count, optimization, iBatch))
ReturnFalse;
cApre.SetHeads(units_count);
for(uint i = 0; i < caCells.Size(); i++)
{
index++;
if(!caCells[i].Init(0, index, OpenCL, units_count, dimension, optimization, iBatch))
ReturnFalse;
}
index++;
if(!cConcat.Init(0, index, OpenCL, GetWindow()*units_count, optimization, iBatch))
ReturnFalse;
//---
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CNeuronGinAR::feedForward(CNeuronBaseOCL *NeuronOCL)
{
//--- Calculate Apre
if(bTrain)
{
if(!cEa.FeedForward())
ReturnFalse;
if(!cWe.FeedForward(cEa.AsObject()))
ReturnFalse;
}
//---
if(!cWx.FeedForward(NeuronOCL))
ReturnFalse;
if(!Concat(cWx.getOutput(), cWe.getOutput(), cWconcat_ex.getOutput(), cWx.GetWindowOut(), cWe.GetWindowOut(), cWx.GetUnits()))
ReturnFalse;
if(!cEn.FeedForward(cWconcat_ex.AsObject()))
ReturnFalse;
if(!cEnT.FeedForward(cEn.AsObject()))
ReturnFalse;
if(!MatMul(cEn.getOutput(), cEnT.getOutput(), cEnEnT.getOutput(), cEnT.GetCount(), cEnT.GetWindow(), cEnT.GetCount()))
ReturnFalse;
if(cEnEnT.Activation() != None)
if(!Activation(cEnEnT.getOutput(), cEnEnT.getOutput(), cEnEnT.Activation()))
ReturnFalse;
if(!cApre.FeedForward(cEnEnT.AsObject()))
ReturnFalse;
if(!IdentSum(cApre.getOutput(), cApre.getOutput(), cApre.Heads()))
ReturnFalse;
//--- GimAR Cells
CNeuronBaseOCL *temp = NeuronOCL;
for(uint i = 0; i < caCells.Size(); i++)
{
if(!caCells[i].FeedForward(temp, cApre.getOutput()))
ReturnFalse;
temp = caCells[i].AsObject();
}
//---
if(!Concat(caCells[0].getOutput(), caCells[1].getOutput(), caCells[2].getOutput(), caCells[3].getOutput(),
cConcat.getOutput(), GetWindow() / 4, GetWindow() / 4, GetWindow() / 4, GetWindow() / 4, GetUnits()))
ReturnFalse;
//---
return CNeuronSwiGLUOCL::feedForward(cConcat.AsObject());
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CNeuronGinAR::calcInputGradients(CNeuronBaseOCL *NeuronOCL)
{
if(!NeuronOCL)
ReturnFalse;
//---
if(!CNeuronSwiGLUOCL::calcInputGradients(cConcat.AsObject()))
ReturnFalse;
if(!DeConcat(caCells[0].getPrevOutput(), caCells[1].getPrevOutput(),
caCells[2].getPrevOutput(), caCells[3].getGradient(),
cConcat.getGradient(), GetWindow() / 4,
GetWindow() / 4, GetWindow() / 4,
GetWindow() / 4, GetUnits()))
ReturnFalse;
//--- GimAR Cells
cApre.getGradient().Fill(0);
for(uint i = caCells.Size() - 1; i > 0; i--)
if(!caCells[i - 1].CalcHiddenGradients(caCells[i].AsObject(), cApre.getOutput(),
cApre.getPrevOutput(),
(ENUM_ACTIVATION)cApre.Activation()) ||
!SumAndNormalize(caCells[i - 1].getGradient(), caCells[i - 1].getPrevOutput(),
caCells[i - 1].getGradient(), cWx.GetWindow(), false, 0, 0, 0, 1) ||
!SumAndNormalize(cApre.getGradient(), cApre.getPrevOutput(),
cApre.getGradient(), GetUnits(), false, 0, 0, 0, 1))
ReturnFalse;
if(!NeuronOCL.CalcHiddenGradients(caCells[0].AsObject(), cApre.getOutput(),
cApre.getPrevOutput(), (ENUM_ACTIVATION)cApre.Activation()) ||
!SumAndNormalize(cApre.getGradient(), cApre.getPrevOutput(),
cApre.getGradient(), GetUnits(), false, 0, 0, 0, 1))
ReturnFalse;
//---
if(!cEnEnT.CalcHiddenGradients(cApre.AsObject()))
ReturnFalse;
if(cEnEnT.Activation() != None)
if(!DeActivation(cEnEnT.getOutput(), cEnEnT.getGradient(),
cEnEnT.getGradient(), cEnEnT.Activation()))
ReturnFalse;
if(!MatMulGrad(cEn.getOutput(), cEn.getPrevOutput(),
cEnT.getOutput(), cEnT.getGradient(),
cEnEnT.getGradient(), cEnT.GetCount(),
cEnT.GetWindow(), cEnT.GetCount()))
ReturnFalse;
if(!cEn.CalcHiddenGradients(cEnT.AsObject()))
ReturnFalse;
if(!SumAndNormalize(cEn.getGradient(), cEn.getPrevOutput(),
cEn.getGradient(), cEnT.GetWindow(), false, 0, 0, 0, 1))
ReturnFalse;
if(cEn.Activation() != None)
if(!DeActivation(cEn.getOutput(), cEn.getGradient(),
cEn.getGradient(), cEn.Activation()))
ReturnFalse;
if(!cWconcat_ex.CalcHiddenGradients(cEn.AsObject()))
ReturnFalse;
if(!DeConcat(cWx.getGradient(), cWe.getGradient(), cWconcat_ex.getGradient(),
cWx.GetWindowOut(), cWe.GetWindowOut(), cWx.GetUnits()))
ReturnFalse;
if(cWx.Activation() != None)
if(!DeActivation(cWx.getOutput(), cWx.getGradient(),
cWx.getGradient(), cWx.Activation()))
ReturnFalse;
if(cWe.Activation() != None)
if(!DeActivation(cWe.getOutput(), cWe.getGradient(),
cWe.getGradient(), cWe.Activation()))
ReturnFalse;
CBufferFloat* temp = NeuronOCL.getGradient();
if(!NeuronOCL.SetGradient(NeuronOCL.getPrevOutput(), false))
ReturnFalse;
if(!NeuronOCL.CalcHiddenGradients(cWx.AsObject()))
ReturnFalse;
if(!SumAndNormalize(NeuronOCL.getGradient(), temp,
NeuronOCL.getGradient(), cWx.GetWindow(), false, 0, 0, 0, 1))
ReturnFalse;
if(!NeuronOCL.SetGradient(temp, false))
ReturnFalse;
if(!cEa.CalcHiddenGradients(cWe.AsObject()))
ReturnFalse;
//---
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CNeuronGinAR::updateInputWeights(CNeuronBaseOCL *NeuronOCL)
{
//--- Apre
if(!cEa.UpdateInputWeights())
ReturnFalse;
if(!cWe.UpdateInputWeights(cEa.AsObject()))
ReturnFalse;
//---
if(!cWx.UpdateInputWeights(NeuronOCL))
ReturnFalse;
if(!cEn.UpdateInputWeights(cWconcat_ex.AsObject()))
ReturnFalse;
//--- GimAR Cells
CNeuronBaseOCL *temp = NeuronOCL;
for(uint i = 0; i < caCells.Size(); i++)
{
if(!caCells[i].UpdateInputWeights(temp, cApre.getOutput()))
ReturnFalse;
temp = caCells[i].AsObject();
}
//---
return CNeuronSwiGLUOCL::updateInputWeights(cConcat.AsObject());
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CNeuronGinAR::WeightsUpdate(CNeuronBaseOCL *source, float tau)
{
if(!CNeuronSwiGLUOCL::WeightsUpdate(source, tau))
ReturnFalse;
//---
CNeuronGinAR* Source = source;
//--- Apre
if(!cEa.WeightsUpdate(Source.cEa.AsObject(), tau))
ReturnFalse;
if(!cWe.WeightsUpdate(Source.cWe.AsObject(), tau))
ReturnFalse;
if(!cWx.WeightsUpdate(Source.cWx.AsObject(), tau))
ReturnFalse;
if(!cEn.WeightsUpdate(Source.cEn.AsObject(), tau))
ReturnFalse;
//--- GimAR Cells
for(uint i = 0; i < caCells.Size(); i++)
if(!caCells[i].WeightsUpdate(Source.caCells[i].AsObject(), tau))
ReturnFalse;
//---
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CNeuronGinAR::Save(const int file_handle)
{
if(!CNeuronSwiGLUOCL::Save(file_handle))
ReturnFalse;
//--- Apre
if(!cEa.Save(file_handle))
ReturnFalse;
if(!cWe.Save(file_handle))
ReturnFalse;
if(!cWx.Save(file_handle))
ReturnFalse;
if(!cEn.Save(file_handle))
ReturnFalse;
//--- GimAR Cells
for(uint i = 0; i < caCells.Size(); i++)
if(!caCells[i].Save(file_handle))
ReturnFalse;
//---
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CNeuronGinAR::Load(const int file_handle)
{
if(!CNeuronSwiGLUOCL::Load(file_handle))
ReturnFalse;
//--- Apre
if(!LoadInsideLayer(file_handle, cEa.AsObject()))
ReturnFalse;
if(!LoadInsideLayer(file_handle, cWe.AsObject()))
ReturnFalse;
if(!LoadInsideLayer(file_handle, cWx.AsObject()))
ReturnFalse;
if(!LoadInsideLayer(file_handle, cEn.AsObject()))
ReturnFalse;
//--- GimAR Cells
for(uint i = 0; i < caCells.Size(); i++)
if(!LoadInsideLayer(file_handle, caCells[i].AsObject()))
ReturnFalse;
//---
uint units_count = GetUnits();
uint dimension = cWx.GetWindow();
uint index = 3;
if(!cWconcat_ex.Init(0, index, OpenCL, 2 * Neurons(), optimization, iBatch))
ReturnFalse;
cWconcat_ex.SetActivationFunction(None);
index += 2;
if(!cEnT.Init(0, index, OpenCL, units_count, dimension, optimization, iBatch))
ReturnFalse;
index++;
if(!cEnEnT.Init(0, index, OpenCL, units_count * units_count, optimization, iBatch))
ReturnFalse;
cEnEnT.SetActivationFunction(GELU);
index++;
if(!cApre.Init(0, index, OpenCL, units_count * units_count, optimization, iBatch))
ReturnFalse;
cApre.SetHeads(units_count);
index += caCells.Size();
if(!cConcat.Init(0, index, OpenCL, GetWindow()*units_count, optimization, iBatch))
ReturnFalse;
//---
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CNeuronGinAR::SetOpenCL(COpenCLMy *obj)
{
CNeuronSwiGLUOCL::SetOpenCL(obj);
//--- Apre
cEa.SetOpenCL(OpenCL);
cWe.SetOpenCL(OpenCL);
cWx.SetOpenCL(OpenCL);
cEn.SetOpenCL(OpenCL);
//--- GimAR Cells
for(uint i = 0; i < caCells.Size(); i++)
caCells[i].SetOpenCL(OpenCL);
//---
cWconcat_ex.SetOpenCL(OpenCL);
cEnT.SetOpenCL(OpenCL);
cEnEnT.SetOpenCL(OpenCL);
cApre.SetOpenCL(OpenCL);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CNeuronGinAR::TrainMode(bool flag)
{
CNeuronSwiGLUOCL::TrainMode(flag);
//--- Apre
cEa.TrainMode(bTrain);
cWe.TrainMode(bTrain);
cWx.TrainMode(bTrain);
cEn.TrainMode(bTrain);
//--- GimAR Cells
for(uint i = 0; i < caCells.Size(); i++)
caCells[i].TrainMode(bTrain);
//---
cWconcat_ex.TrainMode(bTrain);
cEnT.TrainMode(bTrain);
cEnEnT.TrainMode(bTrain);
cApre.TrainMode(bTrain);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CNeuronGinAR::Clear(void)
{
if(!CNeuronSwiGLUOCL::Clear())
ReturnFalse;
for(uint i = 0; i < caCells.Size(); i++)
if(!caCells[i].Clear())
ReturnFalse;
//---
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CNeuronAdaptSpatialNorm::Init(uint numOutputs, uint myIndex, COpenCLMy *open_cl,
uint units_count, uint variables,
ENUM_OPTIMIZATION optimization_type, uint batch)
{
if(!CNeuronBaseOCL::Init(numOutputs, myIndex, open_cl, units_count * variables, optimization_type, batch))
ReturnFalse;
//---
iVariables = variables;
iCount = units_count;
//---
uint dimension = (iVariables + 1) / 2;
uint index = 0;
if(!cEn.Init(0, index, OpenCL, iVariables * dimension, optimization, iBatch))
ReturnFalse;
cEn.SetActivationFunction(None);
index++;
if(!cEnT.Init(0, index, OpenCL, iVariables, dimension, optimization, iBatch))
ReturnFalse;
cEnT.SetActivationFunction(None);
index++;
if(!cEnEnT.Init(0, index, OpenCL, iVariables * iVariables, optimization, iBatch))
ReturnFalse;
cEnEnT.SetActivationFunction(None);
index++;
if(!cAttan.Init(0, index, OpenCL, iVariables * iVariables, optimization, iBatch))
ReturnFalse;
cAttan.SetHeads(iVariables);
//---
index++;
if(!cMeanSTDevs.Init(0, index, OpenCL, 2 * Neurons(), optimization, iBatch))
ReturnFalse;
cMeanSTDevs.SetActivationFunction(None);
//---
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CNeuronAdaptSpatialNorm::AdaptSpatialNorm(CNeuronBaseOCL *NeuronOCL)
{
if(!OpenCL || !NeuronOCL)
ReturnFalse;
uint global_work_offset[3] = { 0 };
uint global_work_size[] = { iCount, MathMin(iVariables, uint(OpenCL.GetMaxLocalSize(1))), iVariables};
uint local_work_size[] = { 1, global_work_size[1], 1};
//---
uint kernel = def_k_AdaptSpatialNorm;
setBuffer(kernel, def_k_asn_inputs, NeuronOCL.getOutputIndex())
setBuffer(kernel, def_k_asn_mean_stdevs, cMeanSTDevs.getOutputIndex())
setBuffer(kernel, def_k_asn_attention, cAttan.getOutputIndex())
setBuffer(kernel, def_k_asn_outputs, getOutputIndex())
kernelExecuteLoc(kernel, global_work_offset, global_work_size, local_work_size)
#ifdef _DEBUG
if(!Output.BufferRead())
ReturnFalse;
#endif
//---
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CNeuronAdaptSpatialNorm::AdaptSpatialNormGrad(CNeuronBaseOCL *NeuronOCL)
{
if(!OpenCL || !NeuronOCL)
ReturnFalse;
uint global_work_offset[3] = { 0 };
uint global_work_size[] = { MathMax(iVariables, iCount), MathMin(MathMax(iVariables, iCount), uint(OpenCL.GetMaxLocalSize(1))), iVariables};
uint local_work_size[] = { 1, global_work_size[1], 1};
//---
uint kernel = def_k_AdaptSpatialNormGrad;
setBuffer(kernel, def_k_asng_inputs, NeuronOCL.getOutputIndex())
setBuffer(kernel, def_k_asng_inputs_gr, NeuronOCL.getGradientIndex())
setBuffer(kernel, def_k_asng_mean_stdevs, cMeanSTDevs.getOutputIndex())
setBuffer(kernel, def_k_asng_mean_stdevs_gr, cMeanSTDevs.getGradientIndex())
setBuffer(kernel, def_k_asng_attention, cAttan.getOutputIndex())
setBuffer(kernel, def_k_asng_attention_gr, cAttan.getGradientIndex())
setBuffer(kernel, def_k_asng_outputs_gr, getGradientIndex())
setArgument(kernel, def_k_asng_total_inputs, iCount)
kernelExecuteLoc(kernel, global_work_offset, global_work_size, local_work_size)
#ifdef _DEBUG
if(!NeuronOCL.getGradient().BufferRead())
ReturnFalse;
#endif
//---
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CNeuronAdaptSpatialNorm::feedForward(CNeuronBaseOCL *NeuronOCL)
{
if(bTrain)
{
if(!cEn.FeedForward())
ReturnFalse;
if(!cEnT.FeedForward(cEn.AsObject()))
ReturnFalse;
if(!MatMul(cEn.getOutput(), cEnT.getOutput(), cEnEnT.getOutput(),
iVariables, cEnT.GetWindow(), iVariables, 1, false))
ReturnFalse;
if(!cAttan.FeedForward(cEnEnT.AsObject()))
ReturnFalse;
}
//---
return AdaptSpatialNorm(NeuronOCL);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CNeuronAdaptSpatialNorm::calcInputGradients(CNeuronBaseOCL *NeuronOCL)
{
if(!AdaptSpatialNormGrad(NeuronOCL))
ReturnFalse;
if(!cEnEnT.CalcHiddenGradients(cAttan.AsObject()))
ReturnFalse;
if(!MatMulGrad(cEn.getOutput(), cEn.getPrevOutput(),
cEnT.getOutput(), cEnT.getGradient(),
cEnEnT.getGradient(), iVariables,
cEnT.GetWindow(), iVariables, 1, false))
ReturnFalse;
if(!cEn.CalcHiddenGradients(cEnT.AsObject()) ||
!SumAndNormalize(cEn.getGradient(), cEn.getPrevOutput(), cEn.getGradient(),
cEnT.GetWindow(), false, 0, 0, 0, 1))
ReturnFalse;
if(cEn.Activation() != None)
if(!DeActivation(cEn.getOutput(), cEn.getGradient(), cEn.getGradient(), cEn.Activation()))
ReturnFalse;
//---
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CNeuronAdaptSpatialNorm::updateInputWeights(CNeuronBaseOCL *NeuronOCL)
{
return cEn.UpdateInputWeights();
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CNeuronAdaptSpatialNorm::Save(const int file_handle)
{
if(!CNeuronBaseOCL::Save(file_handle))
ReturnFalse;
if(!cEn.Save(file_handle))
ReturnFalse;
if(!cAttan.Save(file_handle))
ReturnFalse;
//---
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CNeuronAdaptSpatialNorm::Load(const int file_handle)
{
if(!CNeuronBaseOCL::Load(file_handle))
ReturnFalse;
if(!LoadInsideLayer(file_handle, cEn.AsObject()))
ReturnFalse;
if(!LoadInsideLayer(file_handle, cAttan.AsObject()))
ReturnFalse;
//---
iVariables = cAttan.Heads();
iCount = Neurons() / iVariables;
uint dimension = cEn.Neurons() / iVariables;
//---
uint index = 1;
if(!cEnT.Init(0, index, OpenCL, iVariables, dimension, optimization, iBatch))
ReturnFalse;
cEnT.SetActivationFunction(None);
index++;
if(!cEnEnT.Init(0, index, OpenCL, iVariables * iVariables, optimization, iBatch))
ReturnFalse;
cEnEnT.SetActivationFunction(None);
index += 2;
if(!cMeanSTDevs.Init(0, index, OpenCL, 2 * Neurons(), optimization, iBatch))
ReturnFalse;
cMeanSTDevs.SetActivationFunction(None);
//---
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CNeuronAdaptSpatialNorm::SetOpenCL(COpenCLMy *obj)
{
CNeuronBaseOCL::SetOpenCL(obj);
cEn.SetOpenCL(OpenCL);
cEnT.SetOpenCL(OpenCL);
cEnEnT.SetOpenCL(OpenCL);
cAttan.SetOpenCL(OpenCL);
cMeanSTDevs.SetOpenCL(OpenCL);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CNeuronAdaptSpatialNorm::WeightsUpdate(CNeuronBaseOCL *source, float tau)
{
if(!CNeuronBaseOCL::WeightsUpdate(source, tau))
ReturnFalse;
CNeuronAdaptSpatialNorm* Source = source;
if(!cEn.WeightsUpdate(Source.cEn.AsObject(), tau))
ReturnFalse;
//---
if(!cEn.FeedForward())
ReturnFalse;
if(!cEnT.FeedForward(cEn.AsObject()))
ReturnFalse;
if(!MatMul(cEn.getOutput(), cEnT.getOutput(), cEnEnT.getOutput(),
iVariables, cEnT.GetWindow(), iVariables, 1, false))
ReturnFalse;
if(!cAttan.FeedForward(cEnEnT.AsObject()))
ReturnFalse;
//---
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CNeuronSCNNEncoder::Init(uint numOutputs, uint myIndex, COpenCLMy *open_cl,
uint units_count, uint variables, uint forecast,
uint season_period, uint short_period,
ENUM_OPTIMIZATION optimization_type, uint batch)
{
if(!CNeuronTransposeOCL::Init(numOutputs, myIndex, open_cl, units_count + forecast, variables, optimization_type, batch))
ReturnFalse;
SetActivationFunction(None);
//---
uint index = 0;
if(!cLongNorm.Init(0, index, OpenCL, 1, units_count, variables, optimization, iBatch))
ReturnFalse;
cLongNorm.SetActivationFunction(None);
index++;
if(!cSeasonTransp.Init(0, index, OpenCL, variables, units_count / season_period, season_period, optimization, iBatch))
ReturnFalse;
cSeasonTransp.SetActivationFunction(None);
index++;
if(!cSeasonNorm.Init(0, index, OpenCL, cSeasonTransp.GetCount(), season_period, variables, optimization, iBatch))
ReturnFalse;
cSeasonNorm.SetActivationFunction(None);
index++;
if(!cUnSeasonTransp.Init(0, index, OpenCL, variables, season_period, cSeasonTransp.GetCount(), optimization, iBatch))
ReturnFalse;
index++;
if(!cShortNorm.Init(0, index, OpenCL, units_count / short_period, short_period, variables, optimization, iBatch))
ReturnFalse;
cSeasonNorm.SetActivationFunction(None);
index++;
if(!cAdaptSpatNorm.Init(0, index, OpenCL, units_count, variables, optimization, iBatch))
ReturnFalse;
cAdaptSpatNorm.SetActivationFunction(None);
index++;
uint concatSize = units_count * variables; //inputs
concatSize += cLongNorm.Neurons() + cLongNorm.GetMeanSTDevs().Neurons(); // long term
concatSize += cSeasonNorm.Neurons() + cSeasonNorm.GetMeanSTDevs().Neurons(); // seasons
concatSize += cShortNorm.Neurons() + cShortNorm.GetMeanSTDevs().Neurons(); // short term
concatSize += cAdaptSpatNorm.Neurons() + cAdaptSpatNorm.GetMeanSTDevs().Neurons(); // spatial
if(!cConcatenated.Init(0, index, OpenCL, concatSize, optimization, iBatch))
ReturnFalse;
cConcatenated.SetActivationFunction(None);
index++;
if(!cProjection.Init(0, index, OpenCL, concatSize / variables, concatSize / variables, units_count + forecast, 1, variables, optimization, iBatch))
ReturnFalse;
index++;
if(!cTranspose.Init(0, index, OpenCL, variables, units_count + forecast, optimization, iBatch))
ReturnFalse;
index++;
if(!caFusion[0].Init(0, index, OpenCL, variables, variables, variables, units_count + forecast, optimization, iBatch))
ReturnFalse;
caFusion[0].SetActivationFunction(TANH);
index++;
if(!caFusion[1].Init(0, index, OpenCL, variables, variables, variables, units_count + forecast, optimization, iBatch))
ReturnFalse;
caFusion[1].SetActivationFunction(SIGMOID);
index++;
if(!cFusionOut.Init(0, index, OpenCL, caFusion[0].Neurons(), optimization, iBatch))
ReturnFalse;
//---
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CNeuronSCNNEncoder::feedForward(CNeuronBaseOCL *NeuronOCL)
{
if(!cLongNorm.FeedForward(NeuronOCL))
ReturnFalse;
if(!cSeasonTransp.FeedForward(cLongNorm.AsObject()))
ReturnFalse;
if(!cSeasonNorm.FeedForward(cSeasonTransp.AsObject()))
ReturnFalse;
if(!cUnSeasonTransp.FeedForward(cSeasonNorm.AsObject()))
ReturnFalse;
if(!cShortNorm.FeedForward(cUnSeasonTransp.AsObject()))
ReturnFalse;
if(!cAdaptSpatNorm.FeedForward(cShortNorm.AsObject()))
ReturnFalse;
uint windows[3] = {NeuronOCL.Neurons() / iWindow,
cLongNorm.GetPeriod()*cLongNorm.GetUnits(),
2 * cLongNorm.GetUnits()
};
if(!Concat(NeuronOCL.getOutput(), cLongNorm.getOutput(), cLongNorm.GetMeanSTDevs().getOutput(),
cConcatenated.getOutput(), windows[0], windows[1], windows[2], iWindow))
ReturnFalse;
windows[0] = windows[0] + windows[1] + windows[2];
windows[1] = cSeasonNorm.GetPeriod() * cSeasonNorm.GetUnits();
windows[2] = 2 * cSeasonNorm.GetUnits();
if(!cConcatenated.SwapOutputs() ||
!Concat(cConcatenated.getPrevOutput(), cSeasonNorm.getOutput(), cSeasonNorm.GetMeanSTDevs().getOutput(),
cConcatenated.getOutput(), windows[0], windows[1], windows[2], iWindow))
ReturnFalse;
windows[0] = windows[0] + windows[1] + windows[2];
windows[1] = cShortNorm.GetPeriod() * cShortNorm.GetUnits();
windows[2] = 2 * cShortNorm.GetUnits();
if(!cConcatenated.SwapOutputs() ||
!Concat(cConcatenated.getPrevOutput(), cShortNorm.getOutput(), cShortNorm.GetMeanSTDevs().getOutput(),
cConcatenated.getOutput(), windows[0], windows[1], windows[2], iWindow))
ReturnFalse;
windows[0] = windows[0] + windows[1] + windows[2];
windows[1] = cAdaptSpatNorm.GetUnits();
windows[2] = 2 * cAdaptSpatNorm.GetUnits();
if(!cConcatenated.SwapOutputs() ||
!Concat(cConcatenated.getPrevOutput(), cAdaptSpatNorm.getOutput(), cAdaptSpatNorm.GetMeanSTDevs().getOutput(),
cConcatenated.getOutput(), windows[0], windows[1], windows[2], iWindow))
ReturnFalse;
if(!cProjection.FeedForward(cConcatenated.AsObject()))
ReturnFalse;
if(!cTranspose.FeedForward(cProjection.AsObject()))
ReturnFalse;
for(uint i = 0; i < caFusion.Size(); i++)
if(!caFusion[i].FeedForward(cTranspose.AsObject()))
ReturnFalse;
if(!ElementMult(caFusion[0].getOutput(), caFusion[1].getOutput(), cFusionOut.getOutput()))
ReturnFalse;
//---
return CNeuronTransposeOCL::feedForward(cFusionOut.AsObject());
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CNeuronSCNNEncoder::calcInputGradients(CNeuronBaseOCL *NeuronOCL)
{
if(!NeuronOCL)
ReturnFalse;
//---
if(!CNeuronTransposeOCL::calcInputGradients(cFusionOut.AsObject()))
ReturnFalse;
if(!ElementMultGrad(caFusion[0].getOutput(), caFusion[0].getGradient(),
caFusion[1].getOutput(), caFusion[1].getGradient(),
cFusionOut.getGradient(), caFusion[0].Activation(), caFusion[1].Activation()))
ReturnFalse;
if(!cTranspose.CalcHiddenGradients(caFusion[0].AsObject()))
ReturnFalse;
CBufferFloat* temp = cTranspose.getGradient();
if(!cTranspose.SetGradient(cTranspose.getPrevOutput(), false) ||
!cTranspose.CalcHiddenGradients(caFusion[1].AsObject()) ||
!SumAndNormalize(temp, cTranspose.getGradient(), temp, cTranspose.GetCount(), false, 0, 0, 0, 1) ||
!cTranspose.SetGradient(temp, false))
ReturnFalse;
if(!cProjection.CalcHiddenGradients(cTranspose.AsObject()))
ReturnFalse;
if(!cConcatenated.CalcHiddenGradients(cProjection.AsObject()))
ReturnFalse;
//---
uint windows[3] = {0};
windows[1] = cAdaptSpatNorm.GetUnits();
windows[2] = 2 * cAdaptSpatNorm.GetUnits();
windows[0] = cConcatenated.Neurons() / iWindow - windows[1] - windows[2];
if(!DeConcat(cConcatenated.getPrevOutput(), cAdaptSpatNorm.getGradient(),
cAdaptSpatNorm.GetMeanSTDevs().getGradient(),
cConcatenated.getGradient(), windows[0], windows[1], windows[2], iWindow))
ReturnFalse;
windows[1] = cShortNorm.GetPeriod() * cShortNorm.GetUnits();
windows[2] = 2 * cShortNorm.GetUnits();
windows[0] = windows[0] - windows[1] - windows[2];
if(!DeConcat(cConcatenated.getGradient(), cShortNorm.getPrevOutput(),
cShortNorm.GetMeanSTDevs().getGradient(),
cConcatenated.getPrevOutput(), windows[0], windows[1], windows[2], iWindow))
ReturnFalse;
windows[1] = cSeasonNorm.GetPeriod() * cSeasonNorm.GetUnits();
windows[2] = 2 * cSeasonNorm.GetUnits();
windows[0] = windows[0] - windows[1] - windows[2];
if(!DeConcat(cConcatenated.getPrevOutput(), cSeasonNorm.getPrevOutput(),
cSeasonNorm.GetMeanSTDevs().getGradient(),
cConcatenated.getGradient(), windows[0], windows[1], windows[2], iWindow))
ReturnFalse;
windows[1] = cLongNorm.GetPeriod() * cLongNorm.GetUnits();
windows[2] = 2 * cLongNorm.GetUnits();
windows[0] = windows[0] - windows[1] - windows[2];
if(!DeConcat(NeuronOCL.getPrevOutput(), cLongNorm.getPrevOutput(),
cLongNorm.GetMeanSTDevs().getGradient(),
cConcatenated.getPrevOutput(), windows[0], windows[1], windows[2], iWindow))
ReturnFalse;
//---
if(!cShortNorm.CalcHiddenGradients(cAdaptSpatNorm.AsObject()) ||
!SumAndNormalize(cShortNorm.getGradient(), cShortNorm.getPrevOutput(),
cShortNorm.getGradient(), cShortNorm.GetPeriod(), false, 0, 0, 0, 1))
ReturnFalse;
if(!cUnSeasonTransp.CalcHiddenGradients(cShortNorm.AsObject()))
ReturnFalse;
if(!cSeasonNorm.CalcHiddenGradients(cUnSeasonTransp.AsObject()) ||
!SumAndNormalize(cSeasonNorm.getGradient(), cSeasonNorm.getPrevOutput(),
cSeasonNorm.getGradient(), cSeasonNorm.GetPeriod(), false, 0, 0, 0, 1))
ReturnFalse;
if(!cSeasonTransp.CalcHiddenGradients(cSeasonNorm.AsObject()))
ReturnFalse;
if(!cLongNorm.CalcHiddenGradients(cSeasonTransp.AsObject()) ||
!SumAndNormalize(cLongNorm.getGradient(), cLongNorm.getPrevOutput(),
cLongNorm.getGradient(), cLongNorm.GetPeriod(), false, 0, 0, 0, 1))
ReturnFalse;
if(!NeuronOCL.CalcHiddenGradients(cLongNorm.AsObject()) ||
!SumAndNormalize(NeuronOCL.getGradient(), NeuronOCL.getPrevOutput(),
NeuronOCL.getGradient(), cLongNorm.GetPeriod(), false, 0, 0, 0, 1))
ReturnFalse;
//---
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CNeuronSCNNEncoder::updateInputWeights(CNeuronBaseOCL *NeuronOCL)
{
if(!cAdaptSpatNorm.UpdateInputWeights(cShortNorm.AsObject()))
ReturnFalse;
if(!cProjection.UpdateInputWeights(cConcatenated.AsObject()))
ReturnFalse;
for(uint i = 0; i < caFusion.Size(); i++)
if(!caFusion[i].UpdateInputWeights(cTranspose.AsObject()))
ReturnFalse;
//---
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CNeuronSCNNEncoder::Save(const int file_handle)
{
if(!CNeuronTransposeOCL::Save(file_handle))
ReturnFalse;
//---
if(!cLongNorm.Save(file_handle))
ReturnFalse;
if(!cSeasonTransp.Save(file_handle))
ReturnFalse;
if(!cSeasonNorm.Save(file_handle))
ReturnFalse;
if(!cUnSeasonTransp.Save(file_handle))
ReturnFalse;
if(!cShortNorm.Save(file_handle))
ReturnFalse;
if(!cAdaptSpatNorm.Save(file_handle))
ReturnFalse;
if(!cConcatenated.Save(file_handle))
ReturnFalse;
if(!cProjection.Save(file_handle))
ReturnFalse;
if(!cTranspose.Save(file_handle))
ReturnFalse;
for(uint i = 0; i < caFusion.Size(); i++)
if(!caFusion[i].Save(file_handle))
ReturnFalse;
if(!cFusionOut.Save(file_handle))
ReturnFalse;
//---
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CNeuronSCNNEncoder::Load(const int file_handle)
{
if(!CNeuronTransposeOCL::Load(file_handle))
ReturnFalse;
//---
if(!LoadInsideLayer(file_handle, cLongNorm.AsObject()))
ReturnFalse;
if(!LoadInsideLayer(file_handle, cSeasonTransp.AsObject()))
ReturnFalse;
if(!LoadInsideLayer(file_handle, cSeasonNorm.AsObject()))
ReturnFalse;
if(!LoadInsideLayer(file_handle, cUnSeasonTransp.AsObject()))
ReturnFalse;
if(!LoadInsideLayer(file_handle, cShortNorm.AsObject()))
ReturnFalse;
if(!LoadInsideLayer(file_handle, cAdaptSpatNorm.AsObject()))
ReturnFalse;
if(!LoadInsideLayer(file_handle, cConcatenated.AsObject()))
ReturnFalse;
if(!LoadInsideLayer(file_handle, cProjection.AsObject()))
ReturnFalse;
if(!LoadInsideLayer(file_handle, cTranspose.AsObject()))
ReturnFalse;
for(uint i = 0; i < caFusion.Size(); i++)
if(!LoadInsideLayer(file_handle, caFusion[i].AsObject()))
ReturnFalse;
if(!LoadInsideLayer(file_handle, cFusionOut.AsObject()))
ReturnFalse;
//---
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CNeuronSCNNEncoder::SetOpenCL(COpenCLMy *obj)
{
CNeuronTransposeOCL::SetOpenCL(obj);
//---
cLongNorm.SetOpenCL(OpenCL);
cSeasonTransp.SetOpenCL(OpenCL);
cSeasonNorm.SetOpenCL(OpenCL);
cUnSeasonTransp.SetOpenCL(OpenCL);
cShortNorm.SetOpenCL(OpenCL);
cAdaptSpatNorm.SetOpenCL(OpenCL);
cConcatenated.SetOpenCL(OpenCL);
cProjection.SetOpenCL(OpenCL);
cTranspose.SetOpenCL(OpenCL);
for(uint i = 0; i < caFusion.Size(); i++)
caFusion[i].SetOpenCL(OpenCL);
cFusionOut.SetOpenCL(OpenCL);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CNeuronSCNNEncoder::TrainMode(bool flag)
{
CNeuronTransposeOCL::TrainMode(flag);
//---
cLongNorm.TrainMode(bTrain);
cSeasonTransp.TrainMode(bTrain);
cSeasonNorm.TrainMode(bTrain);
cUnSeasonTransp.TrainMode(bTrain);
cShortNorm.TrainMode(bTrain);
cAdaptSpatNorm.TrainMode(bTrain);
cConcatenated.TrainMode(bTrain);
cProjection.TrainMode(bTrain);
cTranspose.TrainMode(bTrain);
for(uint i = 0; i < caFusion.Size(); i++)
caFusion[i].TrainMode(bTrain);
cFusionOut.TrainMode(bTrain);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CNeuronSCNNEncoder::WeightsUpdate(CNeuronBaseOCL *source, float tau)
{
if(!CNeuronTransposeOCL::WeightsUpdate(source, tau))
ReturnFalse;
CNeuronSCNNEncoder* Source = source;
if(!cAdaptSpatNorm.WeightsUpdate(Source.cAdaptSpatNorm.AsObject(), tau))
ReturnFalse;
if(!cProjection.WeightsUpdate(Source.cProjection.AsObject(), tau))
ReturnFalse;
for(uint i = 0; i < caFusion.Size(); i++)
if(!caFusion[i].WeightsUpdate(Source.caFusion[i].AsObject(), tau))
ReturnFalse;
//---
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CNeuronSCNN::Init(uint numOutputs, uint myIndex, COpenCLMy *open_cl,
uint units_count, uint variables, uint forecast,
uint season_period, uint short_period, uint layers,
ENUM_OPTIMIZATION optimization_type, uint batch)
{
if(!CNeuronBaseOCL::Init(numOutputs, myIndex, open_cl, (units_count + forecast)*variables, optimization_type, batch))
ReturnFalse;
SetActivationFunction(None);
//---
cLayers.Clear();
cLayers.SetOpenCL(OpenCL);
CNeuronSCNNEncoder* encoder = NULL;
CNeuronBaseOCL* residual = NULL;
for(uint l = 0; l < layers; l++)
{
encoder = new CNeuronSCNNEncoder();
if(!encoder)
ReturnFalse;
if(!encoder.Init(0, l, OpenCL, units_count, variables, forecast, season_period, short_period, optimization, iBatch) ||
!cLayers.Add(encoder))
ReturnFalse;
encoder.SetActivationFunction(None);
if((l + 1) == layers)
break;
//---
residual = new CNeuronBaseOCL();
if(!residual)
ReturnFalse;
if(!residual.Init(0, l, OpenCL, units_count * variables, optimization, iBatch) ||
!cLayers.Add(residual))
ReturnFalse;
residual.SetActivationFunction(None);
}
if(!SetGradient(encoder.getGradient(), true))
ReturnFalse;
//---
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CNeuronSCNN::feedForward(CNeuronBaseOCL *NeuronOCL)
{
if(!NeuronOCL)
ReturnFalse;
if(!Output.Fill(0))
ReturnFalse;
CNeuronBaseOCL* inputs = NeuronOCL;
CNeuronSCNNEncoder* current = NULL;
CNeuronBaseOCL* residual = NULL;
CNeuronBaseOCL* temp = NULL;
int layers = cLayers.Total();
//---
for(int l = 0; l < layers; l += 2)
{
current = cLayers[l];
if(!current ||
!current.FeedForward(inputs) ||
!SumAndNormalize(Output, current.getOutput(), Output, current.GetCount(), false, 0, 0, 0, 1))
ReturnFalse;
if((l + 1) == layers)
break;
uint variables = current.GetWindow();
uint dimension = inputs.Neurons() / variables;
uint forecast = current.GetCount() - dimension;
residual = cLayers[l + 1];
if(!residual)
ReturnFalse;
if(!DeConcat(residual.getOutput(), current.getPrevOutput(), current.getOutput(),
dimension, forecast, variables) ||
!SumAndNormalize(residual.getOutput(), inputs.getOutput(), residual.getOutput(),
dimension, true, 0, 0, 0, 1))
ReturnFalse;
inputs = residual;
}
//---
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CNeuronSCNN::calcInputGradients(CNeuronBaseOCL *NeuronOCL)
{
if(!NeuronOCL)
ReturnFalse;
if(!PrevOutput.Fill(0))
ReturnFalse;
//---
CNeuronBaseOCL* inputs = NULL;
CNeuronSCNNEncoder* current = cLayers[-1];
CNeuronBaseOCL* residual = NULL;
int layers = cLayers.Total() - 2;
//---
for(int l = layers; l >= 0; l--)
switch(cLayers[l].Type())
{
case defNeuronBaseOCL:
inputs = cLayers[l];
if(!inputs ||
!inputs.CalcHiddenGradients(current))
ReturnFalse;
if(!!residual)
if(!SumAndNormalize(inputs.getGradient(), residual.getGradient(), inputs.getGradient(),
current.GetWindow(), false, 0, 0, 0, 1))
ReturnFalse;
residual = inputs;
break;
case defNeuronSCNNEncoder:
current = cLayers[l];
if(!residual)
break;
inputs = cLayers[l + 2];
if(!inputs)
ReturnFalse;
if(!Concat(residual.getGradient(), PrevOutput, current.getGradient(),
residual.Neurons() / current.GetWindow(),
current.GetCount() - residual.Neurons() / current.GetWindow(),
current.GetWindow()) ||
!SumAndNormalize(current.getGradient(), inputs.getGradient(), current.getGradient(),
current.GetWindow(), false, 0, 0, 0, 1))
ReturnFalse;
break;
default:
ReturnFalse;
break;
}
//---
if(!NeuronOCL.CalcHiddenGradients(current))
ReturnFalse;
if(!!residual)
if(!SumAndNormalize(NeuronOCL.getGradient(), residual.getGradient(), NeuronOCL.getGradient(),
current.GetWindow(), false, 0, 0, 0, 1))
ReturnFalse;
//---
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CNeuronSCNN::updateInputWeights(CNeuronBaseOCL *NeuronOCL)
{
CNeuronBaseOCL* inputs = NeuronOCL;
CNeuronBaseOCL* current = NULL;
//---
for(int l = 0; l < cLayers.Total(); l++)
{
current = cLayers[l];
if(!current)
ReturnFalse;
if(current.Type() == defNeuronSCNNEncoder ||
current.Type() == defNeuronSSCNNEncoder)
if(!current.UpdateInputWeights(inputs))
ReturnFalse;
inputs = current;
}
//---
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CNeuronSCNN::WeightsUpdate(CNeuronBaseOCL *source, float tau)
{
if(!CNeuronBaseOCL::WeightsUpdate(source, tau))
ReturnFalse;
CNeuronSCNN* Source = source;
if(!cLayers.WeightsUpdate(Source.cLayers.AsObject(), tau))
ReturnFalse;
//---
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CNeuronSCNN::Save(const int file_handle)
{
if(!CNeuronBaseOCL::Save(file_handle))
ReturnFalse;
if(!cLayers.Save(file_handle))
ReturnFalse;
//---
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CNeuronSCNN::Load(const int file_handle)
{
cLayers.Clear();
if(!CNeuronBaseOCL::Load(file_handle))
ReturnFalse;
cLayers.SetOpenCL(OpenCL);
if(!cLayers.Load(file_handle))
ReturnFalse;
//---
CNeuronBaseOCL* last = cLayers[-1];
if(!SetGradient(last.getGradient(), true))
ReturnFalse;
//---
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CNeuronSCNN::SetOpenCL(COpenCLMy *obj)
{
CNeuronBaseOCL::SetOpenCL(obj);
cLayers.SetOpenCL(OpenCL);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CNeuronSCNN::TrainMode(bool flag)
{
CNeuronBaseOCL::TrainMode(flag);
cLayers.TrainMode(flag);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CNeuronPolynomialRegression::Init(uint numOutputs, uint myIndex, COpenCLMy *open_cl,
uint units_count, uint window, uint window_out,
ENUM_OPTIMIZATION optimization_type, uint batch)
{
if(!CNeuronBaseOCL::Init(numOutputs, myIndex, open_cl, units_count * window_out, optimization_type, batch))
ReturnFalse;
activation = None;
//---
if(!cProjection.Init(0, 0, OpenCL, window, window, window_out, units_count, 1, optimization, iBatch))
ReturnFalse;
if(!cConvolution.Init(0, 1, OpenCL, window_out, window_out, window_out, units_count, 1, optimization, iBatch))
ReturnFalse;
cConvolution.SetActivationFunction(None);
if(!cResidual.Init(0, 2, OpenCL, window, window, window_out, units_count, 1, optimization, iBatch))
ReturnFalse;
cResidual.SetActivationFunction(None);
//---
if(!SetGradient(cConvolution.getGradient(), true))
ReturnFalse;
if(!cResidual.SetGradient(getGradient(), true))
ReturnFalse;
//---
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CNeuronPolynomialRegression::feedForward(CNeuronBaseOCL *NeuronOCL)
{
if(!cProjection.FeedForward(NeuronOCL))
ReturnFalse;
if(!cConvolution.FeedForward(cProjection.AsObject()))
ReturnFalse;
if(!cResidual.FeedForward(NeuronOCL))
ReturnFalse;
if(!SumAndNormalize(cConvolution.getOutput(), cResidual.getOutput(),
Output, GetWindowOut(), true, 0, 0, 0, 1))
ReturnFalse;
//---
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CNeuronPolynomialRegression::calcInputGradients(CNeuronBaseOCL *NeuronOCL)
{
if(!NeuronOCL)
ReturnFalse;
//---
if(!cProjection.CalcHiddenGradients(cConvolution.AsObject()))
ReturnFalse;
//---
if(!NeuronOCL.CalcHiddenGradients(cProjection.AsObject()))
ReturnFalse;
CBufferFloat* temp = NeuronOCL.getGradient();
if(!NeuronOCL.SetGradient(NeuronOCL.getPrevOutput(), false) ||
!NeuronOCL.CalcHiddenGradients(cResidual.AsObject()) ||
!SumAndNormalize(temp, NeuronOCL.getGradient(), temp,
GetWindowIn(), false, 0, 0, 0, 1) ||
!NeuronOCL.SetGradient(temp, false))
ReturnFalse;
//---
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CNeuronPolynomialRegression::updateInputWeights(CNeuronBaseOCL *NeuronOCL)
{
if(!cProjection.UpdateInputWeights(NeuronOCL))
ReturnFalse;
if(!cConvolution.UpdateInputWeights(cProjection.AsObject()))
ReturnFalse;
if(!cResidual.UpdateInputWeights(NeuronOCL))
ReturnFalse;
//---
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CNeuronPolynomialRegression::WeightsUpdate(CNeuronBaseOCL *source, float tau)
{
if(!CNeuronBaseOCL::WeightsUpdate(source, tau))
ReturnFalse;
//---
CNeuronPolynomialRegression* Source = source;
if(!cProjection.WeightsUpdate(Source.cProjection.AsObject(), tau))
ReturnFalse;
if(!cConvolution.WeightsUpdate(Source.cConvolution.AsObject(), tau))
ReturnFalse;
if(!cResidual.WeightsUpdate(Source.cResidual.AsObject(), tau))
ReturnFalse;
//---
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CNeuronPolynomialRegression::Save(const int file_handle)
{
if(!CNeuronBaseOCL::Save(file_handle))
ReturnFalse;
//---
if(!cProjection.Save(file_handle))
ReturnFalse;
if(!cConvolution.Save(file_handle))
ReturnFalse;
if(!cResidual.Save(file_handle))
ReturnFalse;
//---
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CNeuronPolynomialRegression::Load(const int file_handle)
{
if(!CNeuronBaseOCL::Load(file_handle))
ReturnFalse;
//---
if(!LoadInsideLayer(file_handle, cProjection.AsObject()))
ReturnFalse;
if(!LoadInsideLayer(file_handle, cConvolution.AsObject()))
ReturnFalse;
if(!LoadInsideLayer(file_handle, cResidual.AsObject()))
ReturnFalse;
//---
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CNeuronPolynomialRegression::SetOpenCL(COpenCLMy *obj)
{
CNeuronBaseOCL::SetOpenCL(obj);
//---
cProjection.SetOpenCL(OpenCL);
cConvolution.SetOpenCL(OpenCL);
cResidual.SetOpenCL(OpenCL);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CNeuronSSCNNEncoder::Init(uint numOutputs, uint myIndex, COpenCLMy *open_cl,
uint units_count, uint variables, uint forecast,
uint season_period, uint short_period,
ENUM_OPTIMIZATION optimization_type, uint batch)
{
if(!CNeuronTransposeOCL::Init(numOutputs, myIndex, open_cl, units_count + forecast,
variables, optimization_type, batch))
ReturnFalse;
activation = None;
//---
int index = 0;
if(!cLongNorm.Init(0, index, OpenCL, 1, units_count, iWindow, optimization, iBatch))
ReturnFalse;
index++;
if(!cLongExtrapolate.Init(0, index, OpenCL, units_count, units_count, iCount, iWindow, 1, optimization, iBatch))
ReturnFalse;
cLongExtrapolate.SetActivationFunction(None);
index++;
if(!cLongMeanSTDevTransp.Init(0, index, OpenCL, iWindow, 2, optimization, iBatch))
ReturnFalse;
if(!cLongMeanSTDevTransp.getGradient().Fill(0))
ReturnFalse;
index++;
if(!cLongMeanExtrapolate.Init(0, index, OpenCL, Neurons(), optimization, iBatch))
ReturnFalse;
cLongExtrapolate.SetActivationFunction(None);
if(!cLongMeanExtrapolate.getPrevOutput().Fill(1))
ReturnFalse;
index++;
if(!cSeasonTransp.Init(0, index, OpenCL, iWindow, units_count / season_period, season_period, optimization, iBatch))
ReturnFalse;
index++;
if(!cSeasonNorm.Init(0, index, OpenCL, season_period, cSeasonTransp.GetCount(), iWindow, optimization, iBatch))
ReturnFalse;
index++;
if(!cUnSeasonTransp.Init(0, index, OpenCL, iWindow, season_period, cSeasonTransp.GetCount(), optimization, iBatch))
ReturnFalse;
index++;
if(!cSeasonExtrapolate.Init(0, index, OpenCL, units_count, units_count, iCount, iWindow, 1, optimization, iBatch))
ReturnFalse;
cSeasonExtrapolate.SetActivationFunction(None);
index++;
if(!cSeasonMeanExtrapolate.Init(0, index, OpenCL, season_period, season_period, iCount, iWindow, 1, optimization, iBatch))
ReturnFalse;
cSeasonMeanExtrapolate.SetActivationFunction(None);
index++;
if(!cShortNorm.Init(0, index, OpenCL, units_count / short_period, short_period, iWindow, optimization, iBatch))
ReturnFalse;
index++;
if(!cShortExtrapolate.Init(0, index, OpenCL, units_count, units_count, iCount, iWindow, 1, optimization, iBatch))
ReturnFalse;
cShortExtrapolate.SetActivationFunction(None);
index++;
if(!cShortMeanExtrapolate.Init(0, index, OpenCL, cShortNorm.GetUnits(), cShortNorm.GetUnits(), iCount, iWindow, 1, optimization, iBatch))
ReturnFalse;
cShortMeanExtrapolate.SetActivationFunction(None);
index++;
if(!cSpatialNorm.Init(0, index, OpenCL, units_count, variables, optimization, iBatch))
ReturnFalse;
index++;
if(!cSpatialExtrapolate.Init(0, index, OpenCL, units_count, units_count, iCount, iWindow, 1, optimization, iBatch))
ReturnFalse;
cSpatialExtrapolate.SetActivationFunction(None);
index++;
if(!cSpatialMeanExtrapolate.Init(0, index, OpenCL, units_count, units_count, iCount, 1, iWindow, optimization, iBatch))
ReturnFalse;
cSpatialMeanExtrapolate.SetActivationFunction(None);
index++;
if(!cConcatenated.Init(0, index, OpenCL, 8 * Neurons(), optimization, iBatch))
ReturnFalse;
index++;
if(!cTranspose.Init(0, index, OpenCL, 8 * iWindow, iCount, optimization, iBatch))
ReturnFalse;
index++;
if(!cFusion.Init(0, index, OpenCL, iCount, 8 * iWindow, iWindow, optimization, iBatch))
ReturnFalse;
//---
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CNeuronSSCNNEncoder::feedForward(CNeuronBaseOCL *NeuronOCL)
{
//--- Long
if(!cLongNorm.FeedForward(NeuronOCL))
ReturnFalse;
if(!cLongExtrapolate.FeedForward(cLongNorm.AsObject()))
ReturnFalse;
if(!cLongMeanSTDevTransp.FeedForward(cLongNorm.GetMeanSTDevs()))
ReturnFalse;
if(!MatMul(cLongMeanSTDevTransp.getOutput(), cLongMeanExtrapolate.getPrevOutput(),
cLongMeanExtrapolate.getOutput(), 1, 1, iCount, iWindow, true))
ReturnFalse;
//--- Season
if(!cSeasonTransp.FeedForward(cLongNorm.AsObject()))
ReturnFalse;
if(!cSeasonNorm.FeedForward(cSeasonTransp.AsObject()))
ReturnFalse;
if(!cUnSeasonTransp.FeedForward(cSeasonNorm.AsObject()))
ReturnFalse;
if(!cSeasonExtrapolate.FeedForward(cUnSeasonTransp.AsObject()))
ReturnFalse;
if(!cSeasonMeanExtrapolate.FeedForward(cSeasonNorm.GetMeans()))
ReturnFalse;
//--- Short
if(!cShortNorm.FeedForward(cUnSeasonTransp.AsObject()))
ReturnFalse;
if(!cShortExtrapolate.FeedForward(cShortNorm.AsObject()))
ReturnFalse;
if(!cShortMeanExtrapolate.FeedForward(cShortNorm.GetMeans()))
ReturnFalse;
//--- Spatial
if(!cSpatialNorm.FeedForward(cShortNorm.AsObject()))
ReturnFalse;
if(!cSpatialExtrapolate.FeedForward(cSpatialNorm.AsObject()))
ReturnFalse;
if(!cSpatialMeanExtrapolate.FeedForward(cSpatialNorm.GetMeans()))
ReturnFalse;
//--- Concat
if(!Concat(cLongExtrapolate.getOutput(), cLongMeanExtrapolate.getOutput(),
cSeasonExtrapolate.getOutput(), cSeasonMeanExtrapolate.getOutput(),
cConcatenated.getOutput(), iCount, iCount, iCount, iCount, iWindow))
ReturnFalse;
if(!Concat(cConcatenated.getOutput(), cShortExtrapolate.getOutput(),
cShortMeanExtrapolate.getOutput(), cConcatenated.getPrevOutput(),
4 * iCount, iCount, iCount, iWindow))
ReturnFalse;
if(!Concat(cConcatenated.getPrevOutput(), cSpatialExtrapolate.getOutput(),
cSpatialMeanExtrapolate.getOutput(), cConcatenated.getOutput(),
6 * iCount, iCount, iCount, iWindow))
ReturnFalse;
//--- Fusion
if(!cTranspose.FeedForward(cConcatenated.AsObject()))
ReturnFalse;
if(!cFusion.FeedForward(cTranspose.AsObject()))
ReturnFalse;
//---
return CNeuronTransposeOCL::feedForward(cFusion.AsObject());
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CNeuronSSCNNEncoder::calcInputGradients(CNeuronBaseOCL *NeuronOCL)
{
if(!NeuronOCL)
ReturnFalse;
//--- Fusion
if(!CNeuronTransposeOCL::calcInputGradients(cFusion.AsObject()))
ReturnFalse;
if(!cTranspose.CalcHiddenGradients(cFusion.AsObject()))
ReturnFalse;
if(!cConcatenated.CalcHiddenGradients(cTranspose.AsObject()))
ReturnFalse;
//--- DeConcat
if(!DeConcat(cConcatenated.getPrevOutput(), cSpatialExtrapolate.getGradient(),
cSpatialMeanExtrapolate.getGradient(), cConcatenated.getGradient(),
6 * iCount, iCount, iCount, iWindow))
ReturnFalse;
if(!DeConcat(cConcatenated.getGradient(), cShortExtrapolate.getGradient(),
cShortMeanExtrapolate.getGradient(), cConcatenated.getPrevOutput(),
4 * iCount, iCount, iCount, iWindow))
ReturnFalse;
if(!DeConcat(cLongExtrapolate.getGradient(), cLongMeanExtrapolate.getGradient(),
cSeasonExtrapolate.getGradient(), cSeasonMeanExtrapolate.getGradient(),
cConcatenated.getGradient(), iCount, iCount, iCount, iCount, iWindow))
ReturnFalse;
//--- Spatial
if(!cSpatialNorm.GetMeans().CalcHiddenGradients(cSpatialMeanExtrapolate.AsObject()))
ReturnFalse;
if(!cSpatialNorm.CalcHiddenGradients(cSpatialExtrapolate.AsObject()))
ReturnFalse;
//--- Short
if(!cShortNorm.CalcHiddenGradients(cSpatialNorm.AsObject()))
ReturnFalse;
CBufferFloat* temp = cShortNorm.getGradient();
if(!cShortNorm.SetGradient(cShortNorm.getPrevOutput(), false) ||
!cShortNorm.CalcHiddenGradients(cShortExtrapolate.AsObject()) ||
!SumAndNormalize(temp, cShortNorm.getGradient(), temp, iWindow, false, 0, 0, 0, 1) ||
!cShortNorm.SetGradient(temp, false))
ReturnFalse;
if(!cShortNorm.GetMeans().CalcHiddenGradients(cShortMeanExtrapolate.AsObject()))
ReturnFalse;
//--- Season
if(!cUnSeasonTransp.CalcHiddenGradients(cShortNorm.AsObject()))
ReturnFalse;
temp = cUnSeasonTransp.getGradient();
if(!cUnSeasonTransp.SetGradient(cUnSeasonTransp.getPrevOutput(), false) ||
!cUnSeasonTransp.CalcHiddenGradients(cSeasonExtrapolate.AsObject()) ||
!SumAndNormalize(temp, cUnSeasonTransp.getGradient(), temp, iWindow, false, 0, 0, 0, 1) ||
!cUnSeasonTransp.SetGradient(temp, false))
ReturnFalse;
if(!cSeasonNorm.GetMeans().CalcHiddenGradients(cSeasonMeanExtrapolate.AsObject()))
ReturnFalse;
if(!cSeasonNorm.CalcHiddenGradients(cUnSeasonTransp.AsObject()))
ReturnFalse;
if(!cSeasonTransp.CalcHiddenGradients(cSeasonNorm.AsObject()))
ReturnFalse;
//--- Long
if(!MatMulGrad(cLongMeanSTDevTransp.getOutput(), cLongMeanSTDevTransp.getGradient(),
cLongMeanExtrapolate.getPrevOutput(), cLongMeanExtrapolate.getGradient(),
cLongMeanExtrapolate.getGradient(), 1, 1, iCount, iWindow, true))
ReturnFalse;
if(!cLongNorm.GetMeanSTDevs().CalcHiddenGradients(cLongMeanSTDevTransp.AsObject()))
ReturnFalse;
if(!cLongNorm.CalcHiddenGradients(cSeasonTransp.AsObject()))
ReturnFalse;
temp = cLongNorm.getGradient();
if(!cLongNorm.SetGradient(cLongNorm.getPrevOutput(), false) ||
!cLongNorm.CalcHiddenGradients(cLongExtrapolate.AsObject()) ||
!SumAndNormalize(temp, cLongNorm.getGradient(), temp, iWindow, false, 0, 0, 0, 1) ||
!cLongNorm.SetGradient(temp, false))
ReturnFalse;
//---
if(!NeuronOCL.CalcHiddenGradients(cLongNorm.AsObject()))
ReturnFalse;
//---
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CNeuronSSCNNEncoder::updateInputWeights(CNeuronBaseOCL *NeuronOCL)
{
//--- Long
if(!cLongNorm.UpdateInputWeights(NeuronOCL))
ReturnFalse;
if(!cLongExtrapolate.UpdateInputWeights(cLongNorm.AsObject()))
ReturnFalse;
//--- Season
if(!cSeasonNorm.UpdateInputWeights(cSeasonTransp.AsObject()))
ReturnFalse;
if(!cSeasonExtrapolate.UpdateInputWeights(cUnSeasonTransp.AsObject()))
ReturnFalse;
if(!cSeasonMeanExtrapolate.UpdateInputWeights(cSeasonNorm.GetMeans()))
ReturnFalse;
//--- Short
if(!cShortNorm.UpdateInputWeights(cUnSeasonTransp.AsObject()))
ReturnFalse;
if(!cShortExtrapolate.UpdateInputWeights(cShortNorm.AsObject()))
ReturnFalse;
if(!cShortMeanExtrapolate.UpdateInputWeights(cShortNorm.GetMeans()))
ReturnFalse;
//--- Spatial
if(!cSpatialNorm.UpdateInputWeights(cShortNorm.AsObject()))
ReturnFalse;
if(!cSpatialExtrapolate.UpdateInputWeights(cSpatialNorm.AsObject()))
ReturnFalse;
if(!cSpatialMeanExtrapolate.UpdateInputWeights(cSpatialNorm.GetMeans()))
ReturnFalse;
//--- Fusion
if(!cFusion.UpdateInputWeights(cTranspose.AsObject()))
ReturnFalse;
//---
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CNeuronSSCNNEncoder::WeightsUpdate(CNeuronBaseOCL *source, float tau)
{
if(!CNeuronTransposeOCL::WeightsUpdate(source, tau))
ReturnFalse;
//---
CNeuronSSCNNEncoder* Source = source;
//--- Long
if(!cLongNorm.WeightsUpdate(Source.cLongNorm.AsObject(), tau))
ReturnFalse;
if(!cLongExtrapolate.WeightsUpdate(Source.cLongExtrapolate.AsObject(), tau))
ReturnFalse;
//--- Season
if(!cSeasonNorm.WeightsUpdate(Source.cSeasonNorm.AsObject(), tau))
ReturnFalse;
if(!cSeasonExtrapolate.WeightsUpdate(Source.cSeasonExtrapolate.AsObject(), tau))
ReturnFalse;
if(!cSeasonMeanExtrapolate.WeightsUpdate(Source.cSeasonMeanExtrapolate.AsObject(), tau))
ReturnFalse;
//--- Short
if(!cShortNorm.WeightsUpdate(Source.cShortNorm.AsObject(), tau))
ReturnFalse;
if(!cShortExtrapolate.WeightsUpdate(Source.cShortExtrapolate.AsObject(), tau))
ReturnFalse;
if(!cShortMeanExtrapolate.WeightsUpdate(Source.cShortMeanExtrapolate.AsObject(), tau))
ReturnFalse;
//--- Spatial
if(!cSpatialNorm.WeightsUpdate(Source.cSpatialNorm.AsObject(), tau))
ReturnFalse;
if(!cSpatialExtrapolate.WeightsUpdate(Source.cSpatialExtrapolate.AsObject(), tau))
ReturnFalse;
if(!cSpatialMeanExtrapolate.WeightsUpdate(Source.cSpatialMeanExtrapolate.AsObject(), tau))
ReturnFalse;
//--- Fusion
if(!cFusion.WeightsUpdate(Source.cFusion.AsObject(), tau))
ReturnFalse;
//---
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CNeuronSSCNNEncoder::Save(const int file_handle)
{
if(!CNeuronTransposeOCL::Save(file_handle))
ReturnFalse;
//---
if(!cLongNorm.Save(file_handle))
ReturnFalse;
if(!cLongExtrapolate.Save(file_handle))
ReturnFalse;
if(!cLongMeanSTDevTransp.Save(file_handle))
ReturnFalse;
if(!cLongMeanExtrapolate.Save(file_handle))
ReturnFalse;
if(!cSeasonTransp.Save(file_handle))
ReturnFalse;
if(!cSeasonNorm.Save(file_handle))
ReturnFalse;
if(!cUnSeasonTransp.Save(file_handle))
ReturnFalse;
if(!cSeasonExtrapolate.Save(file_handle))
ReturnFalse;
if(!cSeasonMeanExtrapolate.Save(file_handle))
ReturnFalse;
if(!cShortNorm.Save(file_handle))
ReturnFalse;
if(!cShortExtrapolate.Save(file_handle))
ReturnFalse;
if(!cShortMeanExtrapolate.Save(file_handle))
ReturnFalse;
if(!cSpatialNorm.Save(file_handle))
ReturnFalse;
if(!cSpatialExtrapolate.Save(file_handle))
ReturnFalse;
if(!cSpatialMeanExtrapolate.Save(file_handle))
ReturnFalse;
if(!cConcatenated.Save(file_handle))
ReturnFalse;
if(!cTranspose.Save(file_handle))
ReturnFalse;
if(!cFusion.Save(file_handle))
ReturnFalse;
//---
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CNeuronSSCNNEncoder::Load(const int file_handle)
{
if(!CNeuronTransposeOCL::Load(file_handle))
ReturnFalse;
//---
if(!LoadInsideLayer(file_handle, cLongNorm.AsObject()))
ReturnFalse;
if(!LoadInsideLayer(file_handle, cLongExtrapolate.AsObject()))
ReturnFalse;
if(!LoadInsideLayer(file_handle, cLongMeanSTDevTransp.AsObject()))
ReturnFalse;
if(!LoadInsideLayer(file_handle, cLongMeanExtrapolate.AsObject()))
ReturnFalse;
if(!LoadInsideLayer(file_handle, cSeasonTransp.AsObject()))
ReturnFalse;
if(!LoadInsideLayer(file_handle, cSeasonNorm.AsObject()))
ReturnFalse;
if(!LoadInsideLayer(file_handle, cUnSeasonTransp.AsObject()))
ReturnFalse;
if(!LoadInsideLayer(file_handle, cSeasonExtrapolate.AsObject()))
ReturnFalse;
if(!LoadInsideLayer(file_handle, cSeasonMeanExtrapolate.AsObject()))
ReturnFalse;
if(!LoadInsideLayer(file_handle, cShortNorm.AsObject()))
ReturnFalse;
if(!LoadInsideLayer(file_handle, cShortExtrapolate.AsObject()))
ReturnFalse;
if(!LoadInsideLayer(file_handle, cShortMeanExtrapolate.AsObject()))
ReturnFalse;
if(!LoadInsideLayer(file_handle, cSpatialNorm.AsObject()))
ReturnFalse;
if(!LoadInsideLayer(file_handle, cSpatialExtrapolate.AsObject()))
ReturnFalse;
if(!LoadInsideLayer(file_handle, cSpatialMeanExtrapolate.AsObject()))
ReturnFalse;
if(!LoadInsideLayer(file_handle, cConcatenated.AsObject()))
ReturnFalse;
if(!LoadInsideLayer(file_handle, cTranspose.AsObject()))
ReturnFalse;
if(!LoadInsideLayer(file_handle, cFusion.AsObject()))
ReturnFalse;
//---
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CNeuronSSCNNEncoder::SetOpenCL(COpenCLMy *obj)
{
CNeuronTransposeOCL::SetOpenCL(obj);
//---
cLongNorm.SetOpenCL(OpenCL);
cLongExtrapolate.SetOpenCL(OpenCL);
cLongMeanSTDevTransp.SetOpenCL(OpenCL);
cLongMeanExtrapolate.SetOpenCL(OpenCL);
cSeasonTransp.SetOpenCL(OpenCL);
cSeasonNorm.SetOpenCL(OpenCL);
cUnSeasonTransp.SetOpenCL(OpenCL);
cSeasonExtrapolate.SetOpenCL(OpenCL);
cSeasonMeanExtrapolate.SetOpenCL(OpenCL);
cShortNorm.SetOpenCL(OpenCL);
cShortExtrapolate.SetOpenCL(OpenCL);
cShortMeanExtrapolate.SetOpenCL(OpenCL);
cSpatialNorm.SetOpenCL(OpenCL);
cSpatialExtrapolate.SetOpenCL(OpenCL);
cSpatialMeanExtrapolate.SetOpenCL(OpenCL);
cConcatenated.SetOpenCL(OpenCL);
cTranspose.SetOpenCL(OpenCL);
cFusion.SetOpenCL(OpenCL);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CNeuronSSCNNEncoder::TrainMode(bool flag)
{
CNeuronTransposeOCL::TrainMode(flag);
//---
cLongNorm.TrainMode(bTrain);
cLongExtrapolate.TrainMode(bTrain);
cLongMeanSTDevTransp.TrainMode(bTrain);
cLongMeanExtrapolate.TrainMode(bTrain);
cSeasonTransp.TrainMode(bTrain);
cSeasonNorm.TrainMode(bTrain);
cUnSeasonTransp.TrainMode(bTrain);
cSeasonExtrapolate.TrainMode(bTrain);
cSeasonMeanExtrapolate.TrainMode(bTrain);
cShortNorm.TrainMode(bTrain);
cShortExtrapolate.TrainMode(bTrain);
cShortMeanExtrapolate.TrainMode(bTrain);
cSpatialNorm.TrainMode(bTrain);
cSpatialExtrapolate.TrainMode(bTrain);
cSpatialMeanExtrapolate.TrainMode(bTrain);
cConcatenated.TrainMode(bTrain);
cTranspose.TrainMode(bTrain);
cFusion.TrainMode(bTrain);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CNeuronSSCNN::Init(uint numOutputs, uint myIndex, COpenCLMy *open_cl,
uint units_count, uint variables, uint forecast,
uint season_period, uint short_period, uint layers,
ENUM_OPTIMIZATION optimization_type, uint batch)
{
if(!CNeuronBaseOCL::Init(numOutputs, myIndex, open_cl, (units_count + forecast)*variables,
optimization_type, batch))
ReturnFalse;
SetActivationFunction(None);
//---
cLayers.Clear();
cLayers.SetOpenCL(OpenCL);
CNeuronSSCNNEncoder* encoder = NULL;
CNeuronBaseOCL* residual = NULL;
for(uint l = 0; l < layers; l++)
{
encoder = new CNeuronSSCNNEncoder();
if(!encoder)
ReturnFalse;
if(!encoder.Init(0, 2 * l, OpenCL, units_count, variables, forecast, season_period,
short_period, optimization, iBatch) ||
!cLayers.Add(encoder))
ReturnFalse;
encoder.SetActivationFunction(None);
if((l + 1) == layers)
break;
//---
residual = new CNeuronBaseOCL();
if(!residual)
ReturnFalse;
if(!residual.Init(0, 2 * l + 1, OpenCL, units_count * variables, optimization, iBatch) ||
!cLayers.Add(residual))
ReturnFalse;
residual.SetActivationFunction(None);
}
if(!SetGradient(encoder.getGradient(), true))
ReturnFalse;
//---
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CNeuronSSCNN::feedForward(CNeuronBaseOCL *NeuronOCL)
{
if(!NeuronOCL)
ReturnFalse;
if(!Output.Fill(0))
ReturnFalse;
CNeuronBaseOCL* inputs = NeuronOCL;
CNeuronSSCNNEncoder* current = NULL;
CNeuronBaseOCL* residual = NULL;
CNeuronBaseOCL* temp = NULL;
int layers = cLayers.Total();
//---
for(int l = 0; l < layers; l += 2)
{
current = cLayers[l];
if(!current ||
!current.FeedForward(inputs) ||
!SumAndNormalize(Output, current.getOutput(), Output, current.GetCount(), false, 0, 0, 0, 1))
ReturnFalse;
if((l + 1) == layers)
break;
uint variables = current.GetWindow();
uint dimension = inputs.Neurons() / variables;
uint forecast = current.GetCount() - dimension;
residual = cLayers[l + 1];
if(!residual)
ReturnFalse;
if(!DeConcat(residual.getOutput(), current.getPrevOutput(), current.getOutput(),
dimension, forecast, variables) ||
!SumAndNormalize(residual.getOutput(), inputs.getOutput(), residual.getOutput(),
dimension, true, 0, 0, 0, 1))
ReturnFalse;
inputs = residual;
}
//---
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CNeuronSSCNN::calcInputGradients(CNeuronBaseOCL *NeuronOCL)
{
if(!NeuronOCL)
ReturnFalse;
if(!PrevOutput.Fill(0))
ReturnFalse;
//---
CNeuronBaseOCL* inputs = NULL;
CNeuronSSCNNEncoder* current = cLayers[-1];
CNeuronBaseOCL* residual = NULL;
int layers = cLayers.Total() - 2;
//---
for(int l = layers; l >= 0; l--)
switch(cLayers[l].Type())
{
case defNeuronBaseOCL:
inputs = cLayers[l];
if(!inputs ||
!inputs.CalcHiddenGradients(current))
ReturnFalse;
if(!!residual)
if(!SumAndNormalize(inputs.getGradient(), residual.getGradient(), inputs.getGradient(),
current.GetWindow(), false, 0, 0, 0, 1))
ReturnFalse;
residual = inputs;
break;
case defNeuronSSCNNEncoder:
current = cLayers[l];
if(!residual)
break;
inputs = cLayers[l + 2];
if(!inputs)
ReturnFalse;
if(!Concat(residual.getGradient(), PrevOutput, current.getGradient(),
residual.Neurons() / current.GetWindow(),
current.GetCount() - residual.Neurons() / current.GetWindow(),
current.GetWindow()) ||
!SumAndNormalize(current.getGradient(), inputs.getGradient(), current.getGradient(),
current.GetWindow(), false, 0, 0, 0, 1))
ReturnFalse;
break;
default:
ReturnFalse;
break;
}
//---
if(!NeuronOCL.CalcHiddenGradients(current))
ReturnFalse;
if(!!residual)
if(!SumAndNormalize(NeuronOCL.getGradient(), residual.getGradient(), NeuronOCL.getGradient(),
current.GetWindow(), false, 0, 0, 0, 1))
ReturnFalse;
//---
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CChebPolinom::Init(uint numOutputs, uint myIndex, COpenCLMy *open_cl, uint dimension,
uint steps, ENUM_OPTIMIZATION optimization_type, uint batch)
{
if(!CNeuronBaseOCL::Init(numOutputs, myIndex, open_cl, dimension * dimension * steps, optimization_type, batch))
ReturnFalse;
//---
activation = None;
iDimension = dimension;
iSteps = steps;
//---
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CChebPolinom::feedForward(CNeuronBaseOCL *NeuronOCL)
{
if(!NeuronOCL || NeuronOCL.Neurons() != (iDimension * iDimension))
ReturnFalse;
//---
uint global_work_offset[3] = { 0 };
uint global_work_size[3] = { MathMin(iDimension, uint(OpenCL.GetMaxLocalSize(0))),
iDimension, iDimension
};
uint local_work_size[3] = { global_work_size[0], 1, 1 };
//---
uint kernel = def_k_ChebStep;
setBuffer(kernel, def_k_cheb_support, NeuronOCL.getOutputIndex())
setBuffer(kernel, def_k_cheb_outputs, getOutputIndex())
for(int step = MathMin(2, MathMax(int(iSteps) - 1, 0)); step < int(iSteps); step++)
{
setArgument(kernel, def_k_cheb_step, step + 1)
kernelExecuteLoc(kernel, global_work_offset, global_work_size, local_work_size)
#ifdef _DEBUG
if(!Output.BufferRead())
ReturnFalse;
#endif
}
//---
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CChebPolinom::calcInputGradients(CNeuronBaseOCL *NeuronOCL)
{
if(!NeuronOCL || NeuronOCL.Neurons() != (iDimension * iDimension))
ReturnFalse;
//---
uint global_work_offset[3] = { 0 };
uint global_work_size[3] = { MathMin(iDimension, uint(OpenCL.GetMaxLocalSize(0))),
iDimension, iDimension
};
uint local_work_size[3] = { global_work_size[0], 1, 1 };
//---
uint kernel = def_k_ChebStepGrad;
setBuffer(kernel, def_k_chebgr_support, NeuronOCL.getOutputIndex())
setBuffer(kernel, def_k_chebgr_support_g, NeuronOCL.getGradientIndex())
setBuffer(kernel, def_k_chebgr_outputs, getOutputIndex())
setBuffer(kernel, def_k_chebgr_outputs_g, getGradientIndex())
for(int step = (int(iSteps) - 1); step >= MathMax(MathMin(2, int(iSteps) - 1), 1); step--)
{
setArgument(kernel, def_k_chebgr_step, step)
kernelExecuteLoc(kernel, global_work_offset, global_work_size, local_work_size)
#ifdef _DEBUG
if(!NeuronOCL.getGradient().BufferRead())
ReturnFalse;
#endif
}
//---
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CChebPolinom::Save(const int file_handle)
{
if(!CNeuronBaseOCL::Save(file_handle))
ReturnFalse;
if(FileWriteInteger(file_handle, int(iDimension)) < INT_VALUE)
ReturnFalse;
if(FileWriteInteger(file_handle, int(iSteps)) < INT_VALUE)
ReturnFalse;
//---
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CChebPolinom::Load(const int file_handle)
{
if(!CNeuronBaseOCL::Load(file_handle))
ReturnFalse;
if(FileIsEnding(file_handle))
ReturnFalse;
iDimension = (uint)FileReadInteger(file_handle);
if(FileIsEnding(file_handle))
ReturnFalse;
iSteps = (uint)FileReadInteger(file_handle);
//---
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CNeuronHimNetGrapConv::Init(uint numOutputs, uint myIndex, COpenCLMy *open_cl,
uint count, uint window, uint cheb_k,
ENUM_OPTIMIZATION optimization_type, uint batch)
{
if(!CNeuronTransposeRCDOCL::Init(numOutputs, myIndex, open_cl, cheb_k,
count, window, optimization_type, batch))
ReturnFalse;
activation = None;
if(!cX_G.Init(0, 0, OpenCL, Neurons(), optimization, iBatch))
ReturnFalse;
cX_G.SetActivationFunction(None);
//---
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CNeuronHimNetGrapConv::FeedForward(CNeuronBaseOCL *NeuronOCL,
CChebPolinom *Support)
{
if(!NeuronOCL || !Support)
ReturnFalse;
if(Support.GetDimension() != iWindow ||
Support.GetSteps() != iCount)
ReturnFalse;
if(NeuronOCL.Neurons() != (Neurons() / iCount))
ReturnFalse;
//---
if(!MatMul(Support.getOutput(), NeuronOCL.getOutput(), cX_G.getOutput(),
iWindow, iWindow, GetDimension(), iCount, false))
ReturnFalse;
//---
return CNeuronTransposeRCDOCL::feedForward(cX_G.AsObject());
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CNeuronHimNetGrapConv::calcInputGradients(CNeuronBaseOCL *NeuronOCL,
CChebPolinom *Support)
{
if(!NeuronOCL || !Support)
ReturnFalse;
if(Support.GetDimension() != iWindow ||
Support.GetSteps() != iCount)
ReturnFalse;
if(NeuronOCL.Neurons() != (Neurons() / iCount))
ReturnFalse;
//---
if(!CNeuronTransposeRCDOCL::calcInputGradients(cX_G.AsObject()))
ReturnFalse;
if(!MatMulGrad(Support.getOutput(), Support.getGradient(),
NeuronOCL.getOutput(), NeuronOCL.getGradient(),
cX_G.getGradient(), iWindow, iWindow,
GetDimension(), iCount, false))
ReturnFalse;
//---
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CNeuronHimNetGrapConv::Load(const int file_handle)
{
if(!CNeuronTransposeRCDOCL::Load(file_handle))
ReturnFalse;
if(!cX_G.Init(0, 0, OpenCL, Neurons(), optimization, iBatch))
ReturnFalse;
//---
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CNeuronHimNetGrapConv::SetOpenCL(COpenCLMy *obj)
{
CNeuronTransposeRCDOCL::SetOpenCL(obj);
cX_G.SetOpenCL(OpenCL);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CNeuronHimNetGCRU::Init(uint numOutputs, uint myIndex, COpenCLMy *open_cl,
uint units, uint window, uint window_out,
uint cheb_k, uint embed_dim,
ENUM_OPTIMIZATION optimization_type, uint batch)
{
if(!CNeuronBaseOCL::Init(numOutputs, myIndex, open_cl, units * window_out, optimization_type, batch))
ReturnFalse;
activation = None;
//---
int index = 0;
if(!cInpAndHidden.Init(0, index, OpenCL, (window + window_out)*units, optimization, iBatch))
ReturnFalse;
cInpAndHidden.SetActivationFunction(None);
index++;
if(!cZ_R.Init(0, index, OpenCL, units, window + window_out, cheb_k, optimization, iBatch))
ReturnFalse;
cZ_R.SetActivationFunction(None);
index++;
if(!cZ_R_emb.Init(0, index, OpenCL, embed_dim, embed_dim,
2 * cheb_k * (window + window_out) * window_out,
units, 1, optimization, iBatch))
ReturnFalse;
cZ_R_emb.SetActivationFunction(None);
index++;
if(!cZe_Re.Init(0, index, OpenCL, 2 * window_out * units, optimization, iBatch))
ReturnFalse;
cZe_Re.SetActivationFunction(None);
index++;
if(!cZ.Init(0, index, OpenCL, window_out * units, optimization, iBatch))
ReturnFalse;
cZ.SetActivationFunction(None);
index++;
if(!cR.Init(0, index, OpenCL, window_out * units, optimization, iBatch))
ReturnFalse;
cR.SetActivationFunction(None);
index++;
if(!cCandidate.Init(0, index, OpenCL, cInpAndHidden.Neurons(), optimization, iBatch))
ReturnFalse;
cCandidate.SetActivationFunction(None);
index++;
if(!cHC.Init(0, index, OpenCL, units, window + window_out, cheb_k, optimization, iBatch))
ReturnFalse;
cHC.SetActivationFunction(None);
index++;
if(!cHC_emb.Init(0, index, OpenCL, embed_dim, embed_dim,
(window + window_out) * window_out * cheb_k,
units, 1, optimization, iBatch))
ReturnFalse;
cHC_emb.SetActivationFunction(None);
index++;
if(!cHCe.Init(0, index, OpenCL, window_out * units, optimization, iBatch))
ReturnFalse;
cHCe.SetActivationFunction(None);
//---
bSupportAccum.BufferFree();
bSupportAccum.Clear();
if(!bSupportAccum.BufferInit(units * units * cheb_k, 0) ||
!bSupportAccum.BufferCreate(OpenCL))
ReturnFalse;
//---
if(!Output.Fill(0))
ReturnFalse;
//---
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CNeuronHimNetGCRU::feedForward(CNeuronBaseOCL *NeuronOCL,
CChebPolinom *Support,
CNeuronBaseOCL *Embedding)
{
if(!NeuronOCL || !Support || !Embedding)
ReturnFalse;
if(!SwapOutputs())
ReturnFalse;
//---
uint cheb_k = cZ_R.GetChebK();
uint units = cZ_R.GetCount();
uint window_out = Neurons() / units;
uint window = cZ_R.GetWindow() - window_out;
//---
if(!Concat(NeuronOCL.getOutput(), PrevOutput, cInpAndHidden.getOutput(), window, window_out, units))
ReturnFalse;
if(!cZ_R.FeedForward(cInpAndHidden.AsObject(), Support))
ReturnFalse;
if(!cZ_R_emb.FeedForward(Embedding))
ReturnFalse;
if(!MatMul(cZ_R.getOutput(), cZ_R_emb.getOutput(), cZe_Re.getOutput(), 1, (window + window_out)*cheb_k,
2 * window_out, units, true))
ReturnFalse;
if(!Activation(cZe_Re.getOutput(), cZe_Re.getOutput(), SIGMOID))
ReturnFalse;
if(!DeConcat(cZ.getOutput(), cR.getOutput(), cZe_Re.getOutput(), window_out, window_out, units))
ReturnFalse;
if(!ElementMult(cZ.getOutput(), PrevOutput, cZ.getPrevOutput()))
ReturnFalse;
if(!Concat(NeuronOCL.getOutput(), cZ.getPrevOutput(), cCandidate.getOutput(), window, window_out, units))
ReturnFalse;
if(!cHC.FeedForward(cCandidate.AsObject(), Support))
ReturnFalse;
if(!cHC_emb.FeedForward(Embedding))
ReturnFalse;
if(!MatMul(cHC.getOutput(), cHC_emb.getOutput(), cHCe.getOutput(), 1, (window + window_out)*cheb_k,
window_out, units, true))
ReturnFalse;
if(!Activation(cHCe.getOutput(), cHCe.getOutput(), TANH))
ReturnFalse;
if(!GateElementMult(PrevOutput, cHCe.getOutput(), cR.getOutput(), Output))
ReturnFalse;
//---
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CNeuronHimNetGCRU::calcInputGradients(CNeuronBaseOCL *NeuronOCL,
CChebPolinom *Support,
CNeuronBaseOCL *Embedding)
{
if(!NeuronOCL || !Support || !Embedding)
ReturnFalse;
//---
uint cheb_k = cZ_R.GetChebK();
uint units = cZ_R.GetCount();
uint window_out = Neurons() / units;
uint window = cZ_R.GetWindow() - window_out;
//---
if(!GateElementMultGrad(PrevOutput, cR.getPrevOutput(),
cHCe.getOutput(), cHCe.getGradient(),
cR.getOutput(), cR.getGradient(),
Gradient, None, TANH, cR.Activation()))
ReturnFalse;
if(!MatMulGrad(cHC.getOutput(), cHC.getGradient(),
cHC_emb.getOutput(), cHC_emb.getGradient(),
cHCe.getGradient(), 1, (window + window_out)*cheb_k,
window_out, units, true))
ReturnFalse;
if(!cHC.calcInputGradients(cCandidate.AsObject(), Support))
ReturnFalse;
if(!DeConcat(NeuronOCL.getGradient(), cZ.getPrevOutput(), cCandidate.getGradient(),
window, window_out, units))
ReturnFalse;
if(!ElementMultGrad(cZ.getOutput(), cZ.getGradient(),
PrevOutput, cCandidate.getPrevOutput(),
cZ.getPrevOutput(), None, None))
ReturnFalse;
if(!Concat(cZ.getGradient(), cR.getGradient(), cZe_Re.getGradient(),
window_out, window_out, units))
ReturnFalse;
if(!DeActivation(cZe_Re.getOutput(), cZe_Re.getGradient(), cZe_Re.getGradient(), SIGMOID))
ReturnFalse;
if(!MatMulGrad(cZ_R.getOutput(), cZ_R.getGradient(),
cZ_R_emb.getOutput(), cZ_R_emb.getGradient(),
cZe_Re.getGradient(), 1, (window + window_out)*cheb_k,
2 * window_out, units, true))
ReturnFalse;
CBufferFloat* temp = Support.getGradient();
if(!Support.SetGradient(GetPointer(bSupportAccum), false) ||
!cZ_R.calcInputGradients(cInpAndHidden.AsObject(), Support) ||
!SumAndNormalize(temp, Support.getGradient(), temp, Support.GetDimension(), false, 0, 0, 0, 1) ||
!Support.SetGradient(temp, false))
ReturnFalse;
if(!DeConcat(cInpAndHidden.getPrevOutput(), cCandidate.getPrevOutput(), cInpAndHidden.getGradient(), window, window_out, units))
ReturnFalse;
if(!SumAndNormalize(NeuronOCL.getGradient(), cInpAndHidden.getPrevOutput(), NeuronOCL.getGradient(), window, false, 0, 0, 0, 1))
ReturnFalse;
if(NeuronOCL.Activation() != None)
if(!DeActivation(NeuronOCL.getOutput(), NeuronOCL.getGradient(), NeuronOCL.getGradient(), NeuronOCL.Activation()))
ReturnFalse;
//---
if(!Embedding.CalcHiddenGradients(cHC_emb.AsObject()))
ReturnFalse;
temp = Embedding.getGradient();
if(!Embedding.SetGradient(Embedding.getPrevOutput(), false) ||
!Embedding.CalcHiddenGradients(cZ_R_emb.AsObject()) ||
!SumAndNormalize(temp, Embedding.getGradient(), temp, cZ_R_emb.GetWindow(), false, 0, 0, 0, 1) ||
!Embedding.SetGradient(temp, false))
ReturnFalse;
//---
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CNeuronHimNetGCRU::updateInputWeights(CNeuronBaseOCL *NeuronOCL,
CChebPolinom *Support,
CNeuronBaseOCL *Embedding)
{
if(!Embedding)
ReturnFalse;
//---
if(!cZ_R_emb.UpdateInputWeights(Embedding))
ReturnFalse;
if(!cHC_emb.UpdateInputWeights(Embedding))
ReturnFalse;
//---
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CNeuronHimNetGCRU::WeightsUpdate(CNeuronBaseOCL *source, float tau)
{
if(!CNeuronBaseOCL::WeightsUpdate(source, tau))
ReturnFalse;
//---
CNeuronHimNetGCRU* Source = source;
if(!cZ_R_emb.WeightsUpdate(Source.cZ_R_emb.AsObject(), tau))
ReturnFalse;
if(!cHC_emb.WeightsUpdate(Source.cHC_emb.AsObject(), tau))
ReturnFalse;
//---
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CNeuronHimNetGCRU::Save(const int file_handle)
{
if(!CNeuronBaseOCL::Save(file_handle))
ReturnFalse;
//---
if(!cZ_R.Save(file_handle))
ReturnFalse;
if(!cZ_R_emb.Save(file_handle))
ReturnFalse;
if(!cHC.Save(file_handle))
ReturnFalse;
if(!cHC_emb.Save(file_handle))
ReturnFalse;
//---
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CNeuronHimNetGCRU::Load(const int file_handle)
{
if(!CNeuronBaseOCL::Load(file_handle))
ReturnFalse;
//---
if(!LoadInsideLayer(file_handle, cZ_R.AsObject()))
ReturnFalse;
if(!LoadInsideLayer(file_handle, cZ_R_emb.AsObject()))
ReturnFalse;
if(!LoadInsideLayer(file_handle, cHC.AsObject()))
ReturnFalse;
if(!LoadInsideLayer(file_handle, cHC_emb.AsObject()))
ReturnFalse;
//---
uint cheb_k = cZ_R.GetChebK();
uint units = cZ_R.GetCount();
uint window_out = Neurons() / units;
uint window = cZ_R.GetWindow() - window_out;
//---
int index = 0;
if(!cInpAndHidden.Init(0, index, OpenCL, (window + window_out)*units, optimization, iBatch))
ReturnFalse;
cInpAndHidden.SetActivationFunction(None);
index += 3;
if(!cZe_Re.Init(0, index, OpenCL, 2 * window_out * units, optimization, iBatch))
ReturnFalse;
index++;
if(!cZ.Init(0, index, OpenCL, window_out * units, optimization, iBatch))
ReturnFalse;
cZ.SetActivationFunction(None);
index++;
if(!cR.Init(0, index, OpenCL, window_out * units, optimization, iBatch))
ReturnFalse;
cR.SetActivationFunction(None);
index++;
if(!cCandidate.Init(0, index, OpenCL, cInpAndHidden.Neurons(), optimization, iBatch))
ReturnFalse;
cCandidate.SetActivationFunction(None);
index += 3;
if(!cHCe.Init(0, index, OpenCL, window_out * units, optimization, iBatch))
ReturnFalse;
cHCe.SetActivationFunction(None);
//---
bSupportAccum.BufferFree();
bSupportAccum.Clear();
if(!bSupportAccum.BufferInit(units * units * cheb_k, 0) ||
!bSupportAccum.BufferCreate(OpenCL))
ReturnFalse;
//---
if(!Output.Fill(0))
ReturnFalse;
//---
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CNeuronHimNetGCRU::SetOpenCL(COpenCLMy *obj)
{
CNeuronBaseOCL::SetOpenCL(obj);
//---
cZ_R.SetOpenCL(OpenCL);
cZ_R_emb.SetOpenCL(OpenCL);
cHC.SetOpenCL(OpenCL);
cHC_emb.SetOpenCL(OpenCL);
cInpAndHidden.SetOpenCL(OpenCL);
cZe_Re.SetOpenCL(OpenCL);
cZ.SetOpenCL(OpenCL);
cR.SetOpenCL(OpenCL);
cCandidate.SetOpenCL(OpenCL);
cHCe.SetOpenCL(OpenCL);
//---
bSupportAccum.BufferCreate(OpenCL);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CNeuronHimNetTempEncoder::Init(uint numOutputs, uint myIndex, COpenCLMy *open_cl,
uint units, uint window, uint window_out, uint cheb_k,
uint layers, uint embed_dim, uint period1,
uint timeframe1, uint period2, uint timeframe2,
ENUM_OPTIMIZATION optimization_type, uint batch)
{
if(layers <= 0)
ReturnFalse;
//---
if(!CNeuronBaseOCL::Init(numOutputs, myIndex, open_cl, window_out * units, optimization_type, batch))
ReturnFalse;
//---
int index = 0;
if(!caEmbeddings[0].Init(0, index, OpenCL, embed_dim, period1, optimization, iBatch))
ReturnFalse;
aTimeframes[0] = MathMax(1, timeframe1);
index++;
if(!caEmbeddings[1].Init(0, index, OpenCL, embed_dim, period2, optimization, iBatch))
ReturnFalse;
aTimeframes[1] = MathMax(1, timeframe2);
if(!cConcatEmbeddings.Init(numOutputs, myIndex, open_cl, 2 * embed_dim, optimization_type, batch))
ReturnFalse;
//---
cGRCUs.Clear();
cGRCUs.SetOpenCL(OpenCL);
index++;
CNeuronHimNetGCRU *temp = new CNeuronHimNetGCRU();
if(!temp ||
!temp.Init(0, index, OpenCL, units, window, window_out, cheb_k, 2 * embed_dim, optimization, iBatch) ||
!cGRCUs.Add(temp))
ReturnFalse;
for(uint i = 1; i < layers; i++)
{
index++;
temp = new CNeuronHimNetGCRU();
if(!temp ||
!temp.Init(0, index, OpenCL, units, window_out, window_out, cheb_k, 2 * embed_dim, optimization, iBatch) ||
!cGRCUs.Add(temp))
ReturnFalse;
}
//---
bSupportAccum.BufferFree();
bSupportAccum.Clear();
if(!bSupportAccum.BufferInit(units * units * cheb_k, 0) ||
!bSupportAccum.BufferCreate(OpenCL))
ReturnFalse;
//---
SetActivationFunction((ENUM_ACTIVATION)temp.Activation());
if(!SetOutput(temp.getOutput(), true) ||
!SetGradient(temp.getGradient(), true))
ReturnFalse;
//---
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CNeuronHimNetTempEncoder::feedForward(CNeuronBaseOCL *NeuronOCL, CChebPolinom *Support, int label)
{
for(uint i = 0; i < caEmbeddings.Size(); i++)
{
int position = (label / int(aTimeframes[i])) % caEmbeddings[i].GetPeriod();
if(!caEmbeddings[i].SetPosition(position) ||
!caEmbeddings[i].FeedForward())
ReturnFalse;
}
if(!Concat(caEmbeddings[0].getOutput(), caEmbeddings[1].getOutput(),
cConcatEmbeddings.getOutput(), 1, 1, caEmbeddings[0].Neurons()))
ReturnFalse;
//---
CNeuronBaseOCL *inputs = NeuronOCL;
CNeuronHimNetGCRU *current = NULL;
for(int i = 0; i < cGRCUs.Total(); i++)
{
current = cGRCUs[i];
if(!current ||
!current.feedForward(inputs, Support, cConcatEmbeddings.AsObject()))
ReturnFalse;
inputs = current;
}
//---
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CNeuronHimNetTempEncoder::calcInputGradients(CNeuronBaseOCL *NeuronOCL, CChebPolinom *Support)
{
if(!NeuronOCL || !Support)
ReturnFalse;
//---
CNeuronBaseOCL *inputs = (cGRCUs.Total() > 1 ? cGRCUs[-2] : NeuronOCL);
CNeuronHimNetGCRU* current = cGRCUs[-1];
if(!current ||
!current.calcInputGradients(inputs, Support, cConcatEmbeddings.AsObject()))
ReturnFalse;
if(!DeConcat(caEmbeddings[0].getGradient(), caEmbeddings[1].getGradient(),
cConcatEmbeddings.getGradient(), 1, 1, caEmbeddings[0].Neurons()))
ReturnFalse;
if(cGRCUs.Total() > 1)
{
CBufferFloat *temp = Support.getGradient();
if(!Support.SetGradient(GetPointer(bSupportAccum), false))
ReturnFalse;
for(int i = cGRCUs.Total() - 2; i >= 0; i--)
{
current = cGRCUs[i];
inputs = (i > 0 ? cGRCUs[i - 1] : NeuronOCL);
if(!current ||
!current.calcInputGradients(inputs, Support, cConcatEmbeddings.AsObject()))
ReturnFalse;
if(!SumAndNormalize(temp, Support.getGradient(), temp, 1, false, 0, 0, 0, 1))
ReturnFalse;
if(!DeConcat(caEmbeddings[0].getPrevOutput(), caEmbeddings[1].getPrevOutput(),
cConcatEmbeddings.getGradient(), 1, 1, caEmbeddings[0].Neurons()))
ReturnFalse;
for(uint i = 0; i < caEmbeddings.Size(); i++)
if(!SumAndNormalize(caEmbeddings[i].getGradient(), caEmbeddings[i].getPrevOutput(),
caEmbeddings[i].getGradient(), 1, false, 0, 0, 0, 1))
ReturnFalse;
}
if(!Support.SetGradient(temp, false))
ReturnFalse;
}
//---
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CNeuronHimNetTempEncoder::updateInputWeights(CNeuronBaseOCL *NeuronOCL, CChebPolinom *Support)
{
for(uint i = 0; i < caEmbeddings.Size(); i++)
if(!caEmbeddings[i].UpdateInputWeights())
ReturnFalse;
//---
CNeuronBaseOCL* inputs = NeuronOCL;
CNeuronHimNetGCRU* current = NULL;
for(int i = 0; i < cGRCUs.Total(); i++)
{
current = cGRCUs[i];
if(!current.updateInputWeights(inputs, Support, cConcatEmbeddings.AsObject()))
ReturnFalse;
inputs = current;
}
//---
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CNeuronHimNetTempEncoder::WeightsUpdate(CNeuronBaseOCL *source, float tau)
{
if(!CNeuronBaseOCL::WeightsUpdate(source, tau))
ReturnFalse;
//---
CNeuronHimNetTempEncoder* Source = source;
for(uint i = 0; i < caEmbeddings.Size(); i++)
if(!caEmbeddings[i].WeightsUpdate(Source.caEmbeddings[i].AsObject(), tau))
ReturnFalse;
if(!cGRCUs.WeightsUpdate(Source.cGRCUs.AsObject(), tau))
ReturnFalse;
//---
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CNeuronHimNetTempEncoder::Save(const int file_handle)
{
if(!CNeuronBaseOCL::Save(file_handle))
ReturnFalse;
//---
for(uint i = 0; i < caEmbeddings.Size(); i++)
{
if(!caEmbeddings[i].Save(file_handle))
ReturnFalse;
if(FileWriteInteger(file_handle, int(aTimeframes[i])) < INT_VALUE)
ReturnFalse;
}
if(!cGRCUs.Save(file_handle))
ReturnFalse;
//---
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CNeuronHimNetTempEncoder::Load(const int file_handle)
{
if(!CNeuronBaseOCL::Load(file_handle))
ReturnFalse;
//---
for(uint i = 0; i < caEmbeddings.Size(); i++)
{
if(!LoadInsideLayer(file_handle, caEmbeddings[i].AsObject()))
ReturnFalse;
if(FileIsEnding(file_handle))
ReturnFalse;
aTimeframes[i] = (uint)FileReadInteger(file_handle);
}
if(!cGRCUs.Load(file_handle))
ReturnFalse;
//---
bSupportAccum.BufferFree();
bSupportAccum.Clear();
CNeuronHimNetGCRU* temp = cGRCUs[-1];
uint units = temp.GetCount();
uint cheb_k = temp.GetChebK();
if(!bSupportAccum.BufferInit(units * units * cheb_k, 0) ||
!bSupportAccum.BufferCreate(OpenCL))
ReturnFalse;
//---
SetActivationFunction((ENUM_ACTIVATION)temp.Activation());
if(!SetOutput(temp.getOutput(), true) ||
!SetGradient(temp.getGradient(), true))
ReturnFalse;
//---
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CNeuronHimNetTempEncoder::SetOpenCL(COpenCLMy *obj)
{
CNeuronBaseOCL::SetOpenCL(obj);
for(uint i = 0; i < caEmbeddings.Size(); i++)
caEmbeddings[i].SetOpenCL(OpenCL);
cGRCUs.SetOpenCL(OpenCL);
//---
bSupportAccum.BufferFree();
bSupportAccum.BufferCreate(OpenCL);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CNeuronHimNetTempEncoder::Clear(void)
{
CNeuronBaseOCL* temp = NULL;
for(int i = 0; i < cGRCUs.Total(); i++)
{
temp = cGRCUs[i];
if(!temp ||
!temp.Clear())
ReturnFalse;
}
//---
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
uint CNeuronHimNetTempEncoder::GetCount(void) const
{
if(cGRCUs.Total() <= 0)
return 0;
CNeuronHimNetGCRU* temp = cGRCUs[0];
if(!temp)
return 0;
//---
return temp.GetCount();
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
uint CNeuronHimNetTempEncoder::GetChebK(void) const
{
if(cGRCUs.Total() <= 0)
return 0;
CNeuronHimNetGCRU* temp = cGRCUs[0];
if(!temp)
return 0;
//---
return temp.GetChebK();
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
uint CNeuronHimNetTempEncoder::GetWindowIn(void) const
{
if(cGRCUs.Total() <= 0)
return 0;
CNeuronHimNetGCRU* temp = cGRCUs[0];
if(!temp)
return 0;
//---
return temp.GetWindowIn();
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
uint CNeuronHimNetTempEncoder::GetWindowOut(void) const
{
uint count = GetCount();
if(count <= 0)
return 0;
//---
return Neurons() / count;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CNeuronHimNetSpatEncoder::Init(uint numOutputs, uint myIndex, COpenCLMy *open_cl,
uint units, uint window, uint window_out, uint cheb_k,
uint layers, uint embed_dim,
ENUM_OPTIMIZATION optimization_type, uint batch)
{
if(layers <= 0)
ReturnFalse;
//---
if(!CNeuronBaseOCL::Init(numOutputs, myIndex, open_cl, window_out * units, optimization_type, batch))
ReturnFalse;
//---
int index = 0;
if(!cEmbedding.Init(0, index, OpenCL, embed_dim, optimization, iBatch))
ReturnFalse;
//---
cGRCUs.Clear();
cGRCUs.SetOpenCL(OpenCL);
index++;
CNeuronHimNetGCRU *temp = new CNeuronHimNetGCRU();
if(!temp ||
!temp.Init(0, index, OpenCL, units, window, window_out, cheb_k, embed_dim, optimization, iBatch) ||
!cGRCUs.Add(temp))
{
DeleteObj(temp);
ReturnFalse;
}
for(uint i = 1; i < layers; i++)
{
index++;
temp = new CNeuronHimNetGCRU();
if(!temp ||
!temp.Init(0, index, OpenCL, units, window_out, window_out, cheb_k, 2 * embed_dim, optimization, iBatch) ||
!cGRCUs.Add(temp))
{
DeleteObj(temp);
ReturnFalse;
}
}
//---
bSupportAccum.BufferFree();
bSupportAccum.Clear();
if(!bSupportAccum.BufferInit(units * units * cheb_k, 0) ||
!bSupportAccum.BufferCreate(OpenCL))
ReturnFalse;
bEmbeddingAccum.BufferFree();
bEmbeddingAccum.Clear();
if(!bEmbeddingAccum.BufferInit(cEmbedding.Neurons(), 0) ||
!bEmbeddingAccum.BufferCreate(OpenCL))
ReturnFalse;
//---
SetActivationFunction((ENUM_ACTIVATION)temp.Activation());
if(!SetOutput(temp.getOutput(), true) ||
!SetGradient(temp.getGradient(), true))
ReturnFalse;
//---
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CNeuronHimNetSpatEncoder::feedForward(CNeuronBaseOCL *NeuronOCL, CChebPolinom *Support)
{
if(bTrain)
if(!cEmbedding.FeedForward())
ReturnFalse;
//---
CNeuronBaseOCL *inputs = NeuronOCL;
CNeuronHimNetGCRU *current = NULL;
for(int i = 0; i < cGRCUs.Total(); i++)
{
current = cGRCUs[i];
if(!current ||
!current.feedForward(inputs, Support, cEmbedding.AsObject()))
ReturnFalse;
inputs = current;
}
//---
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CNeuronHimNetSpatEncoder::calcInputGradients(CNeuronBaseOCL *NeuronOCL, CChebPolinom *Support)
{
if(!NeuronOCL || !Support)
ReturnFalse;
//---
CNeuronBaseOCL *inputs = (cGRCUs.Total() > 1 ? cGRCUs[-2] : NeuronOCL);
CNeuronHimNetGCRU* current = cGRCUs[-1];
if(!current ||
!current.calcInputGradients(inputs, Support, cEmbedding.AsObject()))
ReturnFalse;
if(cGRCUs.Total() > 1)
{
CBufferFloat *sup = Support.getGradient();
if(!Support.SetGradient(GetPointer(bSupportAccum), false))
ReturnFalse;
CBufferFloat *emb = cEmbedding.getGradient();
if(!cEmbedding.SetGradient(GetPointer(bEmbeddingAccum), false))
ReturnFalse;
for(int i = cGRCUs.Total() - 2; i >= 0; i--)
{
current = cGRCUs[i];
inputs = (i > 0 ? cGRCUs[i - 1] : NeuronOCL);
if(!current ||
!current.calcInputGradients(inputs, Support, cEmbedding.AsObject()))
ReturnFalse;
if(!SumAndNormalize(sup, Support.getGradient(), sup, 1, false, 0, 0, 0, 1))
ReturnFalse;
if(!SumAndNormalize(cEmbedding.getGradient(), emb, emb, 1, false, 0, 0, 0, 1))
ReturnFalse;
}
if(!Support.SetGradient(sup, false))
ReturnFalse;
if(!cEmbedding.SetGradient(emb, false))
ReturnFalse;
}
//---
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CNeuronHimNetSpatEncoder::updateInputWeights(CNeuronBaseOCL *NeuronOCL, CChebPolinom *Support)
{
if(!cEmbedding.UpdateInputWeights())
ReturnFalse;
//---
CNeuronBaseOCL* inputs = NeuronOCL;
CNeuronHimNetGCRU* current = NULL;
for(int i = 0; i < cGRCUs.Total(); i++)
{
current = cGRCUs[i];
if(!current.updateInputWeights(inputs, Support, cEmbedding.AsObject()))
ReturnFalse;
inputs = current;
}
//---
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CNeuronHimNetSpatEncoder::WeightsUpdate(CNeuronBaseOCL *source, float tau)
{
if(!CNeuronBaseOCL::WeightsUpdate(source, tau))
ReturnFalse;
//---
CNeuronHimNetSpatEncoder* Source = source;
if(!cEmbedding.WeightsUpdate(Source.cEmbedding.AsObject(), tau))
ReturnFalse;
if(!cGRCUs.WeightsUpdate(Source.cGRCUs.AsObject(), tau))
ReturnFalse;
//---
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CNeuronHimNetSpatEncoder::Save(const int file_handle)
{
if(!CNeuronBaseOCL::Save(file_handle))
ReturnFalse;
//---
if(!cEmbedding.Save(file_handle))
ReturnFalse;
if(!cGRCUs.Save(file_handle))
ReturnFalse;
//---
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CNeuronHimNetSpatEncoder::Load(const int file_handle)
{
if(!CNeuronBaseOCL::Load(file_handle))
ReturnFalse;
//---
if(!LoadInsideLayer(file_handle, cEmbedding.AsObject()))
ReturnFalse;
if(!cGRCUs.Load(file_handle))
ReturnFalse;
//---
bSupportAccum.BufferFree();
bSupportAccum.Clear();
CNeuronHimNetGCRU* temp = cGRCUs[-1];
uint units = temp.GetCount();
uint cheb_k = temp.GetChebK();
if(!bSupportAccum.BufferInit(units * units * cheb_k, 0) ||
!bSupportAccum.BufferCreate(OpenCL))
ReturnFalse;
bEmbeddingAccum.BufferFree();
bEmbeddingAccum.Clear();
if(!bEmbeddingAccum.BufferInit(cEmbedding.Neurons(), 0) ||
!bEmbeddingAccum.BufferCreate(OpenCL))
ReturnFalse;
//---
SetActivationFunction((ENUM_ACTIVATION)temp.Activation());
if(!SetOutput(temp.getOutput(), true) ||
!SetGradient(temp.getGradient(), true))
ReturnFalse;
//---
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CNeuronHimNetSpatEncoder::SetOpenCL(COpenCLMy *obj)
{
CNeuronBaseOCL::SetOpenCL(obj);
cEmbedding.SetOpenCL(OpenCL);
cGRCUs.SetOpenCL(OpenCL);
//---
bSupportAccum.BufferFree();
bSupportAccum.BufferCreate(OpenCL);
bEmbeddingAccum.BufferFree();
bEmbeddingAccum.BufferCreate(OpenCL);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CNeuronHimNetSpatEncoder::Clear(void)
{
CNeuronBaseOCL* temp = NULL;
for(int i = 0; i < cGRCUs.Total(); i++)
{
temp = cGRCUs[i];
if(!temp ||
!temp.Clear())
ReturnFalse;
}
//---
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
uint CNeuronHimNetSpatEncoder::GetCount(void) const
{
if(cGRCUs.Total() <= 0)
return 0;
CNeuronHimNetGCRU* temp = cGRCUs[0];
if(!temp)
return 0;
//---
return temp.GetCount();
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
uint CNeuronHimNetSpatEncoder::GetChebK(void) const
{
if(cGRCUs.Total() <= 0)
return 0;
CNeuronHimNetGCRU* temp = cGRCUs[0];
if(!temp)
return 0;
//---
return temp.GetChebK();
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
uint CNeuronHimNetSpatEncoder::GetWindowIn(void) const
{
if(cGRCUs.Total() <= 0)
return 0;
CNeuronHimNetGCRU* temp = cGRCUs[0];
if(!temp)
return 0;
//---
return temp.GetWindowIn();
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
uint CNeuronHimNetSpatEncoder::GetWindowOut(void) const
{
uint count = GetCount();
if(count <= 0)
return 0;
//---
return Neurons() / count;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CNeuronHimNetSpatEncoder::SetGradient(CBufferFloat *buffer, bool delete_prev = true)
{
if(!CNeuronBaseOCL::SetGradient(buffer, delete_prev))
ReturnFalse;
//---
CNeuronBaseOCL* temp = cGRCUs[-1];
if(!temp ||
!temp.SetGradient(Gradient, delete_prev))
ReturnFalse;
//---
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CNeuronHimNetTempEncoder::SetGradient(CBufferFloat *buffer, bool delete_prev = true)
{
if(!CNeuronBaseOCL::SetGradient(buffer, delete_prev))
ReturnFalse;
//---
CNeuronBaseOCL* temp = cGRCUs[-1];
if(!temp ||
!temp.SetGradient(Gradient, delete_prev))
ReturnFalse;
//---
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CNeuronHimNetEncoder::Init(uint numOutputs, uint myIndex, COpenCLMy *open_cl,
uint units, uint window, uint window_out, uint cheb_k,
uint layers, uint embed_dim, uint period1,
uint timeframe1, uint period2, uint timeframe2,
ENUM_OPTIMIZATION optimization_type, uint batch)
{
if(!CNeuronBaseOCL::Init(numOutputs, myIndex, open_cl, window_out * units, optimization_type, batch))
ReturnFalse;
//---
int index = 0;
if(!cEmbedding.Init(0, index, OpenCL, units * embed_dim, optimization, iBatch))
ReturnFalse;
SetActivationFunction(TANH);
index++;
if(!cEmbeddingT.Init(0, index, OpenCL, units, embed_dim, optimization, iBatch))
ReturnFalse;
index++;
if(!cSupport.Init(0, index, OpenCL, units * units, optimization, iBatch))
ReturnFalse;
cSupport.SetActivationFunction(None);
index++;
if(!cNormSupport.Init(0, index, OpenCL, cSupport.Neurons(), optimization, iBatch))
ReturnFalse;
cNormSupport.SetHeads(units);
cNormSupport.SetActivationFunction(None);
index++;
if(!cPolinomSupport.Init(0, index, OpenCL, units, cheb_k, optimization, iBatch))
ReturnFalse;
index++;
if(!cTempEncoder.Init(0, index, OpenCL, units, window, window_out, cheb_k, layers, (embed_dim + 1) / 2, period1, timeframe1, period2, timeframe2, optimization, iBatch))
ReturnFalse;
index++;
if(!cSpatEncoder.Init(0, index, OpenCL, units, window, window_out, cheb_k, layers, embed_dim, optimization, iBatch))
ReturnFalse;
//---
if(!SetGradient(cTempEncoder.getGradient(), true))
ReturnFalse;
//---
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CNeuronHimNetEncoder::feedForward(CNeuronBaseOCL *NeuronOCL, CBufferFloat *SecondInput)
{
if(!SecondInput)
ReturnFalse;
//---
if(bTrain)
{
if(!cEmbedding.FeedForward())
ReturnFalse;
if(!cEmbeddingT.FeedForward(cEmbedding.AsObject()))
ReturnFalse;
if(!MatMul(cEmbedding.getOutput(), cEmbeddingT.getOutput(), cSupport.getOutput(),
cEmbeddingT.GetCount(), cEmbeddingT.GetWindow(), cEmbeddingT.GetCount(), 1, false))
ReturnFalse;
if(!cNormSupport.FeedForward(cSupport.AsObject()))
ReturnFalse;
if(!cPolinomSupport.FeedForward(cNormSupport.AsObject()))
ReturnFalse;
}
//---
if(!cTempEncoder.feedForward(NeuronOCL, cPolinomSupport.AsObject(), int(SecondInput[0])))
ReturnFalse;
if(!cSpatEncoder.feedForward(NeuronOCL, cPolinomSupport.AsObject()))
ReturnFalse;
if(!SumAndNormalize(cTempEncoder.getOutput(), cSpatEncoder.getOutput(), Output,
cTempEncoder.GetWindowOut(), false, 0, 0, 0, 1))
ReturnFalse;
//---
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CNeuronHimNetEncoder::calcInputGradients(CNeuronBaseOCL *prevLayer)
{
if(!cTempEncoder.calcInputGradients(prevLayer, cPolinomSupport.AsObject()))
ReturnFalse;
CBufferFloat* temp = cPolinomSupport.getGradient();
CBufferFloat* prev = prevLayer.getGradient();
if(!cPolinomSupport.SetGradient(cPolinomSupport.getPrevOutput(), false) ||
!prevLayer.SetGradient(prevLayer.getPrevOutput(), false) ||
!cSpatEncoder.calcInputGradients(prevLayer, cPolinomSupport.AsObject()) ||
!SumAndNormalize(temp, cPolinomSupport.getGradient(), temp,
cSpatEncoder.GetCount(), false, 0, 0, 0, 1) ||
!SumAndNormalize(prev, prevLayer.getGradient(), prev,
cSpatEncoder.GetCount(), false, 0, 0, 0, 1) ||
!cPolinomSupport.SetGradient(temp, false) ||
!prevLayer.SetGradient(prev, false))
ReturnFalse;
if(prevLayer.Activation() != None)
if(!DeActivation(prevLayer.getOutput(), prev, prev, prevLayer.Activation()))
ReturnFalse;
//---
if(!cNormSupport.CalcHiddenGradients(cPolinomSupport.AsObject()))
ReturnFalse;
if(!cSupport.CalcHiddenGradients(cNormSupport.AsObject()))
ReturnFalse;
if(!MatMulGrad(cEmbedding.getOutput(), cEmbedding.getPrevOutput(),
cEmbeddingT.getOutput(), cEmbeddingT.getGradient(),
cSupport.getGradient(),
cEmbeddingT.GetCount(), cEmbeddingT.GetWindow(), cEmbeddingT.GetCount(), 1, false))
ReturnFalse;
if(!cEmbedding.CalcHiddenGradients(cEmbeddingT.AsObject()))
ReturnFalse;
if(!SumAndNormalize(cEmbedding.getGradient(), cEmbedding.getPrevOutput(), cEmbedding.getGradient(),
cEmbeddingT.GetWindow(), false, 0, 0, 0, 1))
ReturnFalse;
if(cEmbedding.Activation() != None)
if(!DeActivation(cEmbedding.getOutput(), cEmbedding.getGradient(),
cEmbedding.getGradient(), cEmbedding.Activation()))
ReturnFalse;
//---
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CNeuronHimNetEncoder::updateInputWeights(CNeuronBaseOCL *NeuronOCL)
{
if(!cEmbedding.UpdateInputWeights())
ReturnFalse;
if(!cTempEncoder.updateInputWeights(NeuronOCL, cPolinomSupport.AsObject()))
ReturnFalse;
if(!cSpatEncoder.updateInputWeights(NeuronOCL, cPolinomSupport.AsObject()))
ReturnFalse;
//---
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CNeuronHimNetEncoder::WeightsUpdate(CNeuronBaseOCL *source, float tau)
{
if(!CNeuronBaseOCL::WeightsUpdate(source, tau))
ReturnFalse;
//---
CNeuronHimNetEncoder* Source = source;
if(!cEmbedding.WeightsUpdate(Source.cEmbedding.AsObject(), tau))
ReturnFalse;
if(!cTempEncoder.WeightsUpdate(Source.cTempEncoder.AsObject(), tau))
ReturnFalse;
if(!cSpatEncoder.WeightsUpdate(Source.cSpatEncoder.AsObject(), tau))
ReturnFalse;
//---
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CNeuronHimNetEncoder::Save(const int file_handle)
{
if(!CNeuronBaseOCL::Save(file_handle))
ReturnFalse;
//---
if(!cEmbedding.Save(file_handle))
ReturnFalse;
if(!cEmbeddingT.Save(file_handle))
ReturnFalse;
if(!cSupport.Save(file_handle))
ReturnFalse;
if(!cNormSupport.Save(file_handle))
ReturnFalse;
if(!cPolinomSupport.Save(file_handle))
ReturnFalse;
if(!cTempEncoder.Save(file_handle))
ReturnFalse;
if(!cSpatEncoder.Save(file_handle))
ReturnFalse;
//---
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CNeuronHimNetEncoder::Load(const int file_handle)
{
if(!CNeuronBaseOCL::Load(file_handle))
ReturnFalse;
//---
if(!LoadInsideLayer(file_handle, cEmbedding.AsObject()))
ReturnFalse;
if(!LoadInsideLayer(file_handle, cEmbeddingT.AsObject()))
ReturnFalse;
if(!LoadInsideLayer(file_handle, cSupport.AsObject()))
ReturnFalse;
if(!LoadInsideLayer(file_handle, cNormSupport.AsObject()))
ReturnFalse;
if(!LoadInsideLayer(file_handle, cPolinomSupport.AsObject()))
ReturnFalse;
if(!LoadInsideLayer(file_handle, cTempEncoder.AsObject()))
ReturnFalse;
if(!LoadInsideLayer(file_handle, cSpatEncoder.AsObject()))
ReturnFalse;
//---
if(!SetGradient(cTempEncoder.getGradient(), true))
ReturnFalse;
//---
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CNeuronHimNetEncoder::SetOpenCL(COpenCLMy *obj)
{
CNeuronBaseOCL::SetOpenCL(obj);
//---
cEmbedding.SetOpenCL(OpenCL);
cEmbeddingT.SetOpenCL(OpenCL);
cSupport.SetOpenCL(OpenCL);
cNormSupport.SetOpenCL(OpenCL);
cPolinomSupport.SetOpenCL(OpenCL);
cTempEncoder.SetOpenCL(OpenCL);
cSpatEncoder.SetOpenCL(OpenCL);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CNeuronHimNetEncoder::TrainMode(bool flag)
{
CNeuronBaseOCL::TrainMode(flag);
//---
cEmbedding.TrainMode(bTrain);
cEmbeddingT.TrainMode(bTrain);
cSupport.TrainMode(bTrain);
cNormSupport.TrainMode(bTrain);
cPolinomSupport.TrainMode(bTrain);
cTempEncoder.TrainMode(bTrain);
cSpatEncoder.TrainMode(bTrain);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CNeuronHimNetEncoder::Clear(void)
{
if(!CNeuronBaseOCL::Clear())
ReturnFalse;
//---
if(!cEmbedding.Clear())
ReturnFalse;
if(!cEmbeddingT.Clear())
ReturnFalse;
if(!cSupport.Clear())
ReturnFalse;
if(!cNormSupport.Clear())
ReturnFalse;
if(!cPolinomSupport.Clear())
ReturnFalse;
if(!cTempEncoder.Clear())
ReturnFalse;
if(!cSpatEncoder.Clear())
ReturnFalse;
//---
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CNeuronHimNetEncoder::SetGradient(CBufferFloat *buffer, bool delete_prev = true)
{
if(!CNeuronBaseOCL::SetGradient(buffer, delete_prev))
ReturnFalse;
//---
if(!cTempEncoder.SetGradient(Gradient, delete_prev))
ReturnFalse;
if(!cSpatEncoder.SetGradient(Gradient, delete_prev))
ReturnFalse;
//---
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CNeuronHimNetDecoder::Init(uint numOutputs, uint myIndex, COpenCLMy *open_cl,
uint units, uint window, uint window_out,
uint cheb_k, uint layers, uint embed_dim,
ENUM_OPTIMIZATION optimization_type, uint batch)
{
if(!CNeuronBaseOCL::Init(numOutputs, myIndex, open_cl, window_out * units, optimization_type, batch))
ReturnFalse;
//---
int index = 0;
if(!cProjection.Init(0, index, OpenCL, window, window, embed_dim, units, 1, optimization, iBatch))
ReturnFalse;
SetActivationFunction(TANH);
index++;
if(!cProjectionT.Init(0, index, OpenCL, units, embed_dim, optimization, iBatch))
ReturnFalse;
index++;
if(!cEmbedding.Init(0, index, OpenCL, units, units, 1, 1, embed_dim, optimization, iBatch))
ReturnFalse;
SetActivationFunction(SIGMOID);
index++;
if(!cSupport.Init(0, index, OpenCL, units * units, optimization, iBatch))
ReturnFalse;
cSupport.SetActivationFunction(None);
index++;
if(!cNormSupport.Init(0, index, OpenCL, cSupport.Neurons(), optimization, iBatch))
ReturnFalse;
cNormSupport.SetHeads(units);
cNormSupport.SetActivationFunction(None);
index++;
if(!cPolinomSupport.Init(0, index, OpenCL, units, cheb_k, optimization, iBatch))
ReturnFalse;
//---
cGRCUs.Clear();
cGRCUs.SetOpenCL(OpenCL);
index++;
CNeuronHimNetGCRU *temp = new CNeuronHimNetGCRU();
if(!temp ||
!temp.Init(0, index, OpenCL, units, window, window_out, cheb_k, embed_dim, optimization, iBatch) ||
!cGRCUs.Add(temp))
{
DeleteObj(temp);
ReturnFalse;
}
for(uint i = 1; i < layers; i++)
{
index++;
temp = new CNeuronHimNetGCRU();
if(!temp ||
!temp.Init(0, index, OpenCL, units, window_out, window_out, cheb_k, 2 * embed_dim, optimization, iBatch) ||
!cGRCUs.Add(temp))
{
DeleteObj(temp);
ReturnFalse;
}
}
//---
bSupportAccum.BufferFree();
bSupportAccum.Clear();
if(!bSupportAccum.BufferInit(cPolinomSupport.Neurons(), 0) ||
!bSupportAccum.BufferCreate(OpenCL))
ReturnFalse;
bEmbeddingAccum.BufferFree();
bEmbeddingAccum.Clear();
if(!bEmbeddingAccum.BufferInit(cEmbedding.Neurons(), 0) ||
!bEmbeddingAccum.BufferCreate(OpenCL))
ReturnFalse;
//---
SetActivationFunction((ENUM_ACTIVATION)temp.Activation());
if(!SetOutput(temp.getOutput(), true) ||
!SetGradient(temp.getGradient(), true))
ReturnFalse;
//---
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CNeuronHimNetDecoder::feedForward(CNeuronBaseOCL *NeuronOCL)
{
if(!cProjection.FeedForward(NeuronOCL))
ReturnFalse;
if(!cProjectionT.FeedForward(cProjection.AsObject()))
ReturnFalse;
if(!MatMul(cProjection.getOutput(), cProjectionT.getOutput(), cSupport.getOutput(),
cProjectionT.GetCount(), cProjectionT.GetWindow(), cProjectionT.GetCount(), 1, false))
ReturnFalse;
if(!cNormSupport.FeedForward(cSupport.AsObject()))
ReturnFalse;
if(!cPolinomSupport.FeedForward(cNormSupport.AsObject()))
ReturnFalse;
//---
if(!cEmbedding.FeedForward(cProjectionT.AsObject()))
ReturnFalse;
//---
CNeuronHimNetGCRU* current = NULL;
CNeuronBaseOCL* inputs = NeuronOCL;
for(int i = 0; i < cGRCUs.Total(); i++)
{
current = cGRCUs[i];
if(!current ||
!current.feedForward(NeuronOCL, cPolinomSupport.AsObject(), cEmbedding.AsObject()))
ReturnFalse;
inputs = current;
}
//---
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CNeuronHimNetDecoder::calcInputGradients(CNeuronBaseOCL *prevLayer)
{
if(!prevLayer)
ReturnFalse;
//---
CNeuronBaseOCL *inputs = (cGRCUs.Total() > 1 ? cGRCUs[-2] : prevLayer);
CNeuronHimNetGCRU* current = cGRCUs[-1];
if(!current ||
!current.calcInputGradients(inputs, cPolinomSupport.AsObject(), cEmbedding.AsObject()))
ReturnFalse;
if(cGRCUs.Total() > 1)
{
CBufferFloat *sup = cPolinomSupport.getGradient();
if(!cPolinomSupport.SetGradient(GetPointer(bSupportAccum), false))
ReturnFalse;
CBufferFloat *emb = cEmbedding.getGradient();
if(!cEmbedding.SetGradient(GetPointer(bEmbeddingAccum), false))
ReturnFalse;
for(int i = cGRCUs.Total() - 2; i >= 0; i--)
{
current = cGRCUs[i];
inputs = (i > 0 ? cGRCUs[i - 1] : prevLayer);
if(!current ||
!current.calcInputGradients(inputs, cPolinomSupport.AsObject(), cEmbedding.AsObject()))
ReturnFalse;
if(!SumAndNormalize(cPolinomSupport.getGradient(), sup, sup, 1, false, 0, 0, 0, 1))
ReturnFalse;
if(!SumAndNormalize(cEmbedding.getGradient(), emb, emb, 1, false, 0, 0, 0, 1))
ReturnFalse;
}
if(!cPolinomSupport.SetGradient(sup, false))
ReturnFalse;
if(!cEmbedding.SetGradient(emb, false))
ReturnFalse;
}
if(!cNormSupport.CalcHiddenGradients(cPolinomSupport.AsObject()))
ReturnFalse;
if(!cSupport.CalcHiddenGradients(cNormSupport.AsObject()))
ReturnFalse;
if(!MatMulGrad(cProjection.getOutput(), cProjection.getPrevOutput(),
cProjectionT.getOutput(), cProjectionT.getPrevOutput(),
cSupport.getGradient(), cProjectionT.GetCount(),
cProjectionT.GetWindow(), cProjectionT.GetCount(), 1, false))
ReturnFalse;
if(!cProjectionT.CalcHiddenGradients(cEmbedding.AsObject()))
ReturnFalse;
if(cProjectionT.Activation() != None)
if(!DeActivation(cProjectionT.getOutput(), cProjectionT.getPrevOutput(),
cProjectionT.getPrevOutput(), cProjectionT.Activation()))
ReturnFalse;
if(!SumAndNormalize(cProjectionT.getGradient(), cProjectionT.getPrevOutput(),
cProjectionT.getGradient(), cProjectionT.GetCount(), false, 0, 0, 0, 1))
ReturnFalse;
if(!cProjection.CalcHiddenGradients(cProjectionT.AsObject()))
ReturnFalse;
if(cProjection.Activation() != None)
if(!DeActivation(cProjection.getOutput(), cProjection.getPrevOutput(),
cProjection.getPrevOutput(), cProjection.Activation()))
ReturnFalse;
if(!SumAndNormalize(cProjection.getGradient(), cProjection.getPrevOutput(),
cProjection.getGradient(), cProjectionT.GetWindow(), false, 0, 0, 0, 1))
ReturnFalse;
//---
CBufferFloat* temp = prevLayer.getGradient();
if(!prevLayer.SetGradient(prevLayer.getPrevOutput(), false) ||
!prevLayer.CalcHiddenGradients(cProjection.AsObject()) ||
!SumAndNormalize(temp, prevLayer.getGradient(), temp, 1, false, 0, 0, 0, 1) ||
!prevLayer.SetGradient(temp, false))
ReturnFalse;
//---
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CNeuronHimNetDecoder::updateInputWeights(CNeuronBaseOCL *NeuronOCL)
{
if(!cProjection.UpdateInputWeights(NeuronOCL))
ReturnFalse;
if(!cEmbedding.UpdateInputWeights(cProjectionT.AsObject()))
ReturnFalse;
//---
CNeuronBaseOCL* inputs = NeuronOCL;
CNeuronHimNetGCRU* current = NULL;
for(int i = 0; i < cGRCUs.Total(); i++)
{
current = cGRCUs[i];
if(!current.updateInputWeights(inputs, cPolinomSupport.AsObject(), cEmbedding.AsObject()))
ReturnFalse;
inputs = current;
}
//---
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CNeuronHimNetDecoder::WeightsUpdate(CNeuronBaseOCL *source, float tau)
{
if(!CNeuronBaseOCL::WeightsUpdate(source, tau))
ReturnFalse;
//---
CNeuronHimNetDecoder* Source = source;
if(!cProjection.WeightsUpdate(Source.cProjection.AsObject(), tau))
ReturnFalse;
if(!cEmbedding.WeightsUpdate(Source.cEmbedding.AsObject(), tau))
ReturnFalse;
if(!cGRCUs.WeightsUpdate(Source.cGRCUs.AsObject(), tau))
ReturnFalse;
//---
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CNeuronHimNetDecoder::Save(const int file_handle)
{
if(!CNeuronBaseOCL::Save(file_handle))
ReturnFalse;
//---
if(!cProjection.Save(file_handle))
ReturnFalse;
if(!cProjectionT.Save(file_handle))
ReturnFalse;
if(!cEmbedding.Save(file_handle))
ReturnFalse;
if(!cSupport.Save(file_handle))
ReturnFalse;
if(!cNormSupport.Save(file_handle))
ReturnFalse;
if(!cPolinomSupport.Save(file_handle))
ReturnFalse;
if(!cGRCUs.Save(file_handle))
ReturnFalse;
//---
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CNeuronHimNetDecoder::Load(const int file_handle)
{
if(!CNeuronBaseOCL::Load(file_handle))
ReturnFalse;
//---
if(!LoadInsideLayer(file_handle, cProjection.AsObject()))
ReturnFalse;
if(!LoadInsideLayer(file_handle, cProjectionT.AsObject()))
ReturnFalse;
if(!LoadInsideLayer(file_handle, cEmbedding.AsObject()))
ReturnFalse;
if(!LoadInsideLayer(file_handle, cSupport.AsObject()))
ReturnFalse;
if(!LoadInsideLayer(file_handle, cNormSupport.AsObject()))
ReturnFalse;
if(!LoadInsideLayer(file_handle, cPolinomSupport.AsObject()))
ReturnFalse;
if(!cGRCUs.Load(file_handle))
ReturnFalse;
//---
bSupportAccum.BufferFree();
bSupportAccum.Clear();
CNeuronHimNetGCRU* temp = cGRCUs[-1];
if(!bSupportAccum.BufferInit(cPolinomSupport.Neurons(), 0) ||
!bSupportAccum.BufferCreate(OpenCL))
ReturnFalse;
bEmbeddingAccum.BufferFree();
bEmbeddingAccum.Clear();
if(!bEmbeddingAccum.BufferInit(cEmbedding.Neurons(), 0) ||
!bEmbeddingAccum.BufferCreate(OpenCL))
ReturnFalse;
//---
SetActivationFunction((ENUM_ACTIVATION)temp.Activation());
if(!SetOutput(temp.getOutput(), true) ||
!SetGradient(temp.getGradient(), true))
ReturnFalse;
//---
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CNeuronHimNetDecoder::SetOpenCL(COpenCLMy *obj)
{
CNeuronBaseOCL::SetOpenCL(obj);
//---
cProjection.SetOpenCL(OpenCL);
cProjectionT.SetOpenCL(OpenCL);
cEmbedding.SetOpenCL(OpenCL);
cSupport.SetOpenCL(OpenCL);
cNormSupport.SetOpenCL(OpenCL);
cPolinomSupport.SetOpenCL(OpenCL);
cGRCUs.SetOpenCL(OpenCL);
//---
bSupportAccum.BufferFree();
bSupportAccum.BufferCreate(OpenCL);
bEmbeddingAccum.BufferFree();
bEmbeddingAccum.BufferCreate(OpenCL);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CNeuronHimNetDecoder::Clear(void)
{
if(!CNeuronBaseOCL::Clear())
ReturnFalse;
//---
if(!cProjection.Clear())
ReturnFalse;
if(!cProjectionT.Clear())
ReturnFalse;
if(!cEmbedding.Clear())
ReturnFalse;
if(!cSupport.Clear())
ReturnFalse;
if(!cNormSupport.Clear())
ReturnFalse;
if(!cPolinomSupport.Clear())
ReturnFalse;
CNeuronBaseOCL* temp = NULL;
for(int i = 0; i < cGRCUs.Total(); i++)
{
temp = cGRCUs[i];
if(!temp || !temp.Clear())
ReturnFalse;
}
//---
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CNeuronFastGConv::Init(uint numOutputs, uint myIndex, COpenCLMy *open_cl,
uint units, uint window, uint sparse_dimension,
ENUM_OPTIMIZATION optimization_type, uint batch)
{
if(!CNeuronBaseOCL::Init(numOutputs, myIndex, open_cl, units * window, optimization_type, batch))
ReturnFalse;
activation = None;
//---
int index = 0;
if(!cInpAndHidden.Init(0, index, OpenCL, 2 * units * window, optimization, iBatch))
ReturnFalse;
index++;
if(!cNormAttention.Init(0, index, OpenCL, units * sparse_dimension, optimization, iBatch))
ReturnFalse;
index++;
if(!cInvDiag.Init(0, index, OpenCL, units, optimization, iBatch))
ReturnFalse;
index++;
if(!cAX.Init(0, index, OpenCL, cInpAndHidden.Neurons(), optimization, iBatch))
ReturnFalse;
index++;
if(!cAXplusX.Init(0, index, OpenCL, cInpAndHidden.Neurons(), optimization, iBatch))
ReturnFalse;
index++;
if(!cNormAXplusX.Init(0, index, OpenCL, cInpAndHidden.Neurons(), optimization, iBatch))
ReturnFalse;
index++;
if(!cZ_R.Init(0, index, OpenCL, 2 * window, 2 * window, 2 * window, units, 1, optimization, iBatch))
ReturnFalse;
cZ_R.SetActivationFunction(SIGMOID);
index++;
if(!cZ.Init(0, index, OpenCL, window * units, optimization, iBatch))
ReturnFalse;
index++;
if(!cR.Init(0, index, OpenCL, window * units, optimization, iBatch))
ReturnFalse;
index++;
if(!cCandidate.Init(0, index, OpenCL, 2 * window * units, optimization, iBatch))
ReturnFalse;
index++;
if(!cHC.Init(0, index, OpenCL, 2 * window, 2 * window, window, units, 1, optimization, iBatch))
ReturnFalse;
cHC.SetActivationFunction(TANH);
//---
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CNeuronFastGConv::RandomWalk(CBufferFloat *data,
CBufferFloat *normal,
CBufferFloat *inv_diag,
const int rows,
const int cols)
{
if(!OpenCL)
ReturnFalse;
uint global_work_offset[2] = {0, 0};
uint global_work_size[2] = {(uint)rows, MathMin((uint)cols, (uint)OpenCL.GetMaxLocalSize(1))};
uint local_work_size[2] = {1, global_work_size[1]};
uint kernel = def_k_RandomWalk;
setBuffer(kernel, def_k_rw_data, data.GetIndex())
setBuffer(kernel, def_k_rw_norm, normal.GetIndex())
setBuffer(kernel, def_k_rw_inv_diag, inv_diag.GetIndex())
setArgument(kernel, def_k_rw_total_cols, cols)
//---
kernelExecuteLoc(kernel, global_work_offset, global_work_size, local_work_size)
#ifdef _DEBUG
if(!inv_diag.BufferRead())
ReturnFalse;
#endif
//---
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CNeuronFastGConv::FeedForward(CNeuronBaseOCL *SourceData, CNeuronSNSMHAttention *SparseAttent)
{
if(!SourceData || !SparseAttent)
ReturnFalse;
//---
const uint units = GetCount();
const uint window = GetWindow();
const uint sparse = GetSparseDimension();
//---
if(!RandomWalk(SparseAttent.getOutput(), cNormAttention.getOutput(), cInvDiag.getOutput(), window, sparse))
ReturnFalse;
if(!SwapOutputs())
ReturnFalse;
if(!Concat(SourceData.getOutput(), PrevOutput, cInpAndHidden.getOutput(), window, window, units))
ReturnFalse;
//---
if(!SparseMatMul(SparseAttent.GetIndexes(), cNormAttention.getOutput(), cInpAndHidden.getOutput(),
cAX.getOutput(), units, sparse, units, 2 * window))
ReturnFalse;
if(!SumAndNormalize(cAX.getOutput(), cInpAndHidden.getOutput(), cAXplusX.getOutput(), 2 * window, false, 0, 0, 0, 1))
ReturnFalse;
if(!DiagMatMul(cInvDiag.getOutput(), cAXplusX.getOutput(), cNormAXplusX.getOutput(), units, 2 * window, 1, None))
ReturnFalse;
if(!cZ_R.FeedForward(cNormAXplusX.AsObject()))
ReturnFalse;
if(!DeConcat(cZ.getOutput(), cR.getOutput(), cZ_R.getOutput(), window, window, units))
ReturnFalse;
if(!ElementMult(cR.getOutput(), PrevOutput, cR.getPrevOutput()))
ReturnFalse;
if(!Concat(SourceData.getOutput(), cR.getPrevOutput(), cCandidate.getOutput(), window, window, units))
ReturnFalse;
if(!cHC.FeedForward(cCandidate.AsObject()))
ReturnFalse;
if(!GateElementMult(PrevOutput, cHC.getOutput(), cZ.getOutput(), Output))
ReturnFalse;
//---
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CNeuronFastGConv::CalcInputGradients(CNeuronBaseOCL *SourceData, CNeuronSNSMHAttention *SparseAttent)
{
if(!SourceData || !SparseAttent)
ReturnFalse;
//---
const uint units = GetCount();
const uint window = GetWindow();
const uint sparse = GetSparseDimension();
//---
if(!GateElementMultGrad(PrevOutput, cInpAndHidden.getGradient(),
cHC.getOutput(), cHC.getGradient(),
cZ.getOutput(), cZ.getGradient(),
Gradient, None, cHC.Activation(), cZ_R.Activation()))
ReturnFalse;
if(!cCandidate.CalcHiddenGradients(cHC.AsObject()))
ReturnFalse;
if(!DeConcat(SourceData.getGradient(), cR.getPrevOutput(),
cCandidate.getGradient(), window, window, units))
ReturnFalse;
if(!ElementMultGrad(cR.getOutput(), cR.getGradient(),
PrevOutput, cInpAndHidden.getGradient(),
cR.getPrevOutput(), cZ_R.Activation(), None))
ReturnFalse;
if(!Concat(cZ.getGradient(), cR.getGradient(),
cZ_R.getGradient(), window, window, units))
ReturnFalse;
if(!cNormAXplusX.CalcHiddenGradients(cZ_R.AsObject()))
ReturnFalse;
if(!DiagMatMulGrad(cInvDiag.getOutput(), cInvDiag.getGradient(),
cAXplusX.getOutput(), cAX.getGradient(),
cNormAXplusX.getGradient(), units, 2 * window, 1))
ReturnFalse;
if(!SparseMatMulGrad(SparseAttent.GetIndexes(), cNormAttention.getOutput(),
cNormAttention.getGradient(), cInpAndHidden.getOutput(),
cInpAndHidden.getGradient(), cAX.getGradient(),
units, sparse, units, 2 * window))
ReturnFalse;
if(!SumAndNormalize(cAX.getGradient(), cInpAndHidden.getGradient(),
cInpAndHidden.getGradient(), 2 * window, false, 0, 0, 0, 1))
ReturnFalse;
if(!DeConcat(cAXplusX.getGradient(), cAXplusX.getPrevOutput(),
cInpAndHidden.getGradient(), window, window, units))
ReturnFalse;
if(!SumAndNormalize(SourceData.getGradient(), cAXplusX.getGradient(),
SourceData.getGradient(), window, false, 0, 0, 0, 1))
ReturnFalse;
if(SourceData.Activation() != None)
if(!DeActivation(SourceData.getOutput(), SourceData.getGradient(),
SourceData.getGradient(), SourceData.Activation()))
ReturnFalse;
if(!DiagMatMul(cInvDiag.getOutput(), cNormAttention.getGradient(),
SparseAttent.getGradient(), units, sparse, 1, None))
ReturnFalse;
//---
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CNeuronFastGConv::updateInputWeights(CNeuronBaseOCL *NeuronOCL)
{
//---
if(!cZ_R.UpdateInputWeights(cNormAXplusX.AsObject()))
ReturnFalse;
if(!cHC.UpdateInputWeights(cCandidate.AsObject()))
ReturnFalse;
//---
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CNeuronFastGConv::WeightsUpdate(CNeuronBaseOCL *source, float tau)
{
if(!CNeuronBaseOCL::WeightsUpdate(source, tau))
ReturnFalse;
//---
CNeuronFastGConv *Source = source;
if(!cZ_R.WeightsUpdate(Source.cZ_R.AsObject(), tau))
ReturnFalse;
if(!cHC.WeightsUpdate(Source.cHC.AsObject(), tau))
ReturnFalse;
//---
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CNeuronFastGConv::Save(const int file_handle)
{
if(!CNeuronBaseOCL::Save(file_handle))
ReturnFalse;
//---
if(!cZ_R.Save(file_handle))
ReturnFalse;
if(!cHC.Save(file_handle))
ReturnFalse;
if(FileWriteInteger(file_handle, (int)GetSparseDimension()) < INT_VALUE)
ReturnFalse;
//---
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CNeuronFastGConv::Load(const int file_handle)
{
if(!CNeuronBaseOCL::Load(file_handle))
ReturnFalse;
//---
if(!LoadInsideLayer(file_handle, cZ_R.AsObject()))
ReturnFalse;
if(!LoadInsideLayer(file_handle, cHC.AsObject()))
ReturnFalse;
//---
if(FileIsEnding(file_handle))
ReturnFalse;
uint sparse_dimension = FileReadInteger(file_handle);
uint units = cZ_R.GetUnits();
uint window_out = Neurons() / units;
uint window = cZ_R.GetWindow() - window_out;
//---
int index = 0;
if(!cInpAndHidden.Init(0, index, OpenCL, units * (window + window_out), optimization, iBatch))
ReturnFalse;
index++;
if(!cNormAttention.Init(0, index, OpenCL, units * sparse_dimension, optimization, iBatch))
ReturnFalse;
index++;
if(!cInvDiag.Init(0, index, OpenCL, units, optimization, iBatch))
ReturnFalse;
index++;
if(!cAX.Init(0, index, OpenCL, cInpAndHidden.Neurons(), optimization, iBatch))
ReturnFalse;
index++;
if(!cAXplusX.Init(0, index, OpenCL, cInpAndHidden.Neurons(), optimization, iBatch))
ReturnFalse;
index++;
if(!cNormAXplusX.Init(0, index, OpenCL, cInpAndHidden.Neurons(), optimization, iBatch))
ReturnFalse;
index += 2;
if(!cZ.Init(0, index, OpenCL, window_out * units, optimization, iBatch))
ReturnFalse;
index++;
if(!cR.Init(0, index, OpenCL, window_out * units, optimization, iBatch))
ReturnFalse;
index++;
if(!cCandidate.Init(0, index, OpenCL, (window + window_out) * units, optimization, iBatch))
ReturnFalse;
//---
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CNeuronFastGConv::SetOpenCL(COpenCLMy *obj)
{
CNeuronBaseOCL::SetOpenCL(obj);
//---
cZ_R.SetOpenCL(OpenCL);
cHC.SetOpenCL(OpenCL);
cInpAndHidden.SetOpenCL(OpenCL);
cNormAttention.SetOpenCL(OpenCL);
cInvDiag.SetOpenCL(OpenCL);
cAX.SetOpenCL(OpenCL);
cAXplusX.SetOpenCL(OpenCL);
cNormAXplusX.SetOpenCL(OpenCL);
cZ.SetOpenCL(OpenCL);
cR.SetOpenCL(OpenCL);
cCandidate.SetOpenCL(OpenCL);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CNeuronSAGDFN::Init(uint numOutputs, uint myIndex, COpenCLMy *open_cl,
uint time_steps, uint variables, uint embedding_dim,
uint emb_layers, uint sparse_dimension, uint heads,
float sparse, uint gcru_layers,
uint forecast, uint forec_layers,
ENUM_OPTIMIZATION optimization_type, uint batch)
{
if(emb_layers <= 0 || gcru_layers <= 0 || forec_layers <= 0)
ReturnFalse;
//---
if(!CNeuronTransposeOCL::Init(numOutputs, myIndex, open_cl, variables, forecast, optimization_type, batch))
ReturnFalse;
//---
uint index = 0;
if(!cTranspose.Init(0, index, OpenCL, time_steps, variables, optimization, iBatch))
ReturnFalse;
//--- Embedding
cEmbedding.Clear();
cEmbedding.SetOpenCL(OpenCL);
index++;
CNeuronConvOCL *conv = new CNeuronConvOCL();
if(!conv ||
!conv.Init(0, index, OpenCL, time_steps, time_steps, embedding_dim, variables, 1, optimization, iBatch) ||
!cEmbedding.Add(conv))
{
DeleteObj(conv);
ReturnFalse;
}
conv.SetActivationFunction(SoftPlus);
for(uint i = 1; i < emb_layers; i++)
{
index++;
conv = new CNeuronConvOCL();
if(!conv ||
!conv.Init(0, index, OpenCL, embedding_dim, embedding_dim,
embedding_dim, variables, 1, optimization, iBatch) ||
!cEmbedding.Add(conv))
{
DeleteObj(conv);
ReturnFalse;
}
conv.SetActivationFunction(SoftPlus);
}
CNeuronBatchNormOCL *norm = new CNeuronBatchNormOCL();
index++;
if(!norm ||
!norm.Init(0, index, OpenCL, conv.Neurons(), iBatch, optimization) ||
!cEmbedding.Add(norm))
{
DeleteObj(norm);
ReturnFalse;
}
norm.SetActivationFunction(None);
//--- GCRUs
cGCRU.Clear();
cGCRU.SetOpenCL(OpenCL);
index++;
if(!cAttention.Init(0, index, OpenCL, variables, embedding_dim, heads,
sparse_dimension, sparse, optimization, iBatch))
ReturnFalse;
CNeuronFastGConv *gcru = NULL;
for(uint i = 0; i < gcru_layers; i++)
{
index++;
gcru = new CNeuronFastGConv();
if(!gcru ||
!gcru.Init(0, index, OpenCL, variables, embedding_dim, sparse_dimension, optimization, iBatch) ||
!cGCRU.Add(gcru))
{
DeleteObj(gcru);
ReturnFalse;
}
}
//--- Forecast
cProjection.Clear();
cProjection.SetOpenCL(OpenCL);
index++;
conv = new CNeuronConvOCL();
if(!conv ||
!conv.Init(0, index, OpenCL, embedding_dim, embedding_dim,
forecast, variables, 1, optimization, iBatch) ||
!cProjection.Add(conv))
{
DeleteObj(conv);
ReturnFalse;
}
conv.SetActivationFunction(SoftPlus);
for(uint i = 1; i < forec_layers; i++)
{
index++;
conv = new CNeuronConvOCL();
if(!conv ||
!conv.Init(0, index, OpenCL, forecast, forecast,
forecast, variables, 1, optimization, iBatch) ||
!cProjection.Add(conv))
{
DeleteObj(conv);
ReturnFalse;
}
conv.SetActivationFunction(SoftPlus);
}
norm = new CNeuronBatchNormOCL();
index++;
if(!norm ||
!norm.Init(0, index, OpenCL, conv.Neurons(), iBatch, optimization) ||
!cProjection.Add(norm))
{
DeleteObj(norm);
ReturnFalse;
}
norm.SetActivationFunction(None);
//---
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CNeuronSAGDFN::feedForward(CNeuronBaseOCL *NeuronOCL)
{
if(!cTranspose.FeedForward(NeuronOCL))
ReturnFalse;
CNeuronBaseOCL *inputs = cTranspose.AsObject();
CNeuronBaseOCL *current = NULL;
//--- Embedding
for(int i = 0; i < cEmbedding.Total(); i++)
{
current = cEmbedding[i];
if(!current ||
!current.FeedForward(inputs))
ReturnFalse;
inputs = current;
}
//--- GCRUs
if(!cAttention.FeedForward(inputs))
ReturnFalse;
CNeuronFastGConv *gcru = NULL;
for(int i = 0; i < cGCRU.Total(); i++)
{
gcru = cGCRU[i];
if(!gcru ||
!gcru.FeedForward(inputs, cAttention.AsObject()))
ReturnFalse;
inputs = gcru;
}
//--- Forecast
for(int i = 0; i < cProjection.Total(); i++)
{
current = cProjection[i];
if(!current ||
!current.FeedForward(inputs))
ReturnFalse;
inputs = current;
}
//--- result
return CNeuronTransposeOCL::feedForward(inputs);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CNeuronSAGDFN::calcInputGradients(CNeuronBaseOCL *NeuronOCL)
{
if(!NeuronOCL)
ReturnFalse;
//---
if(!CNeuronTransposeOCL::calcInputGradients(cProjection[-1]))
ReturnFalse;
//--- Forecast
CNeuronBaseOCL *inputs = NULL;
for(int i = cProjection.Total() - 1; i >= 0; i--)
{
inputs = (i > 0 ? cProjection[i - 1] : cGCRU[-1]);
if(!inputs ||
!inputs.CalcHiddenGradients(cProjection[i]))
ReturnFalse;
}
//--- GCRU
CNeuronFastGConv *gcru = cGCRU[-1];
int layers = cGCRU.Total();
inputs = (layers > 1 ? cGCRU[-2] : cEmbedding[-1]);
if(!gcru ||
!gcru.CalcInputGradients(inputs, cAttention.AsObject()))
ReturnFalse;
if(layers > 1)
{
CBufferFloat *temp = cAttention.getGradient();
if(!cAttention.SetGradient(cAttention.getPrevOutput(), false))
ReturnFalse;
for(int i = layers - 2; i >= 0; i--)
{
inputs = (i > 0 ? cGCRU[i - 1] : cEmbedding[-1]);
gcru = cGCRU[i];
if(!gcru ||
!gcru.CalcInputGradients(inputs, cAttention.AsObject()) ||
!SumAndNormalize(temp, cAttention.getGradient(), temp, 1, false, 0, 0, 0, 1))
ReturnFalse;
}
if(!cAttention.SetGradient(temp, false))
ReturnFalse;
}
CBufferFloat *temp = inputs.getGradient();
if(!inputs.SetGradient(inputs.getPrevOutput(), false) ||
!inputs.CalcHiddenGradients(cAttention.AsObject()) ||
!SumAndNormalize(temp, inputs.getGradient(), temp, 1, false, 0, 0, 0, 1) ||
!inputs.SetGradient(temp, false))
ReturnFalse;
//--- Embedding
for(int i = cEmbedding.Total() - 2; i >= 0; i--)
{
inputs = cEmbedding[i];
if(!inputs ||
!inputs.CalcHiddenGradients(cEmbedding[i + 1]))
ReturnFalse;
}
//---
if(!cTranspose.CalcHiddenGradients(inputs))
ReturnFalse;
if(!NeuronOCL.CalcHiddenGradients(cTranspose.AsObject()))
ReturnFalse;
//---
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CNeuronSAGDFN::updateInputWeights(CNeuronBaseOCL *NeuronOCL)
{
CNeuronBaseOCL *inputs = cTranspose.AsObject();
CNeuronBaseOCL *current = NULL;
//--- Embedding
for(int i = 0; i < cEmbedding.Total(); i++)
{
current = cEmbedding[i];
if(!current ||
!current.UpdateInputWeights(inputs))
ReturnFalse;
inputs = current;
}
//--- GCRUs
if(!cAttention.UpdateInputWeights(inputs))
ReturnFalse;
for(int i = 0; i < cGCRU.Total(); i++)
{
current = cGCRU[i];
if(!current ||
!current.UpdateInputWeights(inputs))
ReturnFalse;
inputs = current;
}
//--- Forecast
for(int i = 0; i < cProjection.Total(); i++)
{
current = cProjection[i];
if(!current ||
!current.UpdateInputWeights(inputs))
ReturnFalse;
inputs = current;
}
//--- result
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CNeuronSAGDFN::WeightsUpdate(CNeuronBaseOCL *source, float tau)
{
if(!CNeuronTransposeOCL::WeightsUpdate(source, tau))
ReturnFalse;
CNeuronSAGDFN *Source = source;
//--- Embedding
if(!cEmbedding.WeightsUpdate(Source.cEmbedding.AsObject(), tau))
ReturnFalse;
//--- GCRUs
if(!cAttention.WeightsUpdate(Source.cAttention.AsObject(), tau))
ReturnFalse;
if(!cGCRU.WeightsUpdate(Source.cGCRU.AsObject(), tau))
ReturnFalse;
//--- Forecast
if(!cProjection.WeightsUpdate(Source.cProjection.AsObject(), tau))
ReturnFalse;
//--- result
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CNeuronSAGDFN::Save(const int file_handle)
{
if(!CNeuronTransposeOCL::Save(file_handle))
ReturnFalse;
//---
if(!cTranspose.Save(file_handle))
ReturnFalse;
//--- Embedding
if(!cEmbedding.Save(file_handle))
ReturnFalse;
//--- GCRUs
if(!cGCRU.Save(file_handle) ||
!cAttention.Save(file_handle))
ReturnFalse;
//--- Forecast
if(!cProjection.Save(file_handle))
ReturnFalse;
//---
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CNeuronSAGDFN::Load(const int file_handle)
{
if(!CNeuronTransposeOCL::Load(file_handle))
ReturnFalse;
//---
if(!LoadInsideLayer(file_handle, cTranspose.AsObject()))
ReturnFalse;
//--- Embedding
if(!cEmbedding.Load(file_handle))
ReturnFalse;
//--- GCRUs
if(!cGCRU.Load(file_handle) ||
!LoadInsideLayer(file_handle, cAttention.AsObject()))
ReturnFalse;
//--- Forecast
if(!cProjection.Load(file_handle))
ReturnFalse;
//---
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CNeuronSAGDFN::SetOpenCL(COpenCLMy *obj)
{
CNeuronTransposeOCL::SetOpenCL(obj);
//---
cTranspose.SetOpenCL(OpenCL);
cEmbedding.SetOpenCL(OpenCL);
cGCRU.SetOpenCL(OpenCL);
cAttention.SetOpenCL(OpenCL);
cProjection.SetOpenCL(OpenCL);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CNeuronSpatialEmbedding::Init(uint numOutputs, uint myIndex, COpenCLMy *open_cl,
uint units, uint window, uint embed_dim,
ENUM_OPTIMIZATION optimization_type, uint batch)
{
if(!CNeuronBaseOCL::Init(numOutputs, myIndex, open_cl, (window + embed_dim)*units, optimization_type, batch))
ReturnFalse;
activation = None;
if(!cEmbedding.Init(0, 0, OpenCL, embed_dim * units, optimization, iBatch))
ReturnFalse;
cEmbedding.SetActivationFunction(TANH);
//---
iUnits = units;
iWindow = window;
iEmbeddingDim = embed_dim;
//---
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CNeuronSpatialEmbedding::feedForward(CNeuronBaseOCL *NeuronOCL)
{
if(!NeuronOCL)
ReturnFalse;
//---
if(bTrain)
if(!cEmbedding.FeedForward())
ReturnFalse;
//---
if(!Concat(NeuronOCL.getOutput(), cEmbedding.getOutput(), Output, iWindow, iEmbeddingDim, iUnits))
ReturnFalse;
//---
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CNeuronSpatialEmbedding::calcInputGradients(CNeuronBaseOCL *NeuronOCL)
{
if(!NeuronOCL)
ReturnFalse;
if(!DeConcat(NeuronOCL.getGradient(), cEmbedding.getGradient(), Gradient, iWindow, iEmbeddingDim, iUnits))
ReturnFalse;
Deactivation(NeuronOCL)
Deactivation(cEmbedding)
//---
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CNeuronSpatialEmbedding::updateInputWeights(CNeuronBaseOCL *NeuronOCL)
{
if(!cEmbedding.UpdateInputWeights())
ReturnFalse;
//---
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CNeuronSpatialEmbedding::WeightsUpdate(CNeuronBaseOCL *source, float tau)
{
if(!CNeuronBaseOCL::WeightsUpdate(source, tau))
ReturnFalse;
//---
CNeuronSpatialEmbedding *Source = source;
if(!cEmbedding.WeightsUpdate(Source.cEmbedding.AsObject(), tau))
ReturnFalse;
//---
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CNeuronSpatialEmbedding::Save(const int file_handle)
{
if(!CNeuronBaseOCL::Save(file_handle))
ReturnFalse;
//---
if(!cEmbedding.Save(file_handle))
ReturnFalse;
//---
if(FileWriteInteger(file_handle, (int)iUnits) < INT_VALUE)
ReturnFalse;
if(FileWriteInteger(file_handle, (int)iWindow) < INT_VALUE)
ReturnFalse;
if(FileWriteInteger(file_handle, (int)iEmbeddingDim) < INT_VALUE)
ReturnFalse;
//---
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CNeuronSpatialEmbedding::Load(const int file_handle)
{
if(!CNeuronBaseOCL::Load(file_handle))
ReturnFalse;
//---
if(!LoadInsideLayer(file_handle, cEmbedding.AsObject()))
ReturnFalse;
//---
if(FileIsEnding(file_handle))
ReturnFalse;
iUnits = (uint)FileReadInteger(file_handle);
if(FileIsEnding(file_handle))
ReturnFalse;
iWindow = (uint)FileReadInteger(file_handle);
if(FileIsEnding(file_handle))
ReturnFalse;
iEmbeddingDim = (uint)FileReadInteger(file_handle);
//---
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CNeuronSpatialEmbedding::SetOpenCL(COpenCLMy *obj)
{
CNeuronBaseOCL::SetOpenCL(obj);
cEmbedding.SetOpenCL(OpenCL);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CNeuronGraphons::Init(uint numOutputs, uint myIndex, COpenCLMy *open_cl,
uint units, uint window, uint emb_dimension,
uint experts, float dropout,
ENUM_OPTIMIZATION optimization_type, uint batch)
{
if(!CNeuronBaseOCL::Init(numOutputs, myIndex, open_cl, units * units, optimization_type, batch))
ReturnFalse;
activation = None;
//---
int index = 0;
if(!cGraphs.Init(0, index, OpenCL, Neurons()*experts, optimization, iBatch))
ReturnFalse;
cGraphs.SetActivationFunction(SIGMOID);
//---
CNeuronBaseOCL *neuron = NULL;
CNeuronConvOCL *conv = NULL;
CNeuronTransposeOCL *transp = NULL;
CNeuronDropoutOCL *dout = NULL;
CNeuronSoftMaxOCL *softmax = NULL;
//--- Probability
acProbability.Clear();
acProbability.SetOpenCL(OpenCL);
index++;
conv = new CNeuronConvOCL();
if(!conv ||
!conv.Init(experts, index, OpenCL, window, window, experts, units, 1, optimization, iBatch) ||
!acProbability.Add(conv))
{
DeleteObj(conv);
ReturnFalse;
}
conv.SetActivationFunction(SoftPlus);
index++;
neuron = new CNeuronBaseOCL();
if(!neuron ||
!neuron.Init(0, index, OpenCL, experts, optimization, iBatch) ||
!acProbability.Add(neuron))
{
DeleteObj(neuron);
ReturnFalse;
}
index++;
dout = new CNeuronDropoutOCL();
if(!dout ||
!dout.Init(0, index, OpenCL, experts, dropout, optimization, iBatch) ||
!acProbability.Add(dout))
{
DeleteObj(dout);
ReturnFalse;
}
index++;
softmax = new CNeuronSoftMaxOCL();
if(!softmax ||
!softmax.Init(0, index, OpenCL, experts, optimization, iBatch) ||
!acProbability.Add(softmax))
{
DeleteObj(softmax);
ReturnFalse;
}
softmax.SetHeads(1);
//--- Data Embedding
acDataEmb.Clear();
acDataEmb.SetOpenCL(OpenCL);
index++;
conv = new CNeuronConvOCL();
if(!conv ||
!conv.Init(0, index, OpenCL, window, window, 2 * emb_dimension, units, 1, optimization, iBatch) ||
!acDataEmb.Add(conv))
{
DeleteObj(conv);
ReturnFalse;
}
conv.SetActivationFunction(SoftPlus);
index++;
conv = new CNeuronConvOCL();
if(!conv ||
!conv.Init(0, index, OpenCL, 2 * emb_dimension, 2 * emb_dimension, emb_dimension, units, 1, optimization, iBatch) ||
!acDataEmb.Add(conv))
{
DeleteObj(conv);
ReturnFalse;
}
conv.SetActivationFunction(None);
index++;
transp = new CNeuronTransposeOCL();
if(!transp ||
!transp.Init(0, index, OpenCL, units, emb_dimension, optimization, iBatch) ||
!acDataEmb.Add(transp))
{
DeleteObj(transp);
ReturnFalse;
}
transp.SetActivationFunction((ENUM_ACTIVATION)conv.Activation());
//---
index++;
if(!cExpertsEmb.Init(0, index, OpenCL, units * emb_dimension * experts, optimization, iBatch))
ReturnFalse;
//---
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CNeuronGraphons::feedForward(CNeuronBaseOCL *NeuronOCL)
{
CNeuronBaseOCL* prev = NeuronOCL;
CNeuronBaseOCL* current = NULL;
//--- Probability
for(int i = 0; i < acProbability.Total(); i++)
{
current = acProbability[i];
if(!current ||
!current.FeedForward(prev))
ReturnFalse;
prev = current;
}
//--- Data Embedding
prev = NeuronOCL;
for(int i = 0; i < acDataEmb.Total(); i++)
{
current = acDataEmb[i];
if(!current ||
!current.FeedForward(prev))
ReturnFalse;
prev = current;
}
//--- Experts
if(bTrain)
if(!cExpertsEmb.FeedForward())
ReturnFalse;
//--- Graphs
uint units = (uint)MathSqrt((double)Neurons());
uint emb_dim = acDataEmb[-1].Neurons() / units;
uint experts = cExpertsEmb.Neurons() / acDataEmb[-1].Neurons();
if(!MatMul(cExpertsEmb.getOutput(), current.getOutput(), cGraphs.getOutput(),
units, emb_dim, units, experts, false))
ReturnFalse;
if(cGraphs.Activation() != None)
if(!Activation(cGraphs.getOutput(), cGraphs.getOutput(), cGraphs.Activation()))
ReturnFalse;
//--- Result
if(!MatMul(acProbability[-1].getOutput(), cGraphs.getOutput(), Output, 1, experts, units * units, 1, false))
ReturnFalse;
//---
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CNeuronGraphons::calcInputGradients(CNeuronBaseOCL *NeuronOCL)
{
if(!NeuronOCL)
ReturnFalse;
//---
if(!acDataEmb[-1] || !acProbability[-1])
ReturnFalse;
//---
uint units = (uint)MathSqrt((double)Neurons());
uint emb_dim = acDataEmb[-1].Neurons() / units;
uint experts = cExpertsEmb.Neurons() / acDataEmb[-1].Neurons();
//---
if(!MatMulGrad(acProbability[-1].getOutput(), acProbability[-1].getGradient(),
cGraphs.getOutput(), cGraphs.getGradient(), Gradient,
1, experts, units * units, 1, false))
ReturnFalse;
//--- Graphs
if(cGraphs.Activation() != None)
if(!DeActivation(cGraphs.getOutput(), cGraphs.getGradient(),
cGraphs.getGradient(), cGraphs.Activation()))
ReturnFalse;
if(!MatMulGrad(cExpertsEmb.getOutput(), cExpertsEmb.getGradient(),
acDataEmb[-1].getOutput(), acDataEmb[-1].getGradient(),
cGraphs.getGradient(), units, emb_dim, units, experts, false))
ReturnFalse;
//---
CNeuronBaseOCL* next = NULL;
CNeuronBaseOCL* current = NULL;
//--- Probability
for(int i = acProbability.Total() - 1; i >= 0; i--)
{
next = acProbability[i];
current = (i == 0 ? NeuronOCL : acProbability[i - 1]);
if(!current ||
!current.CalcHiddenGradients(next))
ReturnFalse;
}
//--- Data Embedding
CBufferFloat *temp = NeuronOCL.getGradient();
if(!NeuronOCL.SetGradient(NeuronOCL.getPrevOutput(), false))
ReturnFalse;
for(int i = acDataEmb.Total() - 1; i >= 0; i--)
{
next = acDataEmb[i];
current = (i == 0 ? NeuronOCL : acDataEmb[i - 1]);
if(!current ||
!current.CalcHiddenGradients(next))
ReturnFalse;
}
if(!SumAndNormalize(temp, NeuronOCL.getGradient(), temp, 1, false, 0, 0, 0, 1) ||
!NeuronOCL.SetGradient(temp, false))
ReturnFalse;
//---
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CNeuronGraphons::updateInputWeights(CNeuronBaseOCL *NeuronOCL)
{
CNeuronBaseOCL* prev = NeuronOCL;
CNeuronBaseOCL* current = NULL;
//--- Probability
for(int i = 0; i < acProbability.Total(); i++)
{
current = acProbability[i];
if(!current ||
!current.UpdateInputWeights(prev))
ReturnFalse;
prev = current;
}
//--- Data Embedding
prev = NeuronOCL;
for(int i = 0; i < acDataEmb.Total(); i++)
{
current = acDataEmb[i];
if(!current ||
!current.UpdateInputWeights(prev))
ReturnFalse;
prev = current;
}
//--- Experts
if(!cExpertsEmb.UpdateInputWeights())
ReturnFalse;
//---
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CNeuronGraphons::WeightsUpdate(CNeuronBaseOCL *source, float tau)
{
if(!CNeuronBaseOCL::WeightsUpdate(source, tau))
ReturnFalse;
//---
CNeuronGraphons *Source = source;
if(!acProbability.WeightsUpdate(Source.acProbability.AsObject(), tau))
ReturnFalse;
if(!acDataEmb.WeightsUpdate(Source.acDataEmb.AsObject(), tau))
ReturnFalse;
if(!cExpertsEmb.WeightsUpdate(Source.cExpertsEmb.AsObject(), tau))
ReturnFalse;
//---
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CNeuronGraphons::Save(const int file_handle)
{
if(!CNeuronBaseOCL::Save(file_handle))
ReturnFalse;
//---
if(!acProbability.Save(file_handle))
ReturnFalse;
if(!acDataEmb.Save(file_handle))
ReturnFalse;
if(!cExpertsEmb.Save(file_handle))
ReturnFalse;
//---
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CNeuronGraphons::Load(const int file_handle)
{
if(!CNeuronBaseOCL::Load(file_handle))
ReturnFalse;
//---
if(!acProbability.Load(file_handle))
ReturnFalse;
if(!acDataEmb.Load(file_handle))
ReturnFalse;
if(!LoadInsideLayer(file_handle, cExpertsEmb.AsObject()))
ReturnFalse;
//---
uint experts = cExpertsEmb.Neurons() / acDataEmb[-1].Neurons();
if(!cGraphs.Init(0, 0, OpenCL, Neurons()*experts, optimization, iBatch))
ReturnFalse;
cGraphs.SetActivationFunction(SIGMOID);
//---
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CNeuronGraphons::SetOpenCL(COpenCLMy *obj)
{
CNeuronBaseOCL::SetOpenCL(obj);
acProbability.SetOpenCL(OpenCL);
acDataEmb.SetOpenCL(OpenCL);
cExpertsEmb.SetOpenCL(OpenCL);
cGraphs.SetOpenCL(OpenCL);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CNeuronGraphons::TrainMode(bool flag)
{
CNeuronBaseOCL::TrainMode(flag);
acProbability.TrainMode(bTrain);
acDataEmb.TrainMode(bTrain);
cExpertsEmb.TrainMode(bTrain);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CNeuronSparseSoftMax::Init(uint numOutputs, uint myIndex, COpenCLMy *open_cl,
uint units, uint dimension_in, uint dimension_out,
ENUM_OPTIMIZATION optimization_type, uint batch)
{
if(dimension_in < dimension_out)
ReturnFalse;
if(!CNeuronSoftMaxOCL::Init(numOutputs, myIndex, open_cl, units * dimension_out, optimization_type, batch))
ReturnFalse;
//---
SetHeads(units);
iDimensionIn = dimension_in;
if(!cIndexes.BufferInit(Neurons(), -1) ||
!cIndexes.BufferCreate(OpenCL))
ReturnFalse;
//---
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CNeuronSparseSoftMax::feedForward(CNeuronBaseOCL *NeuronOCL)
{
if(!OpenCL || !NeuronOCL ||
NeuronOCL.Neurons() < int(iHeads * iDimensionIn))
ReturnFalse;
uint global_work_offset[2] = {0, 0};
uint global_work_size[2] = { iHeads, iDimensionIn };
uint local_work_size[2] = { 1, global_work_size[1] };
uint kernel = def_k_SparseSoftMax;
setBuffer(kernel, def_k_ssoftmax_data, NeuronOCL.getOutputIndex())
setBuffer(kernel, def_k_ssoftmax_outputs, getOutputIndex())
setBuffer(kernel, def_k_ssoftmax_indexes, cIndexes.GetIndex())
setArgument(kernel, def_k_ssoftmax_out_dimension, int(DimensionOut()))
kernelExecuteLoc(kernel, global_work_offset, global_work_size, local_work_size)
#ifdef _DEBUG
if(!Output.BufferRead())
ReturnFalse;
#endif
//---
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CNeuronSparseSoftMax::calcInputGradients(CNeuronBaseOCL *NeuronOCL)
{
if(!OpenCL || !NeuronOCL ||
NeuronOCL.Neurons() < int(iHeads * iDimensionIn))
ReturnFalse;
uint global_work_offset[2] = {0, 0};
uint global_work_size[2] = { iHeads, iDimensionIn };
uint local_work_size[2] = { 1, global_work_size[1] };
uint kernel = def_k_SparseSoftMaxGrad;
setBuffer(kernel, def_k_ssoftmax_gr_data_gr, NeuronOCL.getGradientIndex())
setBuffer(kernel, def_k_ssoftmax_gr_outputs, getOutputIndex())
setBuffer(kernel, def_k_ssoftmax_gr_outputs_gr, getGradientIndex())
setBuffer(kernel, def_k_ssoftmax_gr_indexes, cIndexes.GetIndex())
setArgument(kernel, def_k_ssoftmax_gr_out_dimension, int(DimensionOut()))
kernelExecuteLoc(kernel, global_work_offset, global_work_size, local_work_size)
#ifdef _DEBUG
if(!NeuronOCL.getGradient().BufferRead())
ReturnFalse;
#endif
//---
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CNeuronSparseSoftMax::Save(const int file_handle)
{
if(!CNeuronSoftMaxOCL::Save(file_handle))
ReturnFalse;
if(FileWriteInteger(file_handle, iDimensionIn) < INT_VALUE)
ReturnFalse;
//---
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CNeuronSparseSoftMax::Load(const int file_handle)
{
if(!CNeuronSoftMaxOCL::Load(file_handle))
ReturnFalse;
if(FileIsEnding(file_handle))
ReturnFalse;
iDimensionIn = (uint)FileReadInteger(file_handle);
//---
cIndexes.BufferFree();
if(!cIndexes.BufferInit(Neurons(), -1) ||
!cIndexes.BufferCreate(OpenCL))
ReturnFalse;
//---
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CNeuronSparseSoftMax::SetOpenCL(COpenCLMy *obj)
{
CNeuronSoftMaxOCL::SetOpenCL(obj);
cIndexes.BufferCreate(OpenCL);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CNeuronGlobLocGraphAtt::Init(uint numOutputs, uint myIndex, COpenCLMy *open_cl,
uint units, uint window, uint experts, float dropout,
uint emb_dimension, uint sparse_dimension,
ENUM_OPTIMIZATION optimization_type, uint batch)
{
if(!CNeuronMHAttentionPooling::Init(numOutputs, myIndex, open_cl, window, units,
2, optimization_type, batch))
ReturnFalse;
//---
int index = 0;
if(!cGlobal.Init(0, index, OpenCL, iUnits, iWindow, emb_dimension, experts, dropout,
optimization, iBatch))
ReturnFalse;
index++;
if(!cLocal.Init(0, index, OpenCL, iUnits, iWindow, experts, dropout, emb_dimension,
sparse_dimension, optimization, iBatch))
ReturnFalse;
index++;
if(!cConcat.Init(0, index, OpenCL, 2 * iWindow * iUnits, optimization, iBatch))
ReturnFalse;
cConcat.SetActivationFunction(None);
//---
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CNeuronGlobLocGraphAtt::feedForward(CNeuronBaseOCL *NeuronOCL)
{
if(!cGlobal.FeedForward(NeuronOCL))
ReturnFalse;
if(!cLocal.FeedForward(NeuronOCL))
ReturnFalse;
if(!Concat(cGlobal.getOutput(), cLocal.getOutput(), cConcat.getOutput(),
iWindow, iWindow, iUnits))
ReturnFalse;
//---
return CNeuronMHAttentionPooling::feedForward(cConcat.AsObject());
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CNeuronGlobLocGraphAtt::calcInputGradients(CNeuronBaseOCL *NeuronOCL)
{
if(!NeuronOCL)
ReturnFalse;
//---
if(!CNeuronMHAttentionPooling::calcInputGradients(cConcat.AsObject()))
ReturnFalse;
if(!DeConcat(cGlobal.getGradient(), cLocal.getGradient(), cConcat.getGradient(),
iWindow, iWindow, iUnits))
ReturnFalse;
if(!NeuronOCL.CalcHiddenGradients(cGlobal.AsObject()))
ReturnFalse;
CBufferFloat *temp = NeuronOCL.getGradient();
if(!NeuronOCL.SetGradient(PrevOutput, false))
ReturnFalse;
if(!NeuronOCL.CalcHiddenGradients(cLocal.AsObject()))
ReturnFalse;
if(!SumAndNormalize(temp, PrevOutput, temp, iWindow, false, 0, 0, 0, 1) ||
!NeuronOCL.SetGradient(temp, false))
ReturnFalse;
//---
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CNeuronGlobLocGraphAtt::updateInputWeights(CNeuronBaseOCL *NeuronOCL)
{
if(!cGlobal.UpdateInputWeights(NeuronOCL))
ReturnFalse;
if(!cLocal.UpdateInputWeights(NeuronOCL))
ReturnFalse;
//---
return CNeuronMHAttentionPooling::updateInputWeights(cConcat.AsObject());
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CNeuronGlobLocGraphAtt::WeightsUpdate(CNeuronBaseOCL *source, float tau)
{
if(!CNeuronMHAttentionPooling::WeightsUpdate(source, tau))
ReturnFalse;
//---
CNeuronGlobLocGraphAtt* Source = source;
if(!cGlobal.WeightsUpdate(Source.cGlobal.AsObject(), tau))
ReturnFalse;
if(!cLocal.WeightsUpdate(Source.cLocal.AsObject(), tau))
ReturnFalse;
//---
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CNeuronGlobLocGraphAtt::Save(const int file_handle)
{
if(!CNeuronMHAttentionPooling::Save(file_handle))
ReturnFalse;
//---
if(!cGlobal.Save(file_handle))
ReturnFalse;
if(!cLocal.Save(file_handle))
ReturnFalse;
//---
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CNeuronGlobLocGraphAtt::Load(const int file_handle)
{
if(!CNeuronMHAttentionPooling::Load(file_handle))
ReturnFalse;
//---
if(!LoadInsideLayer(file_handle, cGlobal.AsObject()))
ReturnFalse;
if(!LoadInsideLayer(file_handle, cLocal.AsObject()))
ReturnFalse;
//---
if(!cConcat.Init(0, 2, OpenCL, 2 * iWindow * iUnits, optimization, iBatch))
ReturnFalse;
cConcat.SetActivationFunction(None);
//---
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CNeuronGlobLocGraphAtt::SetOpenCL(COpenCLMy *obj)
{
CNeuronMHAttentionPooling::SetOpenCL(obj);
//---
cGlobal.SetOpenCL(OpenCL);
cLocal.SetOpenCL(OpenCL);
cConcat.SetOpenCL(OpenCL);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CNeuronGlobLocGraphAtt::TrainMode(bool flag)
{
CNeuronMHAttentionPooling::TrainMode(flag);
//---
cGlobal.TrainMode(flag);
cLocal.TrainMode(flag);
cConcat.TrainMode(flag);
}