神经网络变得轻松(第二部分):网络训练和测试

这篇具有很好参考价值的文章主要介绍了神经网络变得轻松(第二部分):网络训练和测试。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

概述

在上一篇名为神经网络变得轻松的文章中,我们曾研究过利用 赫兹量化交易软件配合完全连接的神经网络一起操作的 CNet 构造原理。 在本文中,我将演示一个示例,说明如何在 EA 中利用该类,并在实际条件下评估该类。

1. 定义问题

在开始创建智能交易系统之前,必须定义将为新神经网络设定的目标。 当然,金融市场上所有智能交易系统的共同目标是获利。 然而,此目的太笼统宽泛。赫兹量化交易软件需要为神经网络指定更具体的任务。 甚至,我们需要了解如何评估神经网络的未来结果。

另一个重要的时刻是,先前创建的 CNet 类使用了监督学习的原理,因此它需要标记数据作为训练集合。

如果您查看价格图表,自然会希望在价格峰值时执行交易操作,这可以通过标准的比尔·威廉姆斯(Bill Williams)分形指标来示意。 而指标的问题在于,它会判断 3 根烛条的峰值,且产生的信号始终会延迟 1 根烛条,而这可能会产生相反的信号。 如赫兹量化交易软件设置神经网络以判定第三根烛条形成之前的枢轴点,该怎么办? 这种方法至少会在交易方向移动有一根之前走势的烛条。

这是指训练集合:

  • 在正向递进中,我们会将当前行情状况输入到神经网络,并输出最后一根收盘烛条上提取的形成概率的评估。
  • 对于逆向递进中,在下一根烛条形成之后,我们将检查前一根烛条上是否存在分形,并将输入结果按权重调整。 

为了评估网络运算的结果,我们可以使用均方预测误差,正确的分形预测的百分比,和无法识别的分形的百分比。

现在我们需要判定哪些数据应输入到我们的神经网络中。 您还记得,当您尝试根据图表评估行情状况时所做的事情吗?

首先,建议交易新手从图表中直观评估趋势方向。 因此,我们必须将有关价格变动的信息数字化,并将其输入到神经网络中。 我建议输入有关的开盘价和收盘价、最高价和最低价、交易量和形成时间的数据。 

另一种判定趋势的流行方法是使用振荡器指标。 此类指标操作很方便,因为指标会输出标准化数据。 我决定为本次实验准备四个标准指标:RCI,CCI,ATR 和 MACD,所有指标均带采用标准参数。 我在选择指标及其参数时,没有进行任何其他分析。

有人可能会说利用指标是没有意义的,因为指标的数据是通过重新计算烛条的价格数据而建立的,我们已经将其输入到神经网络当中。 但这并非完全正确。 指标值是通过计算来自多根烛条的数据来判定的,从而可对所分析的样本进行一定程度的扩展。 神经网络训练过程将判定它们如何影响结果。

为了能够评估行情动态,我们在一定的历史时期内将全部信息输入到神经网络之中。

2. 神经网络模型项目

2.1. 判定输入层中神经元的数量

此处,赫兹量化交易软件需要知晓输入层中神经元的数量。 为此,请评估每根烛条上的初始信息,然后将其乘以分析历史记录的深度。

由于指标数据已经标准化,且指标缓冲区的相关数量已知,因此无需预处理指标数据(上述 4 个指标总共有 5 个值)。 因此,若要在输入层中接收这些指标,我们需要为每根所分析烛条创建 5 个神经元。

烛条价格数据的情况略有不同。 从图表直观地判定趋势方向和强度时,我们首先分析烛条方向和大小。 只有在此之后,当我们要判定趋势方向,和可能的枢轴点时,我们要注意所分析品种的价位。 因此,有必要在把该数据输入到神经网络之前对其进行标准化。 我个人输入了所述烛条的开盘价与收盘价、最高价和最低价的差值。 在这种方法中,定义三个神经元就足够了,其中第一个神经元的符号判定烛条方向。

有许多不同的资料论述了各种时间因素对货币波动的影响。 例如,季度线、周线和日线的动态差异,以及欧洲、美洲和亚洲的交易时段,均以不同的方式影响货币汇率。 若要分析这些因素,将烛条形成的月份、时刻和星期几输入进神经网络。 我特意将烛条形成的时间和日期分为几个部分,因为这可令神经网络能够泛化,并找到依赖性。

