神经类群优化算法 (NOA)·进阶篇
多宇宙锚点如何用神经网络扰动
这段实现把 NOA 的并行搜索和神经网络揉在一起:初始化阶段给 popSize 个个体分配不同的激活函数(Sigmoid、SoftPlus、SiLU、Snake 等 8 种),再用 GetTickCount64 加偏移做随机数种子,保证每个网络权重独立。 首次 Moving 里 revision 为假时,直接给所有个体的 coords 维锚点 a[i].c[c] 在 [rangeMin, rangeMax] 内均匀随机,并 Snap 到离散网格 rangeStep,之后置 revision=true 返回,不进入后续演化。 后续每次调用 Moving,先对前 popSize-5 个个体按 eliteProb 概率把坐标替换为当前最优 cB,实现精英保留;再对每个个体跑前向/反向传播:用神经网络输出 outData 乘上区间跨度与 dispScale 再乘随机概率去扰动锚点,依旧 Snap 到网格。 Revision 函数只做一件事:遍历 popSize,若某个体适应度 a[i].f 大于记录最优 fB,就更新 fB 并拷贝坐标到 cB。外汇/贵金属市场高波动,这种群体+网络混合搜索可能提升参数寻优鲁棒性,但过拟合风险偏高,建议开 MT5 把 popSize 调到 50 以内先验证耗时。
eActAlgSigm, class=class="str">"cmt">//class="num">1 eActRatSigm, class=class="str">"cmt">//class="num">2 eActSoftPlus, class=class="str">"cmt">//class="num">3 eActBentIdent, class=class="str">"cmt">//class="num">4 eActSiLU, class=class="str">"cmt">//class="num">5 eActACON, class=class="str">"cmt">//class="num">6 eActSERF, class=class="str">"cmt">//class="num">7 eActSnake class=class="str">"cmt">//class="num">8 }; ArrayResize(nn, popSize); class="type">int cnt = class="num">0; for (class="type">int i = class="num">0; i < popSize; i++) { nn [i].Init(nnConf, actFunc, (class="type">int)GetTickCount64() + cnt); cnt++; } class="kw">return true; } class=class="str">"cmt">//—————————————————————————————————————————————————————————————————————————————— class=class="str">"cmt">//—————————————————————————————————————————————————————————————————————————————— class="type">void C_AO_NOA::Moving() { class=class="str">"cmt">//---------------------------------------------------------------------------- if (!revision) { class=class="str">"cmt">// Initialize the initial values of anchors in all parallel universes for (class="type">int i = class="num">0; i < popSize; i++) { for (class="type">int c = class="num">0; c < coords; c++) { a [i].c [c] = u.RNDfromCI(rangeMin [c], rangeMax [c]); a [i].c [c] = u.SeInDiSp(a [i].c [c], rangeMin [c], rangeMax [c], rangeStep [c]); } } revision = true; class="kw">return; } class=class="str">"cmt">//---------------------------------------------------------------------------- class="type">class="kw">double rnd = class="num">0.0; class="type">class="kw">double val = class="num">0.0; class="type">int pair = class="num">0.0; for (class="type">int i = class="num">0; i < popSize - class="num">5; i++) { for (class="type">int c = class="num">0; c < coords; c++) { if (u.RNDprobab() < eliteProb) { a [i].c [c] = cB [c]; } } } class="type">class="kw">double inpData []; ArrayResize(inpData, coords); class="type">class="kw">double outData []; ArrayResize(outData, coords); class="type">class="kw">double targVal []; ArrayResize(targVal, coords); class="type">class="kw">double err []; ArrayResize(err, coords); for (class="type">int i = class="num">0; i < popSize; i++) { ScaleInp(cB, targVal); ScaleInp(a [i].c, inpData); nn [i].ForwProp(inpData, outData); for (class="type">int c = class="num">0; c < coords; c++) err [c] = targVal [c] - outData [c]; nn [i].BackProp(err); for (class="type">int c = class="num">0; c < coords; c++) { a [i].c [c] += outData [c] * (rangeMax [c] - rangeMin [c]) * dispScale * u.RNDprobab(); a [i].c [c] = u.SeInDiSp(a [i].c [c], rangeMin [c], rangeMax [c], rangeStep [c]); } } } class=class="str">"cmt">//—————————————————————————————————————————————————————————————————————————————— class=class="str">"cmt">//—————————————————————————————————————————————————————————————————————————————— class="type">void C_AO_NOA::Revision() { for (class="type">int i = class="num">0; i < popSize; i++) { if (a [i].f > fB) { fB = a [i].f; ArrayCopy(cB, a [i].c); } } } class=class="str">"cmt">//—————————————————————————————————————————————————————————————————————————————— class=class="str">"cmt">//——————————————————————————————————————————————————————————————————————————————
「特征向量的双向归一化封装」
在 AO_NOA 这类自组织映射实现里,输入特征往往量纲不一,直接喂给网络会让权重被绝对值大的维度带偏。上面两段代码把缩放逻辑收口到 ScaleInp 与 ScaleOut 两个方法,分别负责训练前压入与推理后还原。 ScaleInp 遍历 coords 个坐标,调用 u.Scale 把每个 inp[c] 从 [rangeMin[c], rangeMax[c]] 线性映射到 [-1, 1]。注意 rangeMin 与 rangeMax 是按维度独立存储的数组,说明各特征列允许有不同的原始区间,而不是全局统一标度。 ScaleOut 做逆操作:把网络输出的 [-1, 1] 值按同一组 rangeMin/rangeMax 反算回原始量纲。若你在 MT5 里接贵金属多周期波动率做聚类,这两个函数能保证样本进出空间一致,避免可视化时坐标轴错位。外汇与贵金属杠杆高、跳空频繁,归一化区间若用含极端影线的历史极值,可能放大异常样本权重,建议回测时先截尾再存 range 数组。
class="type">void C_AO_NOA::ScaleInp(class="type">class="kw">double &inp [], class="type">class="kw">double &out []) { for (class="type">int c = class="num">0; c < coords; c++) out [c] = u.Scale(inp [c], rangeMin [c], rangeMax [c], -class="num">1, class="num">1); } class=class="str">"cmt">//—————————————————————————————————————————————————————————————————————————————— class=class="str">"cmt">//—————————————————————————————————————————————————————————————————————————————— class="type">void C_AO_NOA::ScaleOut(class="type">class="kw">double &inp [], class="type">class="kw">double &out []) { for (class="type">int c = class="num">0; c < coords; c++) out [c] = u.Scale(inp [c], -class="num">1, class="num">1, rangeMin [c], rangeMax [c]); } class=class="str">"cmt">//——————————————————————————————————————————————————————————————————————————————
◍ NOA 在中低维测试里的真实得分
神经类群优化(NOA)在小维度和中等维度函数上跑出了可复现的结果。当变量规模拉到 1000 个时,单次计算耗时长到没法接受,所以高维测试直接弃了,没进评分表。 在 9 次独立测试中,NOA 有 6 次达到最优值的约 45%,总得分 2.69447,折合满分百分比 44.91%。具体拆开看:5 Hilly 函数跑 10000 次得 0.70135,25 Hilly 得 0.40129;5 Forest 得 0.62230,25 Forest 得 0.30830;5 Megacity 得 0.45231,25 Megacity 得 0.20892。 NOA 在可视化上形成了明显的扇形结构,这其实是神经类群内部网络输出的空间投影,不是随机散点。想验证的话,在 MT5 里把类群坐标按代打印出来就能看到类似扇面。 横向对比里 NOA 被单独列在无序号行,因为它缺高维数据。同表 40 个算法中,榜首 ANS 拿 6.134(68.15%),NOA 的 44.91% 排接近末尾,仅略高于 CGO 的 43.35%。外汇与贵金属 EA 若借用这类优化器做参数寻优,需明确其高维失效风险,实盘前务必小样本重测。
优化算法横向跑分看差异
把一批元启发式算法丢进同一测试框架,用四组指标(均值、方差、收敛值、综合分)横向比,能直接看出谁在外汇/贵金属参数寻优里更扛造。下表节选了部分结果:ATAm 综合分 42.58、ASHA 40.71、ASBO 40.63,而 NOA 只有 29.94、RW 随机游走 26.09。 注意 NOA 的中间三列全是 0.00000,说明该算法在测试集上某几项指标直接失效,不是单纯分数低。RW 随机游走各项都垫底,印证了无方向搜索在高维参数空间里效率极差。 这类跑分只是算法层参考,真上 MT5 做 EA 参数优化,还得绑具体品种和周期。外汇/贵金属杠杆高、滑点跳空频繁,回测优的算法实盘也可能翻车,结论仅代表概率倾向。
「NOA 的下一步与边界」
神经类群(NOA)把神经网络和优化算法揉在一起,思路来自简单生物的集体智能。在多家测试函数上,它拿到了约 45% 的效率评分——对一个全新概念的方法,算是个能跑的起点,中等复杂度任务里表现最稳。 跑 1000 个变量时,瓶颈立刻显形:要并行训多个神经网络,资源消耗让计算变得不实用。各次运行结果波动大,一面是缺乏可预测性,另一面也是探索策略多样的征兆,在复杂地形里反而可能是优势。 作者留了两条演进方向:压缩神经网络架构减负、做类群间的知识迁移。附带 NOA.zip(181.52 KB)里有 #C_AO.mqh、MLPa.mqh 等 10 个文件,Test_AO_NOA.mq5 可直接在 MT5 跑通验证。 外汇与贵金属市场高波动、高杠杆,这类实验性算法只宜在策略研究层做对照,别直接当实盘信号源。下载脚本自己压一遍 50 与 500 维函数,比读结论更有用。