您应当知道的 MQL5 向导技术(第 28 部分):据入门学习率重新审视 GAN(基础篇)
📘

您应当知道的 MQL5 向导技术(第 28 部分):据入门学习率重新审视 GAN(基础篇)

第 1/2 篇

◍ 用学习率曲线判断 GAN 训练是否走偏

在 MT5 里跑 GAN 类策略模型,入门阶段最常用的观察项就是学习率(learning rate)随迭代步数的变化。很多新手直接套用默认 0.001 的固定步长,结果前 200 步损失下降很快,之后就长期横在 0.4 附近不动,这种扁平段往往意味着生成器已经陷入局部均衡。 把学习率从固定改成按步数衰减(比如每 50 步乘 0.9),在同样 500 步训练中,损失曲线更容易在 300 步后继续下探到 0.2 以下,说明模型还在吸收价格分布特征。外汇与贵金属行情高波动、高杠杆,用这类未充分收敛的 GAN 直接下单风险极高,仅建议作特征生成辅助。 小布盯盘里可以接 MT5 的 OnTester 回传,把每轮学习率打印成折线,肉眼看衰减拐点比看最终准确率更实在。

把学习率单独拎出来拷问 GAN

这次不铺开讲整套生成式对抗网络,只盯一个超参数:学习率。GAN 是成对跑的神经网络,一个生成器按真实行情样本学着装真,一个判别器专门挑刺;两者表面互骗,实际同步训练,最终生成器吐出的信号才对交易者有用。 我们只在一个极简 GAN 上做文章:3 层结构(5-8-1,输入到输出),1 个隐藏层 8 节点,品种锁 EURJPY、日线、回测区间 2023 全年。架构故意保持朴素,就是为了排除层数干扰,单纯看学习率调度有没有戏。 性能衡量不玩虚的,就盯总盈利加恢复因子。每种学习率格式都附策略测试报告,不再像以前堆到文末才给,边讲边贴,方便你直接对照。所有变体共用同一品种、周期、区间,保证可比性。 下面这段代码是信号类的多空触发核心:生成器输出乘 100 后,判别器背书且值大于 50 才投多,小于 50 才投空。改架构或阈值,直接动这几行就能在 MT5 向导里重编译验证。外汇与贵金属杠杆高,回测盈利不代表实盘概率占优,动手前先想清楚风险。

MQL5 / C++
class=class="str">"cmt">//+------------------------------------------------------------------+
class=class="str">"cmt">//| "Voting" that price will grow.                                                  |
class=class="str">"cmt">//+------------------------------------------------------------------+
class="type">int CSignalCGAN::LongCondition(class="type">void)
{  class="type">int result = class="num">0;
   class="type">class="kw">double _gen_out = class="num">0.0;
   class="type">bool _dis_out = false;
   GetOutput(_gen_out, _dis_out);
   _gen_out *= class="num">100.0;
   if(_dis_out && _gen_out > class="num">50.0)
   {  result = class="type">int(_gen_out);
   }
   class=class="str">"cmt">//printf(__FUNCSIG__ + " generator output is: %.5f, which is backed by discriminator as: %s", _gen_out, class="type">class="kw">string(_dis_out));class="kw">return(class="num">0);
   class="kw">return(result);
}
class=class="str">"cmt">//+------------------------------------------------------------------+
class=class="str">"cmt">//| "Voting" that price will fall.                                                 |
class=class="str">"cmt">//+------------------------------------------------------------------+
class="type">int CSignalCGAN::ShortCondition(class="type">void)
{  class="type">int result = class="num">0;
   class="type">class="kw">double _gen_out = class="num">0.0;
   class="type">bool _dis_out = false;
   GetOutput(_gen_out, _dis_out);
   _gen_out *= class="num">100.0;
   if(_dis_out && _gen_out < class="num">50.0)
   {  result = class="type">int(fabs(_gen_out));
   }
   class=class="str">"cmt">//printf(__FUNCSIG__ + " generator output is: %.5f, which is backed by discriminator as: %s", _gen_out, class="type">class="kw">string(_dis_out));class="kw">return(class="num">0);
   class="kw">return(result);
}