另外,我们来包含有关成交量的信息。 如果您的经纪商提供真实的交易量数据,则指明这些交易量;否则指定即时报价的交易量。

故此,为了应对每根烛条,我们需要 12 个神经元。 将此数字乘以所分析的历史深度,您可得到神经网络输入层的大小。

2.2. 设计隐藏层

下一步是准备神经网络的隐藏层。 网络结构(层数和神经元数)的选择是最困难的任务之一。 单层感知器善于类的线性分离。 双层网络可跟踪非线性边界。 三层网络可以描述复杂的多连接区域。 当我们增加层数时,功能类别会扩展,但这会导致收敛性变差,和训练成本增加。 每层当中,神经元的数量必须满足功能的预期变化。 实际上,非常简单的网络无法在实际条件下按要求的精度模拟行为,而过于复杂的网络不仅会重复训练目标函数,还有噪声。

在首篇文章中,我提到了 “5 个为什么” 方法。 现在,我建议继续此实验,并创建一个包含 4 个隐藏层的网络。 我将首个隐藏层中的神经元数量设置为 1000。 不过,也有可能根据分析周期的深度建立一些依赖关系。 遵照帕累托(Pareto)规则,我们将每个后续层中的神经元数量减少 70%。 此外,将遵循如下限制:隐藏层中的神经元数量不得少于 20。

2.3. 判定输出层中神经元的数量

输出层当中神经元的数量取决于任务,及其解决方案。 若要解决回归问题,只需要一个神经元就能产生期望值即可。 为了解决分类问题,我们需要与期望的类数量相等的神经元 - 每个神经元将为分配给每个类的原始对象生成概率。 而在实际中,对象的类别由最大概率判定。

对于我们的情况,我建议创建 2 个神经网络变体,并评估它们在实践中应对我们之问题的适用性。 在第一种情况下,输出层仅有一个神经元。 数值在 0.5...1.0 范围内与买入分形对应,而数值在 -0.5..-1.0 范围内与卖出信号对应,数值在 -0.5...0.5 范围内表示没有信号。 在此解决方案中,双曲正切用作激活函数 - 它的输出值范围为 -1.0 到 +1.0。

在第二种情况下,将在输出层中创建 3 个神经元(买、卖、无信号)。 在这个变体中,我们来训练神经网络,从而获得范围为 0.0...1.0 的结果。 在此,结果就是分形出现的概率。信号将依据最大概率来判定,并根据含有最高概率的神经元的索引来判定信号的方向。

3. 编程

3.1. 准备工作

现在,到编程的时候了。 首先,加入所需的函数库:

  • NeuroNet.mqh — 前一篇文章中创建神经网络的函数库
  • SymbolInfo.mqh — 接收品种数据的标准库
  • TimeSeries.mqh — 处理时间序列的标准库
  • Volumes.mqh — 接收交易量数据的标准库
  • Oscilators.mqh — 含有振荡器类的标准库
#include "NeuroNet.mqh"
#include <Trade\SymbolInfo.mqh>
#include <Indicators\TimeSeries.mqh>
#include <Indicators\Volumes.mqh>
#include <Indicators\Oscilators.mqh>

下一步是编写程序参数,通过它们来设置神经网络和指标参数。

//+------------------------------------------------------------------+
//|   input parameters                                               |
//+------------------------------------------------------------------+
input int                  StudyPeriod =  10;            //Study period, years
input uint                 HistoryBars =  20;            //Depth of history
ENUM_TIMEFRAMES            TimeFrame   =  PERIOD_CURRENT;
//---
input group                "---- RSI ----"
input int                  RSIPeriod   =  14;            //Period
input ENUM_APPLIED_PRICE   RSIPrice    =  PRICE_CLOSE;   //Applied price
//---
input group                "---- CCI ----"
input int                  CCIPeriod   =  14;            //Period
input ENUM_APPLIED_PRICE   CCIPrice    =  PRICE_TYPICAL; //Applied price
//---
input group                "---- ATR ----"
input int                  ATRPeriod   =  14;            //Period
//---
input group                "---- MACD ----"
input int                  FastPeriod  =  12;            //Fast
input int                  SlowPeriod  =  26;            //Slow
input int                  SignalPeriod=  9;             //Signal
input ENUM_APPLIED_PRICE   MACDPrice   =  PRICE_CLOSE;   //Applied price

