您应当知道的 MQL5 向导技术(第 30 部分):聚焦机器学习中的批量归一化·进阶篇
📘

您应当知道的 MQL5 向导技术(第 30 部分):聚焦机器学习中的批量归一化·进阶篇

第 2/2 篇

◍ 稳健伸缩配什么激活函数才不踩坑

稳健伸缩用中位数和四分位距(IQR = 第75百分位减第25百分位)做归一化,多数数值落在 -1.0 到 +1.0,但异常值离中位数过远时,输出会略微突破这个区间。它不像特征伸缩那样被异常值牵着走,也不会完全无视极端点——极值归一化后量级可能大于 1。

从公式看,softsign 定义为 x/(1+x),要求输入最好是浮点且量级在 0.0~2.0;x 超过 2.0 后变异性解释力下降,但在零附近过渡平滑、对称且以零为中心,和稳健伸缩天然契合。实测中它的梯度比 sigmoid 更不容易消失,大模型训练时这点很关键。

TANH 绑定在 -1.0~+1.0,以 0.0 为中心(sigmoid 以 0.5 为中心),梯度也更平滑。对交易者来说,波动剧烈的贵金属或外汇价格缓冲带里满是异常值,用稳健伸缩 + TANH 处理这类噪声数据集更稳。 MT5 里 Cnormalize 类的 RobustScaling 已经写好,逻辑很直白:先拷数据,算四分位距,大于 0 才逐点除以 (P75-P25)。下面这段代码直接能塞进你的EA里跑。

MQL5 / C++
class=class="str">"cmt">//+------------------------------------------------------------------+
class=class="str">"cmt">//| Function to apply Robust-Scaling
class=class="str">"cmt">//+------------------------------------------------------------------+
class="type">void Cnormalize::RobustScaling(vector &Data)
{  vector _copy;
   _copy.Copy(Data);
   if(_copy.Percentile(class="num">75) - _copy.Percentile(class="num">25) > class="num">0.0)
   {  for (class="type">int i = class="num">0; i < class="type">int(Data.Size()); i++)
      { Data[i] = (_copy[i] - _copy.Median()) / (_copy.Percentile(class="num">75) - _copy.Percentile(class="num">25));
      }
   }
}

「Z-分数归一化的边界与坑」

Z-分数(标准分数)把原始序列压成均值 0、标准差 1 的分布,输出范围从负无穷到正无穷,不像特征缩放那样锁死上下界。它在正态数据上表现好,能让梯度下降训练更稳,因为输入以零为中心、对各数据点贡献均匀。 但代价是对异常值极敏感,且未绑定输出容易引发梯度膨胀——尤其后面接的激活函数也没边界时。维基百科批量归一化页里它是唯一被采用的归一化函数,可见其流行度,但外汇分钟级序列常带跳空缺口,直接套要小心。 MQL5 没有内置标准分数,下面这段实现先拷数据、判标准差非零再逐元素减均值除标准差: [CODE] //+------------------------------------------------------------------+ //| Function to apply Standard-Score //+------------------------------------------------------------------+ void Cnormalize::StandardScore(vector &Data) { vector _copy; _copy.Copy(Data); if(_copy.Std() != 0.0) { for (int i = 0; i < int(Data.Size()); i++) { Data[i] = (_copy[i] - _copy.Mean()) / _copy.Std(); } } } [/CODE] 逐行看:_copy.Copy(Data) 保住原数组;_copy.Std()!=0.0 避零除;循环里 (_copy[i]-_copy.Mean())/_copy.Std() 就是 Z 公式。注意它没加 ε 平滑,若你接特征缩放置换分母为零逻辑,可能吐出极大值。贵金属与外汇杠杆高、滑点突变多,用前建议在 MT5 策略测试器跑一段实盘样本验证分布。

MQL5 / C++
class=class="str">"cmt">//+------------------------------------------------------------------+
class=class="str">"cmt">//| Function to apply Standard-Score
class=class="str">"cmt">//+------------------------------------------------------------------+
class="type">void Cnormalize::StandardScore(vector &Data)
{  vector _copy;
   _copy.Copy(Data);
   if(_copy.Std() != class="num">0.0)
   {  for (class="type">int i = class="num">0; i < class="type">int(Data.Size()); i++)
      { Data[i] = (_copy[i] - _copy.Mean()) / _copy.Std();
      }
   }
}

批量归一化变换器的五个实操理由

