神经网络变得简单(第 97 部分):搭配 MSFformer 训练模型·综合运用
📘

神经网络变得简单(第 97 部分):搭配 MSFformer 训练模型·综合运用

第 3/3 篇

「训练循环里的误差缩放与超时打印」

这段逻辑处在强化学习训练主循环尾部,核心是对 Critic 输出做不对称缩放:非负值乘 1.01,负值乘 0.99,相当于给正反馈轻微放大、负反馈轻微衰减,倾向让网络对盈利状态更敏感。 Actor 与 Critic 的反向传播任一步失败就打印函数名与行号、置 Stop 并 break,避免在 MT5 上无声卡死。这种 __FUNCTION__ 配合 __LINE__ 的报错方式,开终端看 Experts 日志能直接定位到行。 每累计tick超过 500 毫秒,用 Comment 在图表刷一次进度:iter 占总 Iterations 的百分比,以及 Actor/Critic 的近期平均误差,精度到 8 位小数。若你跑黄金 5 分钟图训练,把 500 调小到 200 可能更跟手,但会多吃 CPU。 循环结束清 Comment,PrintFormat 打出最终 Actor 与 Critic 误差后调 ExpertRemove 自卸,防止 EA 反复 OnInit。外汇与贵金属波动剧烈,这类自训练 EA 实盘前务必在策略测试器跑够样本,误差收敛只是概率信号,不等于未来收益。

MQL5 / C++
PrintFormat("%s -> %d", __FUNCTION__, __LINE__);
   Stop = true;
   class="kw">break;
   }
   if(Buffer[tr].States[class="num">0].rewards[class="num">0] > class="num">0)
      if(!Actor.backProp(GetPointer(bActions), GetPointer(Encoder), LatentLayer))
         {
         PrintFormat("%s -> %d", __FUNCTION__, __LINE__);
         Stop = true;
         class="kw">break;
         }
   Critic.getResults(Result);
   for(class="type">int c = class="num">0; c < Result.Total(); c++)
      {
      class="type">float value = Result.At(c);
      if(value >= class="num">0)
         Result.Update(c, value * class="num">1.01f);
      else
         Result.Update(c, value * class="num">0.99f);
      }
   if(!Critic.backProp(Result, (CNet *)GetPointer(Encoder), LatentLayer) ||
      !Actor.backPropGradient((CNet *)GetPointer(Encoder), LatentLayer, -class="num">1, true))
      {
      PrintFormat("%s -> %d", __FUNCTION__, __LINE__);
      Stop = true;
      class="kw">break;
      }
   class=class="str">"cmt">//---
   if(GetTickCount() - ticks > class="num">500)
      {
      class="type">class="kw">double percent = class="type">class="kw">double(iter) * class="num">100.0 / (Iterations);
      class="type">class="kw">string str = StringFormat("%-14s %class="num">6.2f%% -> Error %class="num">15.8f\n", "Actor",
percent, Actor.getRecentAverageError());
      str += StringFormat("%-14s %class="num">6.2f%% -> Error %class="num">15.8f\n", "Critic",
percent, Critic.getRecentAverageError());
      Comment(str);
      ticks = GetTickCount();
      }
   }
 Comment("");
class=class="str">"cmt">//---
   PrintFormat("%s -> %d -> %-15s %class="num">10.7f", __FUNCTION__, __LINE__, "Actor", Actor.getRecentAverageError());
   PrintFormat("%s -> %d -> %-15s %class="num">10.7f", __FUNCTION__, __LINE__, "Critic", Critic.getRecentAverageError());
   ExpertRemove();
class=class="str">"cmt">//---
   }

◍ 用策略测试器喂出第一份训练集

真正能用的训练数据,得让智能体跟环境实打实碰过才有意义。在 MT5 里跑策略测试器,按历史数据回测并把每步状态、动作、奖励落盘到训练文件,是最直接的采集路径。 手工标理想交易能凑出正样本,但集子一大,人力成本和出错率都随规模线性往上走,人为偏差会直接污染标签。我平时用 Real-ORL 框架拉初始数据,交互程序在系列前篇和附件里都已给全,本小节不重复贴。 初始集只让模型对环境有个粗轮廓。金融市场的多面性决定任何离线集都覆盖不全,学到的指标—盈利依赖可能是错漏的,因为缺反例。所以训练中途必须持续扩集。 这阶段目标是优化参与者策略。我们要采到贴近当前策略轨迹的数据,看清动作偏一点时奖励往哪走,才能朝回报最大化推。随机策略就多跑几遍通验让随机头铺开动作空间;判定式策略就往动作里加扰动,围出云状动作集。两种做法都适合用测试器慢速优化模式补数据。 外汇和贵金属杠杆高、跳空频繁,这种采集方式只解决数据来源,不承诺样本外泛化,集子质量仍要在 MT5 里反复验证。

