神经网络实践:伪逆 (二)·进阶篇
◍ 从扁平数组还原双列回报矩阵
这段收尾代码把一维数组 M 里的数据按奇偶位置拆回二维数组 Ret,是前面压缩存储的逆操作。 第29行把 M 的偶数索引 (c*2+0) 写进 Ret[c][0],第30行把奇数索引 (c*2+1) 写进 Ret[c][1],循环变量 c 每增1就消费 M 中两个元素。 第33行直接 return Ret,函数到此结束。你在 MT5 里跑这段时,若 M 长度不是 2*c 的整数倍,越界读到的会是0或引发数组错误,建议调用前用 ArraySize(M) 做一次断言。
class="num">29. Ret[c][class="num">0] = M[(c * class="num">2) + class="num">0]; class="num">30. Ret[c][class="num">1] = M[(c * class="num">2) + class="num">1]; class="num">31. } class="num">32. class="num">33. class="kw">return Ret; class="num">34. } class="num">35. class=class="str">"cmt">//+------------------------------------------------------------------+
「把伪逆改成直接吐回归系数」
上一节用数组算伪逆,这一步还能再榨性能:不返回伪逆矩阵,直接返回线性回归的斜率和交点,让 GPU 或专用 CPU 单元跑满速。改动量很小,核心是把原本算完伪逆就停的逻辑,续上一步矩阵乘向量的操作。 代码第 7–11 行先做动态数组检查,若 Ret 不是动态类型就打印提示并故意触发除零让程序退出,这是硬性防护。第 12–19 行把 Infos 里偶数索引当作横坐标累加构造 2×2 矩阵元素,第 20 行算行列式 Det,21–23 行得出逆矩阵存进 T。 第 30 行之后是和上一篇不同的地方:把伪逆结果 M 与 Infos 的奇数索引向量相乘,得到的 Ret[0]、Ret[1] 就是线性回归方程 y = a·x + b 里的 a 和 b。如果你拿上篇 PInv 的返回值手算这步,结果完全一致,只是本实现更贴合硬件流水线。 别把硬件加速当革命 所谓“处理器内置 AI”多是把原先软件里的伪逆和矩阵乘搬进电路,通用核变专用核而已。MT5 上你直接抄下面代码就能验证:接一组 (x, p) 点进去,Ret 输出的两个数就是你能拿去画趋势线的系数,外汇和贵金属波动大、杠杆高,系数仅描述历史点列拟合,实盘信号概率性失效要自担风险。
class="num">01. class=class="str">"cmt">//+------------------------------------------------------------------+ class="num">02. class="type">void Straight_Function(class="kw">const class="type">class="kw">double &Infos[], class="type">class="kw">double &Ret[]) class="num">03. { class="num">04. class="type">class="kw">double M[], T[class="num">4], Det; class="num">05. class="type">uint n = (class="type">uint)(Infos.Size() / class="num">2); class="num">06. class="num">07. if (!ArrayIsDynamic(Ret)) class="num">08. { class="num">09. Print("Response array must be of the dynamic type..."); class="num">10. Det = (class="num">1 / MathAbs(class="num">0)); class="num">11. } class="num">12. ArrayResize(M, Infos.Size()); class="num">13. M[class="num">0] = M[class="num">1] = class="num">0; class="num">14. M[class="num">3] = (class="type">class="kw">double)(n); class="num">15. for (class="type">uint c = class="num">0; c < n; c++) class="num">16. { class="num">17. M[class="num">0] += (Infos[c * class="num">2] * Infos[c * class="num">2]); class="num">18. M[class="num">2] = (M[class="num">1] += Infos[c * class="num">2]); class="num">19. } class="num">20. Det = (M[class="num">0] * M[class="num">3]) - (M[class="num">1] * M[class="num">2]); class="num">21. T[class="num">0] = M[class="num">3] / Det; class="num">22. T[class="num">1] = T[class="num">2] = -(M[class="num">1] / Det); class="num">23. T[class="num">3] = M[class="num">0] / Det; class="num">24. ZeroMemory(M); class="num">25. for (class="type">uint c = class="num">0; c < n; c++) class="num">26. { class="num">27. M[(c * class="num">2) + class="num">0] = (Infos[c * class="num">2] * T[class="num">0]) + T[class="num">1]; class="num">28. M[(c * class="num">2) + class="num">1] = (Infos[c * class="num">2] * T[class="num">2]) + T[class="num">3]; class="num">29. } class="num">30. ArrayResize(Ret, class="num">2); class="num">31. ZeroMemory(Ret); class="num">32. for (class="type">uint c = class="num">0; c < n; c++) class="num">33. { class="num">34. Ret[class="num">0] += (Infos[(c * class="num">2) + class="num">1] * M[(c * class="num">2) + class="num">0]);
循环累加里的隐藏权重
上面这段 MQL5 片段只做了一件事:把偶数索引的 Infos 与对应 M 数组相乘,再叠进 Ret[1]。 第 35 行用 (c * 2) + 1 取奇数偏移,说明真正参与回归的不是连续样本,而是隔位抽出的特征通道;若 c 从 0 跑到某上限,Ret[1] 的最终值完全由这些交错项的乘积和决定。 在 MT5 里把这段塞进自定义指标,打印 Ret[1] 随 K 线推移的数值,你会看到它在横盘段波动极小、突破段陡变——外汇与贵金属杠杆高,这种突变常伴随假突破,验证时务必切到 M5 以上周期交叉比对。
class="num">35. Ret[class="num">1] += (Infos[(c * class="num">2) + class="num">1] * M[(c * class="num">2) + class="num">1]); class="num">36. } class="num">37. } class="num">38. class=class="str">"cmt">//+------------------------------------------------------------------+
◍ 画得少,看得清
把视野收回到最底层:我们折腾半天其实只做了一件事——让单个神经元完成一次线性回归计算。神经网络并不神秘,它只是把同样的数学动作在图结构里重复放大,每个节点无非是一个神经元或一条回归线,信号顺着计算结果挑路径走。 媒体爱把 AI 包装成黑箱魔法,但机器底层跑的永远是加减乘除。你搞清楚一次前向计算,就拿到了理解整个网络的钥匙,不必急着往外汇或贵金属盘面上硬套,那类品种高杠杆、高波动,盲用模型只会放大亏损概率。 随文给的 Anexo_01.mq5(1.47 KB)和 Anexo_02.mq5(5.98 KB)就是让你在 MT5 里单步跑通神经元用的。下一篇才会把这些单元拼成能学习的小网络,思路清楚了,后面组织权重更新才不会迷路。