MQL5算法交易的神经网络-003创建全连接层
创建opencl_program.cl文件保存OpenCL常用操作,创建CMyOpenCL对象处理OpenCL函数。创建SetOpenCL方法设置CMyOpenCL指针。
创建CActivation类处理激活函数。
创建CBufferType类作为动态数据缓冲区的管理接口,支持与OpenCL的交互,并提供各类矩阵操作功能。所有数组都采用CBufferType类型。
创建SetActivation方法设置激活函数。
创建SGDUpdate和AdamUpdate等方法更新权重。
创建FeedForward方法实现前向传播,创建GetOutputs 获取上一层神经元的输出状态。
创建CalcOutputGradient方法计算神经网络的误差梯度。创建GetGradients方法访问上一层的误差梯度。
创建CalcDeltaWeights 方法计算需要迭代的权重变化。
创建UpdateWeights更新权重。
创建Save、Load 和 Type方法保存加载和标识模型。
定义属性
m_cOpenCL:指向用于 OpenCL 技术的类实例的指针
m_cActivation:指向激活函数对象的指针,默认是Swish激活函数
m_eOptimization:训练期间神经元优化方法的类型,默认是Adam
m_cOutputs:神经元输出端的值数组
m_cWeights:权重数组
m_cDeltaWeights:用于累积未完成权重更新的数组(自上次更新以来每个权重的累积误差梯度)
m_cGradients:由于反向传递的最后一次迭代,神经层输出端的误差梯度
m_cMomenum:与其他变量不同,这将是一个包含两个元素的数组,用于记录指向累积矩数组的指针
最终我们创建的全连接层类如下
class CNeuronBase : public CObject
{
protected:
bool m_bTrain;
CMyOpenCL* m_cOpenCL;
CActivation* m_cActivation;
ENUM_OPTIMIZATION m_eOptimization;
CBufferType* m_cOutputs;
CBufferType* m_cWeights;
CBufferType* m_cDeltaWeights;
CBufferType* m_cGradients;
CBufferType* m_cMomenum[2];
//---
virtual bool SGDUpdate(int batch_size, TYPE learningRate,
VECTOR &Lambda);
virtual bool MomentumUpdate(int batch_size, TYPE learningRate,
VECTOR &Beta, VECTOR &Lambda);
virtual bool AdaGradUpdate(int batch_size, TYPE learningRate,
VECTOR &Lambda);
virtual bool RMSPropUpdate(int batch_size, TYPE learningRate,
VECTOR &Beta, VECTOR &Lambda);
virtual bool AdaDeltaUpdate(int batch_size,
VECTOR &Beta, VECTOR &Lambda);
virtual bool AdamUpdate(int batch_size, TYPE learningRate,
VECTOR &Beta, VECTOR &Lambda);
virtual bool SetActivation(ENUM_ACTIVATION_FUNCTION function, VECTOR ¶ms);
public:
CNeuronBase(void);
~CNeuronBase(void);
//---
virtual bool Init(const CLayerDescription *description);
virtual bool SetOpenCL(CMyOpenCL *opencl);
virtual bool FeedForward(CNeuronBase *prevLayer);
virtual bool CalcOutputGradient(CBufferType *target, ENUM_LOSS_FUNCTION loss);
virtual bool CalcHiddenGradient(CNeuronBase *prevLayer);
virtual bool CalcDeltaWeights(CNeuronBase *prevLayer, bool read);
virtual bool UpdateWeights(int batch_size, TYPE learningRate, VECTOR &Beta, VECTOR &Lambda);
//---
virtual void TrainMode(bool flag) { m_bTrain = flag; }
virtual bool TrainMode(void) const { return m_bTrain; }
//---
virtual CBufferType *GetOutputs(void) const { return(m_cOutputs); }
virtual CBufferType *GetGradients(void) const { return(m_cGradients); }
virtual CBufferType *GetWeights(void) const { return(m_cWeights); }
virtual CBufferType *GetDeltaWeights(void) const { return(m_cDeltaWeights);}
virtual bool SetOutputs(CBufferType* buffer, bool delete_prevoius = true);
//--- methods for working with files
virtual bool Save(const int file_handle);
virtual bool Load(const int file_handle);
//--- method of identifying the object
virtual int Type(void) const { return(defNeuronBase); }
virtual ulong Rows(void) const { return(m_cOutputs.Rows()); }
virtual ulong Cols(void) const { return(m_cOutputs.Cols()); }
virtual ulong Total(void) const { return(m_cOutputs.Total()); }
};
方法解析
CNeuronBase:默认使用Adam优化器和Swish激活函数。
SetOpenCL:设置opencl对象,同时为激活函数设置m_cOpenCL。
Init:初始化,传入一个神经层描述的指针。
- 初始化输出结果缓冲区m_cOutputs(每个神经元一个结果,desc.count)
- 初始化误差梯度缓冲区m_cGradients(每个神经元一个误差梯度,desc.count)
- 如果是输入层(desc.window <= 0),则删除多余对象。
- 初始化激活函数SetActivation。
- 初始化权重矩阵m_cWeights(每个神经元一行权重,desc.count, desc.window + 1)。
- 初始化权重梯度累积m_cDeltaWeights(和权重数量对应)。
- 初始化优化器m_cMomenum(和权重数量对应)
FeedForward:前向传播,传入上一层神经元的指针。
- 获取上一层神经元的输出结果,GetOutputs。
- 使用CPU或OpenCL计算输出结果。
CalcOutputGradient:计算输出层的梯度。
CalcHiddenGradient:计算隐藏层的梯度。
CalcDeltaWeights:计算权重的增量。
UpdateWeights:更新权重。
Save:保存数据。
Load:加载数据。