用 EURUSD 历史数据训练编码器与参与者

把前面梳理过的算法落到过程上:模型用 EURUSD 真实历史、H1 周期、2023 全年数据训练。先训环境状态编码器,它只吃历史价格走势和训练期分析的指标,同一历史窗内通验数据一致,所以初始集上无需优调,跑到预测误差不再降且波动收窄就停。 单纯看误差不够,我抽了训练集子集比预测和真实走势:模型抓住了主趋势,曲线平滑微抖,容易让人怀疑它只是背了整体趋势。换一组状态再比,预测波动更明显但仍贴着实际值,假设没坐实。 编码器就绪后进第二阶段,迭代训参与者政策。首轮在初始集上让模型认环境,Real-ORL 收集的可盈利运行打了底。这阶段盯评论者误差——评论者依赖关系建对了,参与者才调得对方向。评论者误差稳住后,去策略测试器跑 Research.mq5 收新数据,建议慢速优化。 新数据进来重训时,两个模型误差会先小涨再探新低,循环扩集重训即可。参与者带随机头,测试时同一周期要多跑几次通验,偏差可忽略才算训完。 我在 2024 年 1 月(非训练集)测了模型,区间邻近训练窗、数据可比。测试完成 37 笔、17 笔盈利,胜率近 46%,多空盈利份额差 0.32%;盈利因子 1.14,最大与平均盈利均高于亏损。但利润集中在前半月,后半月横盘、末周回撤。外汇与贵金属属高风险,样本外表现可能随市场结构变化而衰减,MT5 慢速优化跑一遍最能验证这套流程。

「训练尾段的回撤信号」

MSFformer 这套多尺度特征提取的训练与测试跑下来,整体样本外表现倾向合格,说明用多尺度聚合做时间序列预测在 FX/贵金属行情里是有可行性的。 但有个细节不能忽略:测试期最后一周出现了余额回撤。这个回撤幅度虽未击穿前期低点,却提示模型在临近样本边界时可能过拟合,或市场状态发生了切换。 碰到这种尾段回撤,较务实的做法是补一段额外训练,而不是直接上实盘。MT5 里把那段回撤周单独切片,重新喂回多尺度提取流程,看损失曲线是否收敛再决定。外汇与贵金属杠杆高,样本外回撤随时可能放大,任何训练结论都只是概率倾向。

◍ 别急着下结论

上面列的那套程序不是拿来直接跑就赚钱的。Research.mq5 到 Test.mq5 五个 EA 只负责把行情切成数据集、训模型、测误差,真正落地前还得靠 Trajectory.mqh 定义状态、NeuroNet.mqh 搭网络、NeuroNet.cl 在 GPU 上算。 整套压缩包 MQL5.zip 体积 1378.56 KB,包含了俄文原版迁移过来的全部源码与类库,但作者明确写了不对策略准确性负责,外汇和贵金属杠杆品种用这套任何输出都只是概率倾向,回测飘红不代表实盘能活。 所以拿到 ZIP 先别急着重构,开 MT5 把 Research.mq5 单独挂一个 symbol 跑一周,看它落地的样本维度跟你自己品种匹不匹配,再谈后面的训练管道。

常见问题

先用原文默认的缩放比例跑通一次,再按验证集损失是否震荡来微调;若损失曲线突然变直,八成是缩放过大。
在测试器里开慢速复盘,把每根K线的特征数组按原文格式落盘,凑够几万样本再停,别拿几百条就训。
小布盯盘的AIGC已内置该类诊断,打开对应品种页即可看到训练尾段的概率回撤提示,不用自己写循环。
大概率要重训或做特征对齐,跨品种波动结构不同,直接套用容易给出偏误信号。
不是,原文仅提示概率倾向,外汇贵金属高风险,应结合实时盘口确认再决策。