量化软件——赫兹MT5神经网络变动简单60在线决策转换器(ODT)

最近两篇文章专门介绍了决策转换器方法,其在期望奖励的自回归模型境况下针对动作序列进行建模。您也许还记得,根据这两篇文章的实际测试成果,测试期开始时,看到所训练模型的盈利能力有了相当不错的提升。随着深入,模型的性能下降,并观察到许多无盈利业务,从而导致亏损。得到的亏损金额可能超过以前赚到的利润。

模型的定期额外训练可能会有所帮助。不过,这种方式令模型的操作变得异常复杂。故此,研究如何选择在线模型训练是相当合理的。在此,我们面临着许多必须解决的问题。

《在线决策变换器》一文(2022 年 2 月)中阐述了实施决策转换器在线训练的选项之一。值得注意的是,所提议方法使用了经典 DT 的初级离线训练。在线训练应用在模型的后续优调。作者文章中阐述的实验结果表明,依据 D4RL 测试样本,ODT 的绝对性能能够与领先者竞争。此外,在优调过程中,它显示出更显著的提升。

1. ODT 算法
研究在线决策转换器算法之前,我建议简要回顾一下经典的决策转换器。DT 将 τ 轨迹作为若干个输入令牌序列处理:在途回报(RTG)、状态和动作。特别是,初始 RTG 值等于整个轨迹的回报。在 t 临时步骤中,DT 使用 K 上次步骤的令牌来生成 At 的动作。在本例中,K 是一个超参数,指定转换器的上下文长度。在操作期间,上下文长度也许比训练期要短。

DT 学习 π(At|St, RTGt) 判定政策,其中 St 是从 t-K+1 至 t 的最后状态 K 序列。类似地,RTGt 将最后一个在途回报 K 拟人化。这是一个 K 阶的自动回归模型。智能体政策经训练后,可使用标准 MSE(均方误差)损失函数来预测动作。

在操作过程中,我们示意 RTG 初始化,并初始状态 S0 的所需性能。然后 DT 生成 A0 动作。生成 At 动作后,我们执行它,并观察下一个状态 St+1 接收奖励 rt。这会产生 RTGt+1。

如前,DT 基于包括 A0、S0、S1 和 RTG0、RTG1 在内的轨迹生成 A1 动作。重复该过程,直到该世代完成。

由于训练集数据有限,仅依据离线数据集上训练的政策通常是次优的。离线轨迹的回报率也许较低,并且仅覆盖状态和动作空间的有限部分。提高性能的一个自然策略是进一步训练 RL 智能体与环境的在线交互。但是,标准的决策转换器方法不足以进行在线训练。

在线决策转换器算法对决策转换器进行了关键修改,从而确保高效的在线训练。第一步是泛化概率训练目标。在这种境况下,目标是训练一个随机政策,取最大化重复轨迹的概率。

在线 RL 算法的主要属性是它能够平衡探索和开发。即使采用随机政策,传统的 DT 公式也并未考虑探索。为了解决这个问题,ODT 方法的作者定义通过政策的熵来研究,这取决于轨迹中数据的分布。在离线预训练期间这种分布是静态的,但在在线设置期间则是动态的,因为它依赖于环境交互期间获得的新数据。

与许多现有的最大熵 RL 算法类似,例如软性扮演者-评论者,ODT 方法的作者明确定义了政策熵的下限,来鼓励探索。

ODT 损失函数与 SAC 和其它经典 RL 方法的区别在于,在 ODT 中,损失函数是负对数似然,而非贴现回报。基本上,我们仅专注使用动作序列形态的训练,替代明确地最大化回报。在离线和在线训练中,主观函数都会自动适配相应的扮演者政策。在离线训练期间,交叉熵控制分布的发散程度,而于在线训练期间,交叉熵驱动探索政策。

