//+------------------------------------------------------------------+ //| NNDemo.mq5 | //| Copyright 2025, Google Gemini | //| https://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "Copyright 2025, Google Gemini" #property link "https://www.google.com" #property version "1.00" #include input int InpEpochs = 2000; input double InpTargetError = 0.001; CNeuralNet *Net; int topology[]; //+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ int OnInit() { // Define Topology: 2 Inputs, 3 Hidden Neurons, 1 Output ArrayResize(topology, 3); topology[0] = 2; topology[1] = 3; topology[2] = 1; Net = new CNeuralNet(topology); Print("--- Starting XOR Training ---"); // XOR Training Data // Inputs: {0,0}, {0,1}, {1,0}, {1,1} // Target: {0}, {1}, {1}, {0} double inputs[4][2] = {{0,0}, {0,1}, {1,0}, {1,1}}; double targets[4][1] = {{0}, {1}, {1}, {0}}; for(int epoch = 0; epoch < InpEpochs; ++epoch) { for(int i = 0; i < 4; ++i) { double inputSample[]; ArrayResize(inputSample, 2); inputSample[0] = inputs[i][0]; inputSample[1] = inputs[i][1]; double targetSample[]; ArrayResize(targetSample, 1); targetSample[0] = targets[i][0]; Net.FeedForward(inputSample); Net.BackProp(targetSample); } if(epoch % 100 == 0) { PrintFormat("Epoch: %d, Recent Average Error: %.4f", epoch, Net.GetRecentAverageError()); } if(Net.GetRecentAverageError() < InpTargetError && epoch > 100) { Print("Target error reached. Stopping early."); break; } } Print("--- Training Complete ---"); Print("--- Verifying Results ---"); Verify(0, 0); // Expect ~0 Verify(0, 1); // Expect ~1 Verify(1, 0); // Expect ~1 Verify(1, 1); // Expect ~0 // Save Model string filename = "XOR_Model.bin"; if(Net.Save(filename)) { Print("Model saved to ", filename); } // Test Load delete Net; Net = new CNeuralNet(topology); if(Net.Load(filename, topology)) { Print("Model loaded from ", filename); Print("--- Verifying Loaded Model ---"); Verify(1, 0); // Should still be ~1 } return(INIT_SUCCEEDED); } void Verify(double i1, double i2) { double inputs[]; ArrayResize(inputs, 2); inputs[0] = i1; inputs[1] = i2; Net.FeedForward(inputs); double results[]; Net.GetResults(results); PrintFormat("Input: %.0f, %.0f -> Output: %.4f", i1, i2, results[0]); } //+------------------------------------------------------------------+ //| Expert deinitialization function | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { if(CheckPointer(Net) != POINTER_INVALID) delete Net; } //+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTick() { } //+------------------------------------------------------------------+