「固定学习率在训练里的取舍」

固定学习率常被刚接触机器学习的人直接拿来用,原因只有一个:够简单。每次迭代里权重和偏差的修正幅度都按同一个浮点值走,跨训练局次也不会变,你用一个值就能贯穿全部过程。 这种写法让训练动态更好预测,也更容易调试和复现。我们在测试里统一把初始权重设为 0.1、初始偏差设为 0.01,靠这组固定值,多次测试跑出来的结果能稳定对齐,不像随机初始化神经网络那样每次都飘。 早期训练阶段它还有个隐性好处:学习率不会像别的策略那样后期猛降或暴跌,新旧数据被一视同仁。当你拿初始权重这类非学习率超参数做基准对比时,固定学习率能让你更快摸到有意义的优化区间。 代价是次优收敛和适应性差。梯度下降可能卡在局部最小值而非全局最优,尤其在你没调好那个固定值之前;而且“学习需求随局次递减”几乎是共识,固定写法显然违背了这点。 即便优缺点并存,在 EURJPY 货币对、2023 年日线周期上做试跑,仍得到一组可观察的训练轨迹,外汇与贵金属这类品种波动剧烈,实盘验证前须认清高风险。

◍ 步进衰减怎么压住学习率

步进衰减本质是个带闸门的固定学习率:只多两个参数,管着初始学习率随训练局次往下掉。MQL5 里判定每局实际学习率分两步,先拿局次索引,再乘衰减系数。 局次索引怎么来?for 循环是倒着数的,用总局次 m_epochs 减当前 i,再除以 m_decay_epoch_steps,MathFloor 向下取整。步长设 5,就每 5 局降一次;设 10 就每 10 局降,不会中途乱降。 [CODE] &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">if</span>(m_learning_type == LEARNING_STEP_DECAY) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;<span class="keyword">int</span> _epoch_index = <span class="keyword">int</span>(<span class="functions">MathFloor</span>((m_epochs - i) / m_decay_epoch_steps)); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; _learning_rate = m_learning_rate * <span class="functions">pow</span>(m_decay_rate, _epoch_index); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} [/CODE] 逐行看:第一行进分支,仅当学习类型被选为步进衰减;第二行算局次索引,倒计数保证越靠近训练尾段索引越大;第三行用 pow 把初始率乘衰减率的指数幂,指数就是刚算出的索引,完成逐步降压。 渐次下调能避免一把冲过最小值,在前期快学、后期细调之间取平衡。相比死盯固定率,它更可能绕开损失面的局部最小和鞍点,泛化倾向更好,过度拟合的概率更低。拿 EURJPY 2023 年日线跑这套,会得到一组随局次阶梯式收缩的学习率曲线,开 MT5 把 m_decay_epoch_steps 从 5 改成 10 对照训练日志就能验证节奏差异。外汇与贵金属波动剧烈,任何训练策略都属高风险验证,实盘前务必隔离测试。

MQL5 / C++
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">if</span>(m_learning_type == LEARNING_STEP_DECAY)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;<span class="keyword">class="type">int</span> _epoch_index = <span class="keyword">class="type">int</span>(<span class="functions">MathFloor</span>((m_epochs - i) / m_decay_epoch_steps));
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; _learning_rate = m_learning_rate * <span class="functions">pow</span>(m_decay_rate, _epoch_index);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}

常见问题

把生成器和判别器的损失随 epoch 画出来,若损失长期震荡不收敛且学习率没跟着降,大概率走偏;此时应调小学习率或加衰减。
单独监控学习率能暴露训练早期步长过大导致的模式崩溃,建议在每 100 步打印一次当前学习率值做比对。
小布可接入你的训练日志,自动标出学习率未衰减的异常段并推送提醒,省去你手动翻曲线。
固定学习率后期容易在最优解附近来回跳,验证集指标波动大;步进衰减能在后期压住步长换稳定。
每训练固定轮数(如 50 轮)乘以 0.5~0.9 的衰减因子,观察损失斜率变缓即说明压住了。