构建MQL5中的首个神经网络模型
立即解锁
发布时间: 2025-09-01 00:57:01 阅读量: 5 订阅数: 11 AIGC 

### 构建MQL5中的首个神经网络模型
在MQL5中构建神经网络模型是一个复杂且有挑战性的过程。本文将详细介绍如何创建训练和测试样本,以及如何验证梯度分布的正确性,以确保误差反向传播算法的正确实现。
#### 1. 创建训练和测试样本
我们需要将未归一化的初始数据训练样本写入`study_data_not_norm.csv`和`test_data_not_norm.csv`文件。同时,将未归一化的源数据训练数据集写入`study_data.csv`和`test_data.csv`文件。为了创建这些训练数据集,我们将使用`create_initial_data.mq5`文件中的脚本。运行该脚本两次,收集相同的历史数据,但需要更改数据记录的文件名和“数据归一化标志”。
#### 2. 梯度分布验证
在直接进行神经网络训练之前,我们需要检查误差梯度在整个神经网络中的分布是否正确。这是因为误差梯度决定了每个权重的变化幅度和方向,其实现的正确性会显著影响神经网络训练的整体结果。
为了验证梯度分布的正确性,我们可以使用两种方法来确定函数的导数:
- **解析法**:基于函数的一阶导数来确定梯度,该方法在我们的反向传播方法中实现。
- **经验法**:在其他条件相同的情况下,改变一个指标的值,并评估其对函数最终结果的影响。
从几何角度来看,梯度是函数图像在当前点处切线的斜率,它表示参数值变化时函数值的变化情况。
经验法的基本原理是通过两次简单迭代找到函数图像上的两个点,从而近似得到切线。具体步骤如下:
1. 给参数的当前值加上一个小数字,在不改变其他参数的情况下计算函数值,得到第一个点。
2. 从当前值中减去相同的数字,得到第二个点。通过这两个点的直线将以一定的误差近似所需的切线,改变参数的数字越小,误差越小。
然而,经验法虽然简单,但隐藏了大量操作:
1. 执行前向传播并保存结果。
2. 略微增加一个参数,重复前向传播并保存结果。
3. 略微减小一个参数,重复前向传播并保存结果。
4. 根据找到的点构建直线并确定其斜率。
这些步骤仅用于确定一个参数在一个步骤的梯度。如果在训练一个仅包含一百个参数的神经网络时使用此方法,将需要大量的时间和计算资源。因此,我们通常使用解析法,它可以大大减少必要的迭代次数和执行时间。
我们可以构建一个小型神经网络,比较两种方法的结果。如果结果相似,则表明解析法算法的实现是正确的;如果结果存在显著差异,则需要重新评估解析法中实现的反向传播算法。
#### 3. 创建验证脚本
为了实现上述想法,我们创建了`check_gradient_percp.mq5`脚本,该脚本接收三个外部参数:
- 初始数据向量的大小
- 使用OpenCL技术的标志
- 隐藏层的激活函数
由于我们只检查反向传播方法的正确性,因此可以使用随机值向量作为初始数据。以下是脚本的外部参数定义:
```cpp
//+------------------------------------------------------------------+
//| External parameters for the script |
//+------------------------------------------------------------------+
// Source data vector size
input int BarsToLine = 40;
// Use OpenCL
input bool UseOpenCL = true;
// Hidden Layer Activation Function
input ENUM_ACTIVATION_FUNCTION HiddenActivation = AF_SWISH;
```
在脚本的全局作用域中,我们连接神经网络库并声明一个神经网络对象:
```cpp
//+------------------------------------------------------------------+
//| Connecting the Neural Network Library |
//+------------------------------------------------------------------+
#include "..\..\..\Include\NeuroNetworksBook\realization\neuronnet.mqh"
CNet Net;
```
#### 4. 定义神经网络架构
为了创建神经网络模型,我们将模型创建封装在一个单独的过程`CreateNet`中。该过程接收一个指向正在创建的神经网络模型对象的指针。
我们创建一个三层神经网络来检查误差传播算法的正确性,所有层都基于`CNeuronBase`类构建。具体步骤如下:
1. **创建源数据层**:该层的大小由用户在外部参数`BarsToLine`中指定,不使用激活函数和权重更新方法。
```cpp
//--- source data layer
CLayerDescription *descr = new CLayerDescription();
if(!descr)
{
PrintFormat("Error creating CLayerDescription: %d", GetLastError());
delete layers;
return false;
}
descr.type = defNeuronBase;
descr.count = BarsToLine;
descr.window = 0;
descr.activation = AF_NONE;
descr.optimization = None;
if(!layers.Add(descr))
{
PrintFormat("Error adding layer: %d", GetLastError());
delete layers;
delete descr;
return false;
}
```
2. **创建隐藏层**:神经元数量设置为输入数据层的10倍,该层使用用户在脚本外部参数`HiddenActivation`中指定的激活函数。
```cpp
//--- hidden layer
descr = new CLayerDescription();
if(!descr)
{
PrintFormat("Error creating CLayerDescription: %d", GetLastError());
delete layers;
return false;
}
descr.type = defNeuronBase;
descr.count = 10 * BarsToLine;
descr.activation = HiddenActivation;
descr.optimization = Adam;
descr.activation_params[0] = (TYPE)1;
descr.activation_params[1] = (TYPE)0;
if(!layers.Add(descr))
{
PrintFormat("Error adding layer: %d", GetLastError());
delete layers;
delete descr;
return false;
}
```
3. **创建结果层**:包含一个输出神经元和线性激活函数。
```cpp
//--- result layer
descr = new CLayerDescription();
if(!descr)
{
PrintFormat("Error creating CLayerDescription: %d", GetLastError());
delete layers;
return false;
}
descr.type = defNeuronBase;
descr.count = 1;
descr.activation = AF_LINEAR;
descr.optimizati
```
0
0
复制全文
相关推荐










