Watch
1
0
Fork
You've already forked NeuroBook
0
forked from rosh/NeuroBook
NeuroBook/Scripts/perceptron/check_gradient_percp.mq5

265 lines
18 KiB
MQL5

2025-05-30 16:12:30 +02:00
<EFBFBD><EFBFBD>//+------------------------------------------------------------------+
//| Check_Gradient_percp.mq5 |
//| Copyright 2021, MetaQuotes Ltd. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2021, MetaQuotes Ltd."
#property link "https://www.mql5.com"
#property version "1.00"
#property script_show_inputs
//+------------------------------------------------------------------+
//| Connect the neural network library |
//+------------------------------------------------------------------+
#include "..\..\Include\realization\neuronnet.mqh"
CNet Net;
//+------------------------------------------------------------------+
//| External parameters for script operation |
//+------------------------------------------------------------------+
input int BarsToLine = 10; // Input data vector size
input bool UseOpenCL = false; // Use of OpenCL
input ENUM_ACTIVATION_FUNCTION HiddenActivation = AF_SWISH; // Hidden layer activation function
//+------------------------------------------------------------------+
//| Script program start |
//+------------------------------------------------------------------+
void OnStart()
{
//--- create a model
if(!CreateNet(Net))
return;
//--- create a buffer to read input data
CBufferType *pattern = new CBufferType();
if(!pattern)
{
PrintFormat("Error creating Pattern data array: %d", GetLastError());
return;
}
//--- generate random initial data
if(!pattern.BufferInit(1, BarsToLine))
return;
for(int i = 0; i < BarsToLine; i++)
pattern.m_mMatrix[0, i] = (TYPE)MathRand() / (TYPE)32767;
//--- run feed-forward and backpropagation passes to get analytical gradients
const TYPE delta = (TYPE)1.0e-5;
TYPE dd = 0;
CBufferType *init_pattern = new CBufferType();
init_pattern.m_mMatrix.Copy(pattern.m_mMatrix);
if(!Net.FeedForward(pattern))
{
PrintFormat("Error in FeedForward: %d", GetLastError());
return;
}
CBufferType *etalon_result = new CBufferType();
if(!Net.GetResults(etalon_result))
{
PrintFormat("Error in GetResult: %d", GetLastError());
return;
}
//--- create results buffer
CBufferType *target = new CBufferType();
if(!target)
{
PrintFormat("Error creating Pattern Target array: %d", GetLastError());
return;
}
//--- save obtained data into separate files
target.m_mMatrix.Copy(etalon_result.m_mMatrix);
target.m_mMatrix[0, 0] = etalon_result.m_mMatrix[0, 0] + delta;
if(!Net.Backpropagation(target))
{
PrintFormat("Error in Backpropagation: %d", GetLastError());
delete target;
delete etalon_result;
delete pattern;
delete init_pattern;
return;
}
CBufferType *input_gradient = Net.GetGradient(0);
CBufferType *weights = Net.GetWeights(1);
CBufferType *weights_gradient = Net.GetDeltaWeights(1);
if(UseOpenCL)
{
input_gradient.BufferRead();
weights.BufferRead();
weights_gradient.BufferRead();
}
//--- in a loop alternately change the elements of the initial data and compare
//--- empirical result with the value of the analytical method
for(int k = 0; k < BarsToLine; k++)
{
pattern.m_mMatrix.Copy(init_pattern.m_mMatrix);
pattern.m_mMatrix[0, k] = init_pattern.m_mMatrix[0, k] + delta;
if(!Net.FeedForward(pattern))
{
PrintFormat("Error in FeedForward: %d", GetLastError());
return;
}
if(!Net.GetResults(target))
{
PrintFormat("Error in GetResult: %d", GetLastError());
return;
}
TYPE d = target.At(0) - etalon_result.At(0);
pattern.m_mMatrix[0, k] = init_pattern.m_mMatrix[0, k] - delta;
if(!Net.FeedForward(pattern))
{
PrintFormat("Error in FeedForward: %d", GetLastError());
return;
}
if(!Net.GetResults(target))
{
PrintFormat("Error in GetResult: %d", GetLastError());
return;
}
d -= target.At(0) - etalon_result.At(0);
d /= 2;
dd += input_gradient.At(k) - d;
}
delete pattern;
//--- log the total value of deviations at the input data level
PrintFormat("Delta at input gradient between methods %.5e", dd / delta);
//--- reset the sum value and repeat the loop for weight gradients
dd = 0;
CBufferType *initial_weights = new CBufferType();
if(!initial_weights)
{
PrintFormat("Error creating benchmark weights buffer: %d", GetLastError());
return;
}
if(!initial_weights.m_mMatrix.Copy(weights.m_mMatrix))
{
PrintFormat("Error of copy weights to initial weights buffer: %d", GetLastError());
return;
}
for(uint k = 0; k < weights.Total(); k++)