接下来,声明全局变量 - 稍后会讲解它们的用法。

CSymbolInfo         *Symb;
CiOpen              *Open;
CiClose             *Close;
CiHigh              *High;
CiLow               *Low;
CiVolumes           *Volumes;
CiTime              *Time;
CNet                *Net;
CArrayDouble        *TempData;
CiRSI               *RSI;
CiCCI               *CCI;
CiATR               *ATR;
CiMACD              *MACD;
//---
double               dError;
double               dUndefine;
double               dForecast;
double               dPrevSignal;
datetime             dtStudied;
bool                 bEventStudy;

准备工作至此完成。 现在继续进行类的初始化。

3.2 初始化类

类的初始化将在 OnInit 函数中执行。 首先,我们创建处理品种的 CSymbolInfo 类的实例,并更新有关图表品种的数据。

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
   Symb=new CSymbolInfo();
   if(CheckPointer(Symb)==POINTER_INVALID || !Symb.Name(_Symbol))
      return INIT_FAILED;
   Symb.Refresh();

然后创建时间序列实例。 在您每次创建类实例时,请检查它是否已成功创建,并初始化。 如果发生错误,则以 INIT_FAILED 作为结果退出函数。

   Open=new CiOpen();
   if(CheckPointer(Open)==POINTER_INVALID || !Open.Create(Symb.Name(),TimeFrame))
      return INIT_FAILED;
//---
   Close=new CiClose();
   if(CheckPointer(Close)==POINTER_INVALID || !Close.Create(Symb.Name(),TimeFrame))
      return INIT_FAILED;
//---
   High=new CiHigh();
   if(CheckPointer(High)==POINTER_INVALID || !High.Create(Symb.Name(),TimeFrame))
      return INIT_FAILED;
//---
   Low=new CiLow();
   if(CheckPointer(Low)==POINTER_INVALID || !Low.Create(Symb.Name(),TimeFrame))
      return INIT_FAILED;
//---
   Volumes=new CiVolumes();
   if(CheckPointer(Volumes)==POINTER_INVALID || !Volumes.Create(Symb.Name(),TimeFrame,VOLUME_TICK))
      return INIT_FAILED;
//---
   Time=new CiTime();
   if(CheckPointer(Time)==POINTER_INVALID || !Time.Create(Symb.Name(),TimeFrame))
      return INIT_FAILED;

在此示例中采用了即时报价交易量。 若您希望采用真实交易量,则在调用 Volumes.Creare 方法时将 “VOLUME_TICK” 替换为 “VOLUME_REAL”。

在声明了时间序列之后,创建类的实例,从而以类似方式使用指标。

   RSI=new CiRSI();      
   if(CheckPointer(RSI)==POINTER_INVALID || !RSI.Create(Symb.Name(),TimeFrame,RSIPeriod,RSIPrice))
      return INIT_FAILED;
//---
   CCI=new CiCCI();      
   if(CheckPointer(CCI)==POINTER_INVALID || !CCI.Create(Symb.Name(),TimeFrame,CCIPeriod,CCIPrice))
      return INIT_FAILED;
//---
   ATR=new CiATR();      
   if(CheckPointer(ATR)==POINTER_INVALID || !ATR.Create(Symb.Name(),TimeFrame,ATRPeriod))
      return INIT_FAILED;
//---
   MACD=new CiMACD();      
   if(CheckPointer(MACD)==POINTER_INVALID || !MACD.Create(Symb.Name(),TimeFrame,FastPeriod,SlowPeriod,SignalPeriod,MACDPrice))
      return INIT_FAILED;