与经典最大熵 RL 方法的另一个重要区别是,在 ODT 中,政策熵是在序列级别定义的,而不是在过渡级别。虽然 SAC 在所有时间步骤上都对政策熵施加了 β 下限,但 ODT 限制了在 K 个连续时间步长骤求熵的均值。因此,约束条件仅要求在 K 个时间步骤序列上的熵均值高于指定的 β 值。因此,任何满足过渡级别约束的政策也满足序列级别约束。因此,当 K > 1 时,可行的政策空间更大。当 K = 1 时,序列级别约束简化为类似于 SAC 的过渡级别约束。

在模型训练期间,回放缓冲区记录以前的经验,并定期更新。对于大多数现有的 RL 算法,经验渲染缓冲区由转换组成。在一个世代内的每个在线交互阶段之后,智能体的政策和 Q-函数将据梯度下降进行更新。然后,执行该政策来收集新的过渡,并将其添加到经验回放缓冲区。在 ODT 的情况下,经验回放缓冲区由轨迹组成,而非过渡。经过初步的离线训练后,我们从离线数据集中取得具有最大结果的轨迹初始化经验回放缓冲区。每次我们与环境交互时,我们都会依据当前政策完整执行世代。然后,我们取按照 FIFO 顺序收集的轨迹更新经验回放缓冲区。接下来,我们更新智能体政策,并执行新世代。利用平均行动评估政策,通常会导致较高的奖励,但这在使用随机行动进行在线研究时很实用,因为它会产生更加多样化的轨迹和行为形态。

此外,ODT 算法需要一个初始 RTG 形式的超参数,以便收集额外的在线数据。多种作用验明,从经验上讲,离线 DT 的实际评估回报与初始 RTG 具有很强的相关性,并且推断出的 RTG 值经常超出离线数据集中观察到的最大回报。ODT 的作者发现,最好取现有智能系统的结果按一个小的固定比例来设置这个超参数。该方法的作者在他们的工作中采用的是 2 倍缩放。原始论文提供的实验结果具有更大数值,以及在训练过程中发生变化的结果(例如,离线和在线数据集中最佳评估回报的分位数)。但在实践中,它们不如固定比例的 RTG 有效。

与 DT 一样,ODT 算法使用两步采样程序,确保对回放缓冲区中 K 长度的子轨迹采样时保持一致性。首先,我们按与其长度成正比的概率对一条轨迹进行采样。然后以相等的概率选择 K 长度的子轨迹。

我们将在本文的下一节中再把握该方法的实际实现。


2. 利用 MQL5 实现
在熟悉了该方法的理论层面之后,我们转入其实际实现。本节将讲述我们自己对拟议方式的实现看法,并从前几篇文章的开发作为补充。在实施中,ODT 算法包括两阶段模型训练:

初步离线训练。
与环境在线交互期间对模型进行优调。
出于本文的目的,我们将取用上一篇文章中的预训练模型。故因早前已运作过训练,我们跳过第一阶段的离线训练,立即转入模型训练的第二部分。


利用 RTG 模型生成与原版 ODT 算法有背离,其提议这牛初始 RTG 使用智能系统评估比例,随后根据获得的实际结果调整目标。

此外,因使用先前已训练模型,故不允许我们更改模型的架构。但我们来看看所用模型的架构如何与 ODT 算法相对应。

该方法的作者提议使用随机扮演者政策。这是我们在之前文章中所用的模型。

ODT 提议使用轨迹经验回放缓冲区,替代单独轨迹。这正是我们操控的缓冲区。

在训练模型时,我们没有使用损失函数的熵分量来鼓励环境探索。在该阶段,我们不会添加它,并承受可能的风险。我们期望随机扮演者政策和 RTG 生成模型在与环境的在线交互过程中提供充分的探索。

从我的实现中排除的另一点,涉及经验回放缓冲区。在离线训练之后,该方法的作者提议选择一些最有盈利性的轨迹,这些轨迹将于在线训练的第一阶段用到。我们最初限制了经验回放缓冲区中的轨迹数量。在转向在线训练时,我们将使用整个现有的经验复现缓冲区,我们将在与环境交互的过程中添加新的轨迹。同时,在添加新轨迹时,我们不会立即删除最旧的轨迹。在完成验算后将数据保存到文件时,我们将使用先前创建的方法限制缓冲区大小。