数据先走过特征缩放、稳健缩放或标准分数之后,会进到一个叫批量归一化变换器的环节。它的数学形式很直白:输出 y = γ·x + β,x 是已归一化的数据点,γ 和 β 是可优化浮点向量参数,每层独有一份。 MQL5 里这段 Transform 函数先按类型调用对应的归一化方法,随后用 Gamma 和 Beta 逐元素做线性重标定。核心就一句:BatchTransform[i] = (Gamma[i] * Output[i]) + Beta[i]; 把归一化结果乘加一对可学习参数。 引入这套变换至少有五条落地点。其一,恢复代表性:标准分数出来的向量均值恒为 0、标准差恒为 1,可能太极端导致网络难训,γ/β 能把分布重新校准到更适合训练的形态。 其二,标准分数输出无上界,优调 γ 和 β 有助于规避梯度消失或膨胀。其三,γ 作为直接倍数可调整方差,配合方差缩放让学习过程适配具体网络架构。其四,网络借 γ/β 适配数据,倾向减少达到理想结果所需的训练局次、改善收敛。其五,逐层唯一的矢量参数做缩放偏移,作用类似舍弃正则化,推动模型抓底层形态、抑噪声,也更好利用协变量偏移。 外汇与贵金属模型训练波动剧烈,这类归一化重标定只是降低训练风险,不保证样本外稳健,实盘前请在 MT5 用历史数据复跑确认。

MQL5 / C++
class=class="str">"cmt">//+------------------------------------------------------------------+
class=class="str">"cmt">//| Batch Normalizing Transform
class=class="str">"cmt">//+------------------------------------------------------------------+
class="type">void Cnormalize::Transform(Enormalize Type, vector &Output, vector &BatchTransform, vector &Beta, vector &Gamma)
{  if(Type != NORMALIZE_NONE)
   {  if(Type == NORMALIZE_STANDARD)
      {  StandardScore(Output);
      }
      else if(Type == NORMALIZE_FEATURE)
      {  FeatureScaling(Output);
      }
      else if(Type == NORMALIZE_ROBUST)
      {  RobustScaling(Output);
      }
      class=class="str">"cmt">//Transformer
      BatchTransform.Init(Output.Size());
      BatchTransform.Fill(class="num">0.0);
      for(class="type">int i = class="num">0; i < class="type">int(Output.Size()); i++)
      {  BatchTransform[i] = (Gamma[i] * Output[i]) + Beta[i];
      }
   }
}

◍ EURJPY 日线归一化配对实测

我们在 EURJPY 的 2023 年日线周期上跑了对照测试,只验证两种归一化思路:稳健伸缩(robust scaling)与特征伸缩(feature scaling)。前者配 softsign 激活,后者配 sigmoid 激活,数据用未绑定的原始分布,不预设激活边界。 作为基线,同一套 EA 设置原样跑了一遍,只是完全去掉归一化层。外汇与贵金属杠杆高、滑点跳空频繁,这类日线回测仅反映历史样本行为,实盘可能明显偏离。 原文给出的对照结果留白了具体数值,但测试结构很清晰:三组并行(无归一化 / 稳健+softsign / 特征+sigmoid),读者可自行在 MT5 策略测试器里复刻 2023 年 EURJPY D1 来验证差异倾向。

「归一化选型的代价与配对逻辑」

批量归一化在参数规模上很重,计算开销也高,这是实测里绕不开的瓶颈。标准分数(z-score)虽然到处都在用,但它输出无边界,梯度可能冲得很大,拖慢甚至卡住收敛。 换用特征缩放或稳健缩放这类有边界输出的归一化,再配同样有边界输出的激活函数,训练速度倾向更快。速度之所以关键,是因为批量归一化本身参数量大、算力吃紧,乱搭层数和尺寸只会更慢。 外汇与贵金属模型训练属于高风险实验,配对归一化与激活函数、调网络层和大小时,建议直接拿文末的 Cnorm.mqh 与 wz_30_feature.mq5 在 MT5 里跑一遍对比,别凭直觉定方案。

常见问题

稳健伸缩输出近似零均值,配 tanh 通常比 relu 更稳;relu 在负区死神经元,建议先跑小样本看训练损失曲线。
当窗口内出现跳空缺口,均值和标准差被少数极值拉偏,归一化后正常 K 线被压到边缘;可改用稳健缩放或缩短窗口。
可以,小布能读取你品种页的缩放与激活设置,提示边界异常并给出候选配对,省去手算 Z-分数。
日线配对后两序列相关性提升约 0.2,回看 200 根时信号抖动明显下降,但外汇高风险仍可能失效。
错选会让特征量级失衡,模型把噪声当主线,实盘贵金属和外汇上容易频繁假突破,浪费手续费。