MQL5算法交易的神经网络-003创建全连接层

MQL5算法交易的神经网络-003创建全连接层
Photo by Alina Grubnyak / Unsplash

创建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 &params);

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:加载数据。

Read more

MQL5算法交易的神经网络-007长短期记忆网络

MQL5算法交易的神经网络-007长短期记忆网络

定义属性 构建LSTM的四个门控单元:m_cForgetGate、m_cInputGate、m_cNewContent、m_cOutputGate,分别负责遗忘门、输入门、新内容和输出门的计算。 m_cMemorys和m_cHiddenStates,存储LSTM单元的记忆状态和隐藏状态。 m_cInputs,输入数据的缓冲区。 m_cForgetGateOuts、m_cInputGateOuts、m_cNewContentOuts、m_cOutputGateOuts,保存各个门控单元的输出结果。 m_cInputGradient,存储输入梯度,用于反向传播。 m_iDepth,网络的深度,表示层数。 初始化 创建CLayerDescription 指针temp 利用temp初始化 ForgetGate 利用temp初始化 InputGate 利用temp初始化 OutputGate 利用temp初始化 NewContent 初始化 InputGradient

By dumengru
20241122 所有盈利都是市场的馈赠

20241122 所有盈利都是市场的馈赠

说来也奇怪,我不断做空BTC和XAU,二者又不断创出新高,然而我的账户资金却不减反增。 经过总结,我认为盈利的原因有以下几个: 1. 能够感受到市场的最小阻力线方向。我能够明显感受到价格的最小阻力线方向是向上的,这样促使我在做空时非常谨慎,也能够很好的踩住回调的节奏。 2. 能够感受到压力和支撑位。趋势的特征之一就是压力和支撑位都比较明显,有了明显的点位,进出场时也能够得心应手。 3. 交易方向明确。这可能是最重要的一点,因为方向明确,所以我有更多的时间和精力去观察市场最小阻力线方向。 4. 仓位控制的较稳。这是慢慢培养的一种交易习惯。 5. 市场给机会。交易员的所有盈利都是市场的馈赠。

By dumengru
20241121 如果犯错不可避免

20241121 如果犯错不可避免

一个有趣的现象,交易员有时会在明知是错的情况下去犯错。 原因很简单,当你数次陷入假突破陷阱之后,你还会相信真的突破来临嘛?如果恰好你通过抄底摸顶获得了大幅盈利,当真的突破来临时,你就会不假思索地再次抄底摸顶,从而使自己身处险境。 有人会说,如果不确定是否真突破,那我不去做不就可以了么?你或许可以抵挡住一次两次诱惑,但是当你多次“准确”预测行情,而又没有参与的时候,你就会后悔,懊恼,甚至是痛恨自己“胆小如鼠”。 这就是交易中的诱惑与陷阱,也就是人们常说的贪婪与恐惧。 成功的主观交易员与其说是战胜了市场,不如说是战胜了自己。人性的弱点无法克服,如果犯错不可避免,那该怎么办呢? BTC交易 今天BTC终于突破了,在持续横盘震荡了数个交易日之后,在价格跌跌宕宕突破93000和94000之后,今天一举突破95000点并直接突破到97000点。 今天的交易就是非常典型的明知故犯错。 之前提到过BTC一直横盘,经常出现价格突破后立刻回调,也就是非常典型的假突破。我注意到BTC价格的低点和高点一次比一次高,因此理性观点是偏向多头的。但是自特朗普当选以来,BTC价格在不到15个交易日内

By dumengru
20241120 价格波动会影响交易者情绪

20241120 价格波动会影响交易者情绪

挣钱并不会让交易者感到更舒心,因为不管是盈利还是亏损,他都会犯错,而只要犯错,就不会感到舒心。——《股票作手回忆录》 我发现自己每隔一段时间就会出现一段低潮期,低潮期的感觉就是:内心十分抗拒交易,又忍不住查看行情,一旦看到行情波动又忍不住交易。 主要原因我认为是自己看不清楚市场方向。XAU从底部已经大幅反弹超过80美金,BTC不断冲击新高,USTEC也从底部有所反弹。没有明确的大方向导致在交易时总是惴惴不安。 与此同时,我的账户资金却大幅增长,为什么呢? 在账户本金只有500美元的情况下,我给自己定的目标是每天盈利20美元。由于我看不清楚大方向,因此当我达到这个目标之后总跟自己强调不要继续交易。尽管我内心十分抗拒,但是行情总是会走出一些极端价格,一些让我无法抗拒入场的价格。 由于黄金短期大幅反弹,所以我比较看空。 BTC低点不断抬升,不断创出新高后回落。我看多但从来不做多,并且总是在前高附近做空。 USTEC的趋势性比较强,V型反转也很多。 所以最近几笔交易比较有意思:当我看到XAU和BTC同时出现在前高附近时,我就会同时做空二者;当我看到XAU在前高附近而USTEC大

By dumengru