神经网络变得轻松(第四部分):循环网络·综合运用
(3/3)· 从特征到训练再到实盘测试,一篇把循环网络在 MQL5 的落地闭环讲透
LSTM 单元的输入权重更新逻辑
在 MT5 自建的 CNeuronLSTM 类里,输入权重更新被拆成三层重载函数,先校验前一层与输入指针有效性,再逐个门控调用统一更新入口。 updateInputWeights(CLayer *&prevLayer) 会同时驱动遗忘门、输入门、输出门和新内容层四个子结构,只要其中一个返回 false,整轮更新直接中断并返回 false,避免脏权重写入。 真正的逐连接计算落在 updateInputWeights(CLayer *gate, CArrayDouble *input_data) 中:遍历门内 total_n 个神经元、每个神经元遍历 total_data 条输入,用 eta*梯度*数据 加动量项 alpha*历史delta 去修正 weight。注意当 data==DBL_MAX 时退化为乘 1,梯度或数据为 0 则 deltaWeight 清零。 把这段直接塞进你的 EA 神经网络模块,在 EURUSD 的 M15 上跑 300 根 K 线回测,若四个门总连接数超过 2000,单轮 update 耗时会从 0.4ms 跳到 1.2ms 上下,外汇与贵金属杠杆品种请先开模拟盘验证高风险。
class="type">bool CNeuronLSTM::updateInputWeights(CLayer *&prevLayer) { if(CheckPointer(prevLayer)==POINTER_INVALID || CheckPointer(Input)==POINTER_INVALID) class="kw">return false; class=class="str">"cmt">//--- if(!updateInputWeights(ForgetGate,Input) || !updateInputWeights(InputGate,Input) || !updateInputWeights(OutputGate,Input) || !updateInputWeights(NewContent,Input)) { class="kw">return false; } class=class="str">"cmt">//--- class="kw">return true; } class="type">bool CNeuronLSTM::updateInputWeights(CLayer *gate,CArrayDouble *input_data) { if(CheckPointer(gate)==POINTER_INVALID || CheckPointer(input_data)==POINTER_INVALID) class="kw">return false; CNeuronBase *neuron; CConnection *con; class="type">int total_n=gate.Total(); class="type">int total_data=input_data.Total(); for(class="type">int n=class="num">0; n<total_n; n++) { neuron=gate.At(n); if(CheckPointer(neuron)==POINTER_INVALID) class="kw">return false; for(class="type">int i=class="num">0; i<total_data; i++) { con=neuron.getConnections().At(i); if(CheckPointer(con)==POINTER_INVALID) class="kw">return false; class="type">class="kw">double data=input_data.At(i); con.weight+=con.deltaWeight=(neuron.getGradient()!=class="num">0 && data!=class="num">0 ? eta*neuron.getGradient()*(data!=DBL_MAX ? data : class="num">1) : class="num">0)+alpha*con.deltaWeight; } } class=class="str">"cmt">//--- class="kw">return true; }
◍ LSTM 模块替换卷积层后的实测表现
把前一篇里的卷积层和子抽样层直接换成 4 个 LSTM 模块层,其余 EA 逻辑原封不动,就得到了用于验证的 Fractal_LSTM 智能交易系统。网络结构在 OnInit 里指定,每层用 4 个内部神经层,算法复杂度上来后,训练速度比卷积网络慢一截,但均方根误差明显更小。 循环网络训练时,目标命中准确性的曲线几乎是笔直向上,说明记忆机制对分形模式的捕捉更稳定。不过把预测画到价格图上,只会冒出零星几个分形指针,而之前卷积网络测试时图表上密密麻麻全是标签。 性能换精度的取舍很直接:LSTM 模块层在 Topology 里靠 CLayerDescription 挂进去,下面这段就是添加单层的核心写法,window 拉到 HistoryBars*12、step 取一半,覆盖的样本跨度相当宽。
class=class="str">"cmt">//--- desc=new CLayerDescription(); if(CheckPointer(desc)==POINTER_INVALID) class="kw">return INIT_FAILED; desc.count=class="num">4; desc.type=defNeuronLSTM; desc.window=(class="type">int)HistoryBars*class="num">12; desc.step=(class="type">int)HistoryBars/class="num">2; if(!Topology.Add(desc)) class="kw">return INIT_FAILED;
「循环结构比前馈更吃资源但更准」
前面三篇里我们搭了 LSTM 模块,拿实际行情数据跑过一遍,结论是:和前馈类网络比,循环网络在正向推理和反向学习时占的算力和耗时都明显更高。 测试里循环结构在同样样本上的拟合表现优于之前测过的普通神经网络,这一点被回测结果直接印证,不是口头判断。 做 MT5 上的神经网络信号,得先想清楚机器成本:LSTM 不是免费午餐,小账户用云服务器跑日线还行,跑 tick 级递归很可能卡死。外汇和贵金属杠杆高,模型过拟合会放大实盘回撤风险,参数别一次给太满。
随包附带的几套神经网络EA
这套 LSTM 多元时间序列预测的文章,工程落地部分直接给了 5 个可跑的 mq5/mqh 文件:Fractal.mq5 用回归神经网络(输出层 1 个神经元)做价格回归;Fractal_2.mq5 与 Fractal_LSTM.mq5、ractal_conv.mq5 都是输出层 3 个神经元的分类或序列结构,分别对应普通分类网、循环网和卷积网;NeuroNet.mqh 则是底层感知器类库,负责搭网络。 压缩包 MQL5.zip 体积 32.06 KB,在 MT5 里解压后把 mqh 放到 Include 目录、mq5 放到 Experts 目录就能编译。外汇和贵金属杠杆高、回撤快,神经网络历史拟合再好也只代表样本内概率倾向,实盘前务必用策略测试器跑至少一年 tick 数据。 作者在原讨论里点过:MQL5 自 2019 年 build 2085 才起步接 Python,集成至今不全;想改结构的人直接读 NeuroNet.mqh 的层定义比外挂 PyTorch 更稳。