现在我们可以直接利用神经网络类运作了。 首先,创建一个类的实例。 在 CNet 类初始化期间,构造函数参数会将引用传递给含有网络结构规范的数组。 请注意,网络训练过程当中会消耗计算资源,且会花费大量时间。 因此,每次重启之后,网络都是不正确的,需要训练。 此处是我如何操作的:首先,我在声明网络实例时未指定结构,然后尝试从本地存储加载先前已训练过的网络(文件名在 #define 中提供)。

#define FileName        Symb.Name()+"_"+EnumToString((ENUM_TIMEFRAMES)Period())+"_"+IntegerToString(HistoryBars,3)+"fr_ea"
...
...
...
...
   Net=new CNet(NULL);
   ResetLastError();
   if(CheckPointer(Net)==POINTER_INVALID || !Net.Load(FileName+".nnw",dError,dUndefine,dForecast,dtStudied,false))
     {
      printf("%s - %d -> Error of read %s prev Net %d",__FUNCTION__,__LINE__,FileName+".nnw",GetLastError());

如果无法加载先前已训练的数据,则会将消息打印到日志,指示错误代码,然后开始创建新的未经训练的网络。 首先,声明 CArrayInt 类的实例,并指定神经网络的结构。 元素的数量表示神经网络层的数量,而元素的数值表示相应层中神经元的数量。

      CArrayInt *Topology=new CArrayInt();
      if(CheckPointer(Topology)==POINTER_INVALID)
         return INIT_FAILED;

正如早前所提到的,我们在输入层中需要 12 个神经元来应对每根烛条。 因此,在第一个数组元素中,用 12 乘以所分析历史记录的深度。

      if(!Topology.Add(HistoryBars*12))
         return INIT_FAILED;

然后定义隐藏层。 我们已判定在第一个隐藏层中将包括 4 个含 1000 个神经元的隐藏层。 然后,在后续的每个层中,神经元的数量将减少 70%,但每一层至少含有 20 个神经元。 数据将循环添加到数组当中。

      int n=1000;
      bool result=true;
      for(int i=0;(i<4 && result);i++)
        {
         result=(Topology.Add(n) && result);
         n=(int)MathMax(n*0.3,20);
        }
      if(!result)
        {
         delete Topology;
         return INIT_FAILED;
        }

在输出层中指示 1 来构建回归模型。

      if(!Topology.Add(1))
         return INIT_FAILED;

如果我们采用分类模型,则需要为输出神经元指定 3。

接下来,删除先前创建的 CNet 类实例,并创建一个新实例,并在其中指明要创建的神经网络的结构。 创建新的神经网络实例后,删除网络结构的类,因为以后不会再用到它。

      delete Net;
      Net=new CNet(Topology);
      delete Topology;
      if(CheckPointer(Net)==POINTER_INVALID)
         return INIT_FAILED;

设置变量的初始值,以便收集统计数据:

  • dError - 标准偏差(误差)
  • dUndefine - 未定义分形的百分比
  • dForecast - 正确预测分形的百分比
  • dtStudied — 最后一根已训练烛条的日期。
      dError=-1;
      dUndefine=0;
      dForecast=0;
      dtStudied=0;
     }

不要忘记,只当没有先前训练过的神经网络,无需从本地存储加载的情况下,我们才需要设置神经网络结构,创建神经网络类的新实例,并初始化统计变量。
在 OnInit 函数的末尾,创建 CArrayDouble() 类的实例,该实例用来与神经网络交换数据,并开始神经网络训练过程。

我想在这里分享另一种解决方案。 MQL5 不支持异步函数调用。 如果我们从 OnInit 函数显式调用学习函数,则终端将误认为程序初始化过程尚未完成,直到训练完成。 这就是为什么我们要创建一个自定义事件,从 OnChartEvent 函数调用该训练函数,替代直接调用该函数的原因。 创建事件时,请在 lparam 参数中指定训练开始日期。 这种方法可令我们调用函数,并完成 OnInit 函数。

神经网络变得轻松(第二部分):网络训练和测试,神经网络,网络,人工智能

 文章来源地址https://www.toymoban.com/news/detail-560645.html

                    

到了这里,关于神经网络变得轻松(第二部分):网络训练和测试的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 自定义的卷积神经网络模型CNN,对图片进行分类并使用图片进行测试模型-适合入门,从模型到训练再到测试,开源项目

    自定义的卷积神经网络模型CNN,对图片进行分类并使用图片进行测试模型-适合入门,从模型到训练再到测试:开源项目 开源项目完整代码及基础教程: 资料获取,关注公众号【一起来学习哟】获取 CNN模型: 1.导入必要的库和模块: torch:PyTorch深度学习框架。 torchvision:P

    2024年02月06日
    浏览(46)
  • 神经网络训练算法的调用,神经网络中的矩阵运算

    反向传播算法(Backpropagation)是目前用来训练人工神经网络(Artificial Neural Network,ANN)的最常用且最有效的算法。其主要思想是: (1)将训练集数据输入到ANN的输入层,经过隐藏层,最后达到输出层并输出结果,这是ANN的前向传播过程; (2)由于ANN的输出结果与实际结果

    2023年04月08日
    浏览(53)
  • openmv云端训练神经网络自动生成openmv的神经网络模型

    打开openmv工具栏如图所示,点击新数据集  弹出如下界面,这里我选择的是我自己新建的new date文件夹,你们选择自己新建的文件夹即可  接下来我们点击左边红框框起来的地方,可得到中间那个界面,可自己创建名称  左上角就是我创建好的两个,接下来我们点击下面红框

    2024年02月12日
    浏览(40)
  • 利用GPU训练神经网络

    确实训练得要快多了 如果不确定是否有GPU,这种写法更好 判断一下,如果有再执行;这样才在CPU或者GPU上都能跑,优先GPU 修改部分代码 其实模型和损失函数不需另外赋值,但训练和测试部分需要

    2024年01月16日
    浏览(37)
  • 神经网络小结:训练的全过程

    这一节我们主要是将之前的知识穿起来,形成一个整体。如果之前的没看过可以回翻一下专栏。但是在整体回归之前,我们还需要学习一个小知识点——随机初始化 在神经网络中,我们大致的训练流程就是:通过前向传播得出当前 θ theta θ 下的假设结果,使用代价函数对比

    2024年02月10日
    浏览(44)
  • 机器学习18:训练神经网络-最佳实践

    在【 机器学习17 】中, 笔者介绍了 反向传播算法。反向传播算法 是神经网络最常见的训练算法。它使得梯度下降对于多层神经网络来说是可行的。 TensorFlow 可以自动处理反向传播,因此我们不需要深入了解该算法。要了解其工作原理,请阅读 【 机器学习17

    2024年02月12日
    浏览(48)
  • 神经网络的训练过程、常见的训练算法、如何避免过拟合

    神经网络的训练是深度学习中的核心问题之一。神经网络的训练过程是指通过输入训练数据,不断调整神经网络的参数,使其输出结果更加接近于实际值的过程。本文将介绍神经网络的训练过程、常见的训练算法以及如何避免过拟合等问题。 神经网络的训练过程通常包括以下

    2024年02月05日
    浏览(45)
  • [pytorch]手动构建一个神经网络并且训练

    上一篇博客全都是说明类型的,实际代码能不能跑起来两说,谨慎观看.本文中直接使用fashions数据实现softmax的简单训练并且完成结果输出.实现一个预测并且观测到输出结果. 并且更重要的是,在这里对一些训练的过程,数据的形式,以及我们在softmax中主要做什么以及怎么做来进行说

    2024年02月05日
    浏览(34)
  • 机器学习17:训练神经网络-反向传播算法

    反向传播算法对于快速训练大型神经网络至关重要。本文将介绍算法的工作原理。 目录 1.简单的神经网络 2.激活函数 3.错误函数 4.正向传播 4.1 更新隐藏层 5.反向传播 5.1 求导数

    2024年02月12日
    浏览(54)
  • 如何看待第三代神经网络SNN?详解脉冲神经网络的架构原理、数据集和训练方法

    作者丨科技猛兽 编辑丨极市平台 本文首发于极市平台公众号,转载请获得授权并标明出处。 1 脉冲神经网络简介 2 脉冲神经网络原理 3 脉冲神经网络数据集 4 脉冲神经网络训练方法 5 脉冲神经网络评价指标 脉冲神经网络 (SNN) 属于 第三代神经网络模型 ,实现了更高级的生物

    2024年02月08日
    浏览(65)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包