因此,考虑到可能的风险,我们可以很容易地使用上一篇文章中训练的模型。然后,我们将尝试通过使用 ODT 方式优调模型在线训练过程,从而提高它们的效率。

在此,我们有必要解决一些建设性问题。交易过程本质上是有条件的,且无止境。我说“有条件的”,因为出于多种原因,它仍然是有限的。但在可预见的未来发生这种事件的概率性非常小,以至于我们认为它是无限的。由此,我们并未遵照该方法作者的建议,在世代结束后运作附加训练过程,而是按一定的频率。

在此,我想提醒您,在我们的 DT 实现中,只把最后一根柱线的数据提供到模型输入端。整个历史数据上下文存储在嵌入图层的结果缓冲区当中。这种方式令我们能够减少再次处理冗余数据的资源消耗。但这成为在线训练道路上的“绊脚石”之一。事实是,嵌入缓冲区中的数据是按严格的历史顺序存储的。模型的定期附加训练过程,会导致来自其它轨迹或相同轨迹,但来自不同历史段的历史数据重新填充缓冲区。模型进行附加训练后,继续与环境交互时,这会令数据失真。

为了解决此问题,实际上有若干种选项。在运行过程中,它们具有各自不同的实现复杂性和资源消耗。初看,最简单的事情是创建一个缓冲区的副本,并在继续与环境交互之前,将缓冲区返回到开始训练之前的状态。然而,在仔细查验该过程后,我们明白,在主模型一侧,仅用模型的顶级类运作,无需访问神经层的独立缓冲区。在这种境况下,从模型的一个缓冲区把数据复制回模型的简单过程,会导致许多设计变化。这令该方法的实现变得非常复杂。

在完成额外的训练之后,我们可以将整组历史数据重复传输到模型之中,无需对模型进行构造性的更改。但这会导致大量重复的模型前向验算操作。此种操作的数量随着上下文大小的增加而增长。这令该方法效率低下。数据再处理所消耗的时间和计算资源,可能会超过将嵌入历史记录存储在神经层缓冲区中所节省的成本。

该问题的另一种解决方案是使用重复模型。一个是与环境互动所必需的。其二是为了附加训练。这种方式在内存资源方面更加昂贵,但彻底解决了嵌入层缓冲区中的数据问题。但模型之间的数据交换问题又浮现了。毕竟,经过附加训练后,与环境交互的模型应使用更新的智能体政策。RTG 生成模型也是如此。在此,我们可以回忆起软性扮演者-评论者方法,及其对目标模型的软更新。也许看似很奇怪,但这种机制允许我们在模型之间传输更新的权重比率,而无需更改剩余的缓冲区,包括嵌入层结果的缓冲区。

若要使用这种方式,我们必须在嵌入层中添加一个权重交换方法,该方法以前在 SAC 实现中未曾用过。

在此我们应该说,在添加方法时,我们仅直接对 CNeuronEmbeddingOCL 类进行添加,因为其运行所需的所有 API 早前已由我们制定,并以 CNeuronBaseOCL 神经层基类的虚拟方法的形式实现。还应该注意的是,如果不进行指定的修改,我们的模型操作不会产生错误。毕竟,默认情况下将调用父类的方法。但在这种情况下,如此操作是不完整,也不正确。

为了维护一致性,及正确覆盖虚拟方法,我们声明了一个方法,来保存参数。在该方法主体中,我们立即调用父类的类似方法。

bool CNeuronEmbeddingOCL::WeightsUpdate(CNeuronBaseOCL *source, float tau)
  {
   if(!CNeuronBaseOCL::WeightsUpdate(source, tau))
      return false;
正如我们不止一次说过的那样,这种调用父类的方式允许我们在一个动作中实现所有必要的控制,没必要重复,并对继承对象执行必要的操作。

在父类方法的操作成功结束后,我们转入在嵌入类中直接声明对象的工作。但为了获得供体类的相似对象访问权,我们应该覆盖结果对象的类型。
 

  • 24
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值