2026-08-01 11:27:28 -04:00 | | | # AI/ — neural network subsystem
|
| | |
|
| | | The engine behind the four AI signal modules (`CSignalPAI`, `CSignalCONV`,
|
| | | `CSignalLSTM`, `CSignalHYBRID`). It is a from-scratch MQL5 network — no external
|
| | | ML runtime — with four interchangeable compute tiers behind one interface.
|
| | |
|
| | | ## File layout
|
| | |
|
| | | `AI\Network.mqh` is the entry point and the only file anything outside `AI\`
|
2026-08-23 21:05:52 -04:00 | | | includes. It holds **declarations only**: every neuron/layer/net class, the
|
| | | compile-time constants, and the nested include chain that orders them. Each
|
| | | nested `#include` sits exactly where its base class becomes visible, so that
|
| | | order is a dependency graph, not a preference — do not reorder it.
|
2026-08-01 11:27:28 -04:00 | | |
|
| | | | file | holds |
|
| | | |---|---|
|
2026-08-23 21:05:52 -04:00 | | | | `Network.mqh` | every class declaration, tuning constants, include chain |
|
2026-08-01 11:27:28 -04:00 | | | | `Network.cl` | OpenCL kernels (see below) |
|
| | | | `ArrayLayer.mqh` | `CArrayLayer` — the layer collection |
|
| | | | `LayerDescription.mqh` | `CLayerDescription` — the topology descriptor |
|
| | | | `BufferDouble.mqh` | `CBufferDouble` — host/device buffer |
|
| | |
|
| | | Method **bodies** live in `AI\Impl\`, included at the bottom of `Network.mqh`
|
| | | after every declaration. This is a pure relocation — a body cannot run during
|
| | | compilation, and every declaration it could reference is already visible above it.
|
| | |
|
| | | | `AI\Impl\` | holds |
|
| | | |---|---|
|
2026-08-23 21:05:52 -04:00 | | | | `NeuronPrimitives.mqh` | `CConnection` / `CArrayCon` — weight storage |
|
2026-08-01 11:27:28 -04:00 | | | | `NeuronBase.mqh` | `CNeuronBase` — init, forward, gradients, activation, persistence |
|
2026-08-23 21:05:52 -04:00 | | | | `NeuronCPU.mqh` | `CNeuron` — pure-MQL5 dense neuron |
|
2026-08-01 11:27:28 -04:00 | | | | `NeuronConvPool.mqh` | `CNeuronConv`, `CNeuronPool` |
|
| | | | `NeuronLSTM.mqh` | `CNeuronLSTM` — gate layers, BPTT |
|
| | | | `Layer.mqh` | `CLayer` — element construction from a descriptor or a `.nnw` stream |
|
2026-08-23 21:05:52 -04:00 | | | | `NetBuild.mqh` | `CNet` lifecycle: topology construction, OpenCL init |
|
2026-08-01 11:27:28 -04:00 | | | | `NetForward.mqh` | `feedForward`, `backProp`, `getResults`, logit adjustment |
|
| | | | `NetPersistence.mqh` | `CNet::Save` / `CNet::Load` — the `.nnw` format |
|
| | | | `NetWeights.mqh` | EMA blend, in-memory snapshot/restore, per-layer learning report |
|
| | | | `NeuronOCLBase.mqh` | `CNeuronBaseOCL` |
|
2026-08-23 21:05:52 -04:00 | | | | `NeuronOCLConvPool.mqh` | `CNeuronConvOCL`, `CNeuronPoolOCL` |
|
| | | | `NeuronBatchNorm.mqh` | `CNeuronBatchNormOCL` — host-side batch norm, all tiers |
|
2026-08-01 11:27:28 -04:00 | | | | `NeuronOCLLSTM.mqh` | `CNeuronLSTMOCL` — sequence LSTM, fused kernels, BPTT caches |
|
| | |
|
| | | ## Compute tiers
|
| | |
|
| | | Selected once at construction and logged; each layer runs entirely on one tier.
|
| | |
|
| | | 1. **OpenCL** — `Network.cl`, compiled from the `#resource` at startup.
|
| | | 2. **DirectML** — `WarriorDML.dll` (D3D12 compute).
|
| | | 3. **CPU DLL** — `WarriorCPU.dll`, a threaded fallback. Thread count is fixed at
|
| | | `CPU_THREADS_PER_NETWORK` per net rather than a share of the machine; see the
|
| | | comment on that constant for why a machine-wide budget was wrong.
|
| | | 4. **Pure MQL5** — no DLL, no GPU. Single backtests run here so a Market build
|
| | | (which strips every `#import`) is still able to infer.
|
| | |
|
| | | A Market build (`WARRIOR_MARKET_BUILD`) compiles tiers 2 and 3 out entirely.
|
| | |
|
| | | ## Classes
|
| | |
|
| | | - **`CNet`** — owns the layer stack, the forward/backward passes and `.nnw`
|
| | | persistence. Note that a `.nnw` pins the **architecture**, not just the
|
| | | weights: `Save` writes each layer's activation and `Load` restores it, so a
|
| | | head activation changed in source only ever reaches a brand-new topology.
|
| | | `EnforceOutputActivation()` re-asserts it after every load.
|
| | | - **`CLayer` / `CArrayLayer`** — neuron containers; `CreateElementScaled()` is
|
| | | the single construction point for every neuron type, from a descriptor or from
|
| | | a file stream.
|
| | | - **`CNeuronBase` → `CNeuron` / `CNeuronPool` / `CNeuronConv` / `CNeuronLSTM`** —
|
| | | the pure-MQL5 family.
|
| | | - **`CNeuronBaseOCL` → `CNeuronLSTMOCL` / `CNeuronConvOCL` / `CNeuronPoolOCL` /
|
| | | `CNeuronBatchNormOCL`** — the accelerated family. Despite the `OCL` suffix
|
| | | these also drive the DirectML and CPU-DLL tiers.
|
| | |
|
| | | `ENUM_ACTIVATION` is `NONE, TANH, SIGMOID, PRELU`; `ENUM_OPTIMIZATION` is
|
| | | `SGD, ADAM`. `NativeActivationCode()` translates to the int code the backends
|
| | | share — and deliberately makes `NONE` fall through every backend switch.
|
| | |
|
| | | ## Network.cl
|
| | |
|
| | | 22 kernels in four groups: dense (`FeedForward`, `CaclOutputGradient`,
|
| | | `CaclHiddenGradient`, `UpdateWeightsMomentum/Adam`), conv/pool (`FeedForwardConv`,
|
| | | `FeedForwardProof`, `CalcHiddenGradientConv`, `CalcInputGradientProof`,
|
| | | `UpdateWeightsConv*`), single-step LSTM (`LSTM_Gates`, `LSTM_State`,
|
| | | `LSTM_*Gradient`) and sequence LSTM (`LSTM_SeqStep*`, `LSTM_UpdateWeights*`).
|
| | |
|
| | | Two invariants worth knowing before touching them:
|
| | |
|
| | | - `MIN_ACTIVATION_DERIVATIVE` (1.0e-3f) floors every LSTM gate derivative in both
|
| | | gradient kernels. It is already there — do not "add" it.
|
| | | - Kernel math is mirrored in `DirectML\WarriorCPU.cpp` and `WarriorDML.cpp`.
|
| | | A change to one is a change to all three, or the tiers silently diverge.
|
| | |
|
| | | ## Usage
|
| | |
|
| | | ```
|
| | | CNet *net = new CNet(topology); // CArrayObj of CLayerDescription
|
| | | net.feedForward(inputs); // CArrayDouble
|
| | | net.backProp(targets, weight);
|
| | | net.getResults(out);
|
| | | net.Save(path, ...); net.Load(path, ...);
|
| | | ```
|
| | |
|
| | | The 3-output classification case is special-cased in `backProp`/`backPropOCL`:
|
| | | it computes a joint softmax + cross-entropy gradient across all three neurons
|
| | | rather than three independent per-neuron deltas.
|
| | |
|
| | | ## Known gaps
|
| | |
|
| | | - No unit tests. Changes are validated by compile + a live era's `dW/W` line
|
| | | (`CNet::LayerLearningReport`), which is the only reliable check that a layer is
|
| | | actually receiving gradient in the assembled net.
|
| | | - No dedicated SoftMax layer; the head is `Dense(SIGMOID)` with the gradient
|
| | | short-circuited. See `REFACTOR_NOTES.md` §G for why, and for what would have to
|
| | | move together to change it.
|