期货量化软件神经网络变得轻松(第二十二部分):递归模型的无监督学习

文章探讨了如何利用LSTM递归神经网络构建自动编码器,以处理时间序列数据,特别是金融市场数据。通过这种方式,模型能够记忆历史信息,提高预测准确性。文章详细介绍了LSTM模块的架构和实现,包括前馈传递、反向传播和权重更新的内核设计。此外,还讨论了模型的训练策略,强调了在处理历史数据时保留记忆的重要性。
摘要由CSDN通过智能技术生成

概述

在我们赫兹量化软件系列文章的最后两篇里专门讨论了自动编码器。 它们的体系架构令反向传播算法基于未标记的数据上训练各种神经网络模型成为可能。 该模型学习在选择主要特征时压缩初始数据。 我们的实验已确认了自动编码器模型的有效性。 请注意,我们采用的是完全连接的神经层来训练自动编码器。 此类模型有固定的输入数据窗口。 我们构建完成的算法可以训练采用固定输入数据窗口运行的任何模型。 但是递归模型的体系结构是不同的。 为了决定神经元的激活,除了初始数据外,这些模型还要用到它们以前的状态。 构建自动编码器时应考虑此特性。

1. 递归模型的训练特点

我们赫兹量化软件从回顾递归模型的组织及其目的开始。 看看价格图表。 它显示相对于价格走势的历史数据。 每根柱线都是针对特定时间间隔内品种价格波动的范围边界的描述。 请注意,这是“历史数据”。 这意味着它们不会再改变。 随着时间的推移会出现新柱线,但旧柱线不会再变化。 在每个特定的时间点,我们都有不变的历史数据,和最后一根蜡烛,它还没有完全成形,随时能够变化,直到它的时间间隔关闭。

通过分析历史数据,我们尝试预测未来最有可能的价格走势。 历史数据的分析深度在每种情况下都有所区别。 这大概是与神经网络所用的固定初始数据量相关的主要问题之一。 较小的历史数据窗口限制了分析的可能性。 过度的窗口会令模型及其学习复杂化。 因此,在选择输入数据窗口的大小时,此类模型的架构师必须妥协并遵循“中庸之道”。

另一方面,我们正在应对历史数据。 无论我们如何选择窗口大小,在每次模型迭代中,我们都会将 99% 以上的信息重新传输到它。 之后,模型也将重新处理此数据。 这看起来不像是对资源的有效利用。 但遗憾的是,完全连接和卷积模型都不记得以前处理过的任何信息。

上述问题可以经由递归网络来解决。 思路如下。 每个神经元的状态取决于源数据的处理结果。 因此,我们可以假设神经元的状态是源数据的压缩形式。 故此,我们可以将源数据与先前的状态一起馈送到神经元当中。 如此这般,神经元的新状态将取决于我们正在分析的系统当前状态和先前状态,而信息是有关在神经元的先前状态中哪些被压缩。

此方法令模型能够记忆系统的若干个状态。 以权重系数绝对值小于 1 的激活函数,逐渐降低最早历史数据的影响。 结果就是,我们得到的模型具有相当的可预测记忆界线。

运用这种带有记忆的模型,我们制定决策时,不必再受限于所取用的历史数据窗口。 此外,我们减少了重新传输的信息量,因为模型已经记住它了。 出于这些优点,递归模型可被视为解决时间序列处理问题的高优先级领域之一。

然而,需要特殊方式来运用这些功能进行递归模型训练。 例如,回到自编码器的架构,如果我们把上图中模型的输入 Xi 和输出 Yi 等同起来,那么为了从潜伏状态恢复原始数据,就没有必要记住之前的状态了。 因此,该模型将排除训练过程中历史数据的影响。 它只会评估当前状态。 如果递归模型失去了记忆能力,它就失去了其主要优势。

既如此,在开发模型架构时,我们必须要考虑到这一事实。 学习过程应进行规划,这样模型就会强制访问以前迭代的数据。

在自动编码器构造中,解码器架构在大多数情况下几乎是编码器架构的镜像。 当运作递归模型时保留了相同的措施。 奇怪的是,最早期的这种架构之一曾被用于监督学习。 题为 “利用 RNN 编码器/解码器学习短语表达 — 用于统计机器翻译” 的论文作者提出了RNN 编码器-解码器模型,来进行统计机器翻译。 该模型的编码器和解码器就是递归网络。 编码器将源语言的短语压缩为某个潜伏状态。 然后解码器将其“解包”还原为目标语言的短语。 它与自动编码器非常相似,是不是?

使用递归模型可以一次一个单词地将短语传输到编码器,这令基于不同长度的短语来训练模型成为可能。 在收到完整的短语后,编码器再把潜伏状态传输到解码器。 解码器再一次一个单词地给出目标语言的短语翻译。

基于英语和法语的标记短语进行训练之后,作者获得了一个能够返回语义和语法上有意义的短语的模型。

递归模型的无监督学习在发表于 2015 年 2 月的文章 “使用 LSTMs 的视频表现无监督学习” 中已有了很好的阐述。 文章作者基于各种视频素材进行了一系列实验,训练递归自动编码器。 执行的实验包含两个方面:数据输入到编码器后再恢复,以及视频序列可能延续的预测。

该文章介绍了自动编码器的各种架构。 但它们都利用的是 LSTM 模块进行信号编码和解码。 投注结果是采用 1 个编码器和 2 个解码器训练模型时获得的。 一个解码器负责恢复原始数据,第二个解码器预测视频序列最有可能的延续。

在编码器中利用循环模块,能够将原始视频逐帧传输到模型之中。 取决于任务的不同,递归解码器模块返回逐帧重建或预测的视频序列。

此外,该文作者表明,在与视频运动识别相关的任务中,采用无监督算法预训练的递归模型,再采用监督算法进行额外训练后,即使基于相对少量的标记数据,也能提供相当优异的结果。

这两篇文章中提供的资料表明,这种方式可以成功地解决我们的问题。

然而,我在实现中所做的将与建议的模型略有偏差。 它们都要用到解码器中的循环模块,并返回逐帧解码数据。 这完全符合翻译和视频分析任务。 这也许会在预测下一根柱线时给出不错的结果。 但我还没有做过任何这方面的实验。 在一般情况下,在分析市场形势时,我们评估它,并作为涵盖相当长时间间隔的完整图片。 因此,我们将逐步小幅度地把市场形势的变化转移到模型之中。 然后,模型应参考当前和以前得到的数据评估形势。 这意味着潜伏状态应包含有关尽可能宽的时间间隔的信息。

为了达到这种效果,我们在编码器中仅用递归模块。 在解码器中,我们还将采用完全连接神经层,且在若干次迭代中还原传输到编码器的数据。

2. 实现

接下来,我们进入本文的实践部分。 我们将基于前面讨论的 LSTM 模块构建递归编码器,其结构如下图所示。 该模块由 4 个完全连接神经层组成。 其中三个执行门的功能规范信息流。 第四个转换源数据。

LSTM 模块使用 2 个递归信息流:记忆和隐藏状态。

我们之前曾用 MQL5 重新创建了 LSTM 模块算法。 现在我们将用 OpenCL 技术重复它。 为了实现该算法,我们来创建一个新的 CNeuronLSTMOCL 类。 主要缓冲区和方法集继承自基类 CNeuronBaseOCL,我们将其当作父类。

方法和类变量的结构如下所示。 类方法非常容易识别:这些是我们在每个新类中覆盖的前馈和后馈方法。 变量的目的需要略加解释。

class CNeuronLSTMOCL : public CNeuronBaseOCL
  {
protected:
   CBufferFloat      m_cWeightsLSTM;
   CBufferFloat      m_cFirstMomentumLSTM;
   CBufferFloat      m_cSecondMomentumLSTM;

   int               m_iMemory;
   int               m_iHiddenState;
   int               m_iConcatenated;
   int               m_iConcatenatedGradient;
   int               m_iInputs;
   int               m_iWeightsGradient;
//---
   virtual bool      feedForward(CNeuronBaseOCL *NeuronOCL) override;
   virtual bool      updateInputWeights(CNeuronBaseOCL *NeuronOCL) override;

public:
                     CNeuronLSTMOCL(void);
                    ~CNeuronLSTMOCL(void);
//---
   virtual bool      Init(uint numOutputs, uint myIndex, COpenCLMy *open_cl,
                          uint numNeurons, ENUM_OPTIMIZATION optimization_type,
                          uint batch) override;
//---
   virtual bool      calcInputGradients(CNeuronBaseOCL *NeuronOCL);
//---
   virtual bool      Save(int const file_handle) override;
   virtual bool      Load(int const file_handle) override;
//---
   virtual int       Type(void) override const   {  return defNeuronLSTMOCL; }
  };

首先,我们在这里看到 3 个数据缓冲区:

  • m_cWeightsLSTM — LSTM 模块的权重系数矩阵
  • m_cFirstMomentumLSTM — 更新权重的第一个动量的矩阵
  • m_cSecondMomentumLSTM — 更新权重的第二个动量的矩阵

以下几点需要注意。 如上所述,LSTM 模块包含 4 个完全连接神经层。 与此同时,我们只为权重矩阵 m_cWeightsLSTM 声明了一个缓冲区。 此缓冲区将包含所有 4 个神经层的权重。 使用级联缓冲区将允许我们同时并行化所有 4 个神经层。 稍后在研究每种方法的实现时,我们会更详细地研究并行规划机制。

这同样适用于动量缓冲区 m_cFirstMomentumLSTM 和 m_cSecondMomentumLSTM

在最新的终端版本中,MetaQuotes Ltd 实现了一定数量的改进。 它们还影响到我们所用的 OpenCL 技术。 特别是,他们增加了 OpenCL 对象的最大可能数量,并增加了无需双精度支持情况下在显卡上使用该技术的可能性。 这将降低训练模型所需的总时间,因为现在不需要在调用每个内核之前从 CPU 内存加载数据,或在执行后将其往回卸载。 在开始训练过程之前,将所有初始数据一次性加载到 OpenCL 关联内存当中,并在训练结束后复制结果就足够了。

甚至,它允许我们仅在 OpenCL 关联中声明一些缓冲区,而无需在设备的主内存中创建镜像缓冲区。 这是指用于存储临时信息的

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

赫兹量化软件

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值