为交易设计的训练神经网络准备数据的一个基本问题是准备必要的输入数据。例如,当我们使用十几个指标时,请考虑这种情况。这些指标可能代表一组若干信息图表。如果我们将这些指标计算到一定的深度,那么结果将多达100个条目,在某些情况下甚至更多。我们能用计算机视觉使神经网络训练更容易吗?为了解决这个问题,让我们使用卷积神经网络,这是经常用来解决分类和识别问题。
在本文中,我们将使用卷积神经网络,其架构如图所示。该方案给出了构造卷积神经网络(CNN)的一般原理。
在这种情况下,我们有:
如果你是新的卷积神经网络,不要担心看似繁琐和复杂的建设。给定结构的神经网络是自动建立的,您只需要设置主要参数。
在准备一组图像之前,先定义神经网络的用途。理想情况下,在轴枢点上训练网络会很好。根据这个目的,我们需要用最后一个极值柱做截图。然而,这个实验没有实际价值。这就是为什么我们将使用另一组图像。此外,还可以使用不同的数组进行实验,包括上面提到的数组。这也可能为神经网络在解决基于图像的分类任务时的效率提供额外的证据。在连续时间序列上获得的神经网络响应需要额外的优化。
让我们不要把实验复杂化,集中在两类图像上:
出于神经网络训练的目的,任何方向的移动都将被确定为价格在趋势方向上达到新的极值。此时将制作图表截图。趋势反转时刻对网络训练也很重要。当价格达到每日高点或低点时,还将制作图表截图。
在开始操作之前,我们需要准备图表外观。使用 CNN.tpl 模板。把它保存到 \AppData\Roaming\MetaQuotes\Terminal\D0E8209F77C8CF37AD8BF550E51FF075\MQL5\Profiles\Templates.
在图表属性中将文本定义为“White”。
也可以附加任何其他指标,我随意拿了这些指标。还建议根据您的硬件功能找到最佳图表大小。
使用以下脚本创建图像数组。
//+------------------------------------------------------------------+ //| CNNet.mq5 | //| Copyright 2021, Andrey Dibrov. | //| https://www.mql5.com/en/users/tomcat66 | //+------------------------------------------------------------------+ #property copyright "Copyright 2021, Andrey Dibrov." #property link "https://www.mql5.com/en/users/tomcat66" #property version "1.00" #property strict #property script_show_inputs input string Date="2017.01.02 00:00"; input string DateOut="2018.12.13 23:00"; input string DateTest="2019.01.02 00:00"; input string Dataset="Train"; string Date1; int count,countB,countS; int day; double DibMin; double DibMax; int HandleDate; long WIDTH; long HEIGHT; //+------------------------------------------------------------------+ //| Script program start function | //+------------------------------------------------------------------+ void OnStart() { //--- MqlDateTime stm; ChartSetInteger(0,CHART_SHIFT,false); ChartSetInteger(0,CHART_AUTOSCROLL,false); ChartSetInteger(0,CHART_SHOW_OBJECT_DESCR,false); WIDTH=ChartGetInteger(0,CHART_WIDTH_IN_PIXELS); ChartSetInteger(0,CHART_SHOW_PRICE_SCALE,false); if(Dataset=="Test") { HandleDate=FileOpen(Symbol()+"Date.csv",FILE_CSV|FILE_READ|FILE_WRITE|FILE_ANSI,";"); ChartNavigate(0,CHART_END,-(iBarShift(NULL,PERIOD_H1,StringToTime(DateTest)))); Sleep(1000); for(int i=iBarShift(NULL,PERIOD_H1,StringToTime(DateTest)); i>0; i--) { Date1=TimeToString(iTime(NULL,PERIOD_H1,i)); if(DateTest<=Date1) { if(ChartNavigate(0,CHART_END,-i)) { Sleep(20); if(ChartScreenShot(0, (string)count + ".png", (int)WIDTH, (int)WIDTH, ALIGN_LEFT)) { FileWrite(HandleDate,TimeToString(iTime(NULL,PERIOD_H1,i))); count++; Sleep(20); } } } } } if(Dataset=="Train") { ChartNavigate(0,CHART_END,-iBarShift(NULL,PERIOD_H1,StringToTime(Date))); Sleep(1000); for(int i=iBarShift(NULL,PERIOD_H1,StringToTime(Date)); i>=iBarShift(NULL,PERIOD_H1,StringToTime(DateOut)); i--) { TimeToStruct(iTime(NULL,PERIOD_H1,i),stm); Date1=TimeToString(iTime(NULL,PERIOD_H1,i)); if(DateOut>=Date1 && Date<=Date1) { if(ChartNavigate(0,CHART_END,-i)) { Sleep(20); if(day != stm.day) { FileCopy("Sell" + (string)countS + ".png", 0, "Buy" + (string)(countB+1) + ".png", FILE_REWRITE); FileDelete("Sell" + (string)countS + ".png", 0); FileCopy("Buy" + (string)countB + ".png", 0, "Sell" + (string)(countS+1) + ".png", FILE_REWRITE); FileDelete("Buy" + (string)countB + ".png", 0); countB ++; countS ++; } day = stm.day; if(stm.hour == 0) { DibMin = iOpen(NULL, PERIOD_H1, i); DibMax = iOpen(NULL, PERIOD_H1, i); } if(iLow(NULL, PERIOD_H1, i+1) < DibMin) { DibMin = iLow(NULL, PERIOD_H1, i+1); countS ++; ChartScreenShot(0, "Sell" + (string)countS + ".png", (int)WIDTH, (int)WIDTH, ALIGN_LEFT); } if(iHigh(NULL, PERIOD_H1, i+1) > DibMax) { DibMax = iHigh(NULL, PERIOD_H1, i+1); countB ++; ChartScreenShot(0, "Buy" +(string)countB + ".png", (int)WIDTH, (int)WIDTH, ALIGN_LEFT); } Sleep(20); } } else break; } } }
脚本在两种模式下工作:“Train”-创建一个用于训练的图像数组,“Test”-创建一个用于获取神经网络响应的图像数组,根据该数组将生成一个指标。此外,该指标将用于优化交易策略。
让我们以“Train”模式运行脚本。
变量“Date”- 样本的初始数据,将在其中选择用于训练的图像。"DateOut' — 选择用于训练的图像的采样周期的结束日期。"DateTest" — 从神经网络中选择图像以获得每小时响应的开始日期。结束日期将是脚本启动时间。
一系列买入。。。卖出。。。图像将保存在数据目录的…\MQL5\Files文件夹中。图片总数为6125张。
接下来,为训练、验证和测试集准备目录。为方便起见,在桌面上创建“CNN”文件夹,并在其中创建三个文件夹-“Train”、“Val”、“Test”。
在“Train”和“Val”目录中,创建子目录“Buy”和“Sell”。在“Test”下创建一个子目录“Resp”。
从文件夹..\MQL5\Files中,剪切所有文件“Buy…”并将其粘贴到…\Train\Buy。我们有3139张图片。对“Sell…”重复相同的步骤,并将其添加到…\Train\Sell。这里有2986张图片。从文件夹“Buy”和“Sell”,削减30%的最后(有最高的数字)图像和过去他们的相应子文件夹下的“Val”。
我们现在拥有的
我们已经准备了一组图像用于训练网络。我有449x449像素的图像。
准备一组图像进行测试。以“Test”模式运行脚本。
一组连续的每小时屏幕截图将保存到 ...\MQL5\文件中。它们现在是12558个。不要将它们分开或分组,因为神经网络应该自己进行分组。更准确地说,网络应该显示图像与网络训练条件相对应的概率。向上和向下移动。向下移动并向上翻转。
将这些文件剪切粘贴到 ...CNN\Test\Resp。
我们准备了一组图像,用于测试响应和优化策略。日期和时间为 EURUSDDate 的文件,保留在..\MQL5\files下,应该移动到CNN文件夹。
我想指出 MetaTrader 5 的一个特殊特性。在策略测试器中使用专家顾问来准备一组图像将更加方便和可靠。但是,MetaTrader 5不提供在策略测试器中创建屏幕截图的功能。无论如何,这个特定功能不会影响交易机器人的创建。
我们将使用 Anaconda 环境处理卷积网络。它应该配置为与 CPU 和 GPU(如果你有一个NVIDIA显卡)一起工作。这个显卡是加快学习过程所需要的。尽管如此,它还是对创建神经网络体系结构施加了一些限制——依赖于显卡的RAM数量。但学习速度明显提高。例如,在我的例子中,CPU上的一个训练 epoch 持续20分钟,而GPU上需要1-2分钟。如果网络是40个 epoch 的训练,那么我将需要13和1.5个小时。GPU的使用可以大大加快研究阶段的神经网络搜索过程。
安装 tensorflow gpu, 键入命令 conda create -n PythonGPU python=3.6 tensorflow-gpu. 请注意,应为 python 3.6 安装 tensorflow gpu。
安装 keras gpu, 键入命令 conda install -c anaconda keras-gpu.
在 Python GPU 环境中安装用于编程的 Jupyter 接口。CPU Jupyter 在安装 Anaconda 时已经安装好了。键入命令 - conda install jupyter.
安装另外两个库, Pandas 和 Pillow - conda install -c anaconda pandas. 然后 - conda install pillow. 如果您不打算使用显卡,也应该为CPU安装这些库。
让我们探讨一下程序代码的每个部分。
首先加载必要的神经网络库模块。
from tensorflow.python.keras.preprocessing.image import ImageDataGenerator from tensorflow.python.keras.models import Sequential from tensorflow.python.keras.layers import Conv2D, MaxPooling2D from tensorflow.python.keras.layers import Activation, Dropout, Flatten, Dense from tensorflow.keras.callbacks import ModelCheckpoint from tensorflow.keras.models import load_model
然后设置所需的超参数。
# Directory with data for training train_dir = 'train' # Directory with data for validation val_dir = 'val' # Image dimensions img_width, img_height = 449, 449 # Image-based tensor dimension for input to the neural network # backend Tensorflow, channels_last input_shape = (img_width, img_height, 3) # Number of epochs epochs = 20 # Mini-sample size batch_size = 7 # Number of images for training nb_train_samples = 4289 # Number of images for validation nb_validation_samples = 1836 # Number of images for testing #nb_test_samples = 3736
让我们创建网络架构。
这个架构的例子可以很容易地更新-我们可以增加层的数量和它们的大小,根据序列改变它们的位置,改变卷积核的维数,修改激活函数和使用完全连接的层。然而,这里出现了一个难题:当使用GPU时,为了增加神经网络的结构,有必要增加显卡的RAM。或者,应该减小图像大小。否则,我们会花很多时间使用CPU。
model = Sequential() model.add(Conv2D(96, (3, 3), input_shape=input_shape)) model.add(Activation('relu')) model.add(MaxPooling2D(pool_size=(2, 2))) model.add(Conv2D(32, (3, 3))) model.add(Activation('relu')) model.add(MaxPooling2D(pool_size=(2, 2))) model.add(Conv2D(16, (3, 3))) model.add(Activation('relu')) model.add(MaxPooling2D(pool_size=(2, 2))) model.add(Flatten()) model.add(Dense(64)) model.add(Activation('relu')) model.add(Dropout(0.5)) model.add(Dense(1)) model.add(Activation('sigmoid'))
编译神经网络。使用偏差函数:二进制交叉熵(binary-crossentropy)。在本例中,我们将使用由两个类组成的响应,理想情况下,这两个类的值应该是0或1。但是,实际值将从0到1分布。选择梯度下降(Gradient Descent)优化器。它似乎是最适合神经网络训练的。选择准确度指标,即正确答案的百分比。
model.compile(loss='binary_crossentropy', optimizer='sgd', metrics=['accuracy'])
对图像像素强度数据进行归一化处理。
datagen = ImageDataGenerator(rescale=1. / 255)
使用Keras生成器从磁盘读取数据,并为神经网络创建训练和验证图像阵列。同样, class_mode 是 'binary'. 将 Shuffle 设置为“False”。这样,图像打乱被禁用。
train_generator = datagen.flow_from_directory( train_dir, target_size=(img_width, img_height), batch_size=batch_size, class_mode='binary', shuffle=False) val_generator = datagen.flow_from_directory( val_dir, target_size=(img_width, img_height), batch_size=batch_size, class_mode='binary', shuffle=False)
回调函数在每个历元后保存训练好的神经网络。这允许根据错误值和命中率选择最合适的网络。
callbacks = [ModelCheckpoint('cnn_Open{epoch:1d}.hdf5')]
现在,进行网络训练。
model.fit( train_generator, steps_per_epoch=nb_train_samples // batch_size, epochs=epochs, validation_data=val_generator, validation_steps=nb_validation_samples // batch_size, callbacks=callbacks)
12. 如图所示运行程序。
如果前面的步骤已经正确执行,神经网络将开始学习。
After the end of the training process, 20 trained neural networks will appear under the CNN folder.
Let us view training results and select a neural network for further use.
乍一看,在第18个epoch时,神经网络的学习错误率为30%,正确率为85%。然而,当在验证集上运行神经网络时,我们看到错误增加,正确答案的百分比下降。所以,我们应该选择一个在第11 epoch 训练的网络。它在验证集有最合适的结果:val_loss=0.6607 和 val_accuracy=0.6129。理想情况下,误差值应趋于0(或至少不超过35-40%),而精度应接近1(至少不低于55-60%)。在这种情况下,可以省略优化,也可以通过使用最小参数来提高交易质量。即使有了这些训练结果,也有可能建立一个有利可图的交易系统。
现在让我们来看看上述工作是否有实际意义。
在不支持GPU的设置下运行 Jupyter Notebook 并从CNN目录中打开Test.jpynb。
让我们看一下代码块。
首先加载必要的神经网络库模块。
from tensorflow.python.keras.preprocessing.image import ImageDataGenerator from tensorflow.python.keras.models import Sequential from tensorflow.python.keras.layers import Conv2D, MaxPooling2D from tensorflow.python.keras.layers import Activation, Dropout, Flatten, Dense from tensorflow.keras.callbacks import ModelCheckpoint from tensorflow.keras.models import load_model import pandas as pd
设置所需的参数。
predict_dir = 'Test' img_width, img_height = 449, 449 nb_predict_samples = 12558
从文件中读取测试图像的数据和时间。
Date=pd.read_csv('EURUSDDate.csv', delimiter=';',header=None)
加载第11 epoch 后保存的神经网络。
model=load_model('cnn_Open11.hdf5')
规范化图片。
datagen = ImageDataGenerator(rescale=1. / 255)
使用生成器从磁盘读取数据。
predict_generator = datagen.flow_from_directory( predict_dir, target_size=(img_width, img_height), shuffle=False)
从神经网络得到响应。
indicator=model.predict(predict_generator, nb_predict_samples )
显示结果。获得反馈的过程需要很多时间,所以下面是一个过程完成的通知。
print(indicator)
将得到的结果保存到文件中。
Date=pd.DataFrame(Date) Date['0'] =indicator Date.to_csv('Indicator.csv',index=False, header=False,sep=';')
运行程序,完成后 Indicator.csv 文件将在CNN目录下创建。
把它移动到 C:\Users\...\AppData\Roaming\MetaQuotes\Terminal\Common\Files.
在 EURUSD H1 图表上运行 NWI 指标.
//+------------------------------------------------------------------+ //| NWI.mq5 | //| Copyright © 2019, Andrey Dibrov. | //+------------------------------------------------------------------+ #property copyright "Copyright © 2019, Andrey Dibrov." #property link "https://www.mql5.com/en/users/tomcat66" #property version "1.00" #property indicator_separate_window #property indicator_buffers 2 #property indicator_plots 2 #property indicator_type1 DRAW_LINE #property indicator_type2 DRAW_LINE #property indicator_color1 Red #property indicator_color2 DodgerBlue int Handle; int i; int h; input int Period=5; double ExtBuffer[]; double SignBuffer[]; datetime Date1; datetime Date0; string File_Name="Indicator.csv"; //+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ void OnInit() { SetIndexBuffer(0,ExtBuffer,INDICATOR_DATA); SetIndexBuffer(1,SignBuffer,INDICATOR_DATA); IndicatorSetInteger(INDICATOR_DIGITS,5); Handle=FileOpen(File_Name,FILE_CSV|FILE_SHARE_READ|FILE_ANSI|FILE_COMMON,";"); //FileClose(Handle); } //+------------------------------------------------------------------+ //| Relative Strength Index | //+------------------------------------------------------------------+ int OnCalculate(const int rates_total, const int prev_calculated, const int begin, const double &price[]) { MqlDateTime stm; Date0=StringToTime(FileReadString(Handle)); i=iBarShift(NULL,PERIOD_H1,Date0,false); Handle=FileOpen(File_Name,FILE_CSV|FILE_SHARE_READ|FILE_ANSI|FILE_COMMON,";"); ArraySetAsSeries(ExtBuffer,true); ArraySetAsSeries(SignBuffer,true); while(!FileIsEnding(Handle) && !IsStopped()) { Date1=StringToTime(FileReadString(Handle)); ExtBuffer[i]=StringToDouble(FileReadString(Handle)); h=Period-1; if(i>=0) { while(h>=0) { SignBuffer[i]=SignBuffer[i]+ExtBuffer[i+h]; h--; } } SignBuffer[i]=SignBuffer[i]/Period; TimeToStruct(Date1,stm); i--; } FileClose(Handle); return(rates_total); } //+------------------------------------------------------------------+
为简单起见,我们将使用主指示线与简单平均线的交叉来解释网络响应。使用 TestCNN 专家顾问.
//+------------------------------------------------------------------+ //| TestCNN.mq5 | //| Copyright © 2019, Andrey Dibrov. | //+------------------------------------------------------------------+ #property copyright " Copyright © 2019, Andrey Dibrov." #property link "https://www.mql5.com/en/users/tomcat66" #property version "1.00" #property strict #include<Trade\Trade.mqh> CTrade trade; input int Period=5; input int H1; input int H2; input int H3; input int H4; input int LossBuy; input int ProfitBuy; input int LossSell; input int ProfitSell; ulong TicketBuy1; ulong TicketSell0; datetime Count; double Per; double Buf_0[]; double Buf_1[]; bool send1; bool send0; int h=4; int k; int K; int bars; int Handle; //+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ int OnInit() { //--- Handle=FileOpen("Indicator.csv",FILE_CSV|FILE_SHARE_READ|FILE_ANSI|FILE_COMMON,";"); while(!FileIsEnding(Handle)&& !IsStopped()) { StringToTime(FileReadString(Handle)); bars++; } FileClose(Handle); ArrayResize(Buf_0,bars); ArrayResize(Buf_1,bars); Handle=FileOpen("Indicator.csv",FILE_CSV|FILE_SHARE_READ|FILE_ANSI|FILE_COMMON,";"); while(!FileIsEnding(Handle)&& !IsStopped()) { Count=StringToTime(FileReadString(Handle)); Buf_0[k]=StringToDouble(FileReadString(Handle)); h=Period-1; if(k>=h) { while(h>=0) { Buf_1[k]=Buf_1[k]+Buf_0[k-h]; h--; } Buf_1[k]=Buf_1[k]/Period; } k++; } FileClose(Handle); int deviation=10; trade.SetDeviationInPoints(deviation); trade.SetTypeFilling(ORDER_FILLING_RETURN); trade.SetAsyncMode(true); //--- return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Expert deinitialization function | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { //--- } //+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTick() { //--- MqlDateTime stm; TimeToStruct(TimeCurrent(),stm); int digits=(int)SymbolInfoInteger(_Symbol,SYMBOL_DIGITS); double point=SymbolInfoDouble(_Symbol,SYMBOL_POINT); double PriceAsk=SymbolInfoDouble(_Symbol,SYMBOL_ASK); double PriceBid=SymbolInfoDouble(_Symbol,SYMBOL_BID); double SL1=NormalizeDouble(PriceBid-LossBuy*point,digits); double TP1=NormalizeDouble(PriceAsk+ProfitBuy*point,digits); double SL0=NormalizeDouble(PriceAsk+LossSell*point,digits); double TP0=NormalizeDouble(PriceBid-ProfitSell*point,digits); if(LossBuy==0) SL1=0; if(ProfitBuy==0) TP1=0; if(LossSell==0) SL0=0; if(ProfitSell==0) TP0=0; //---------Buy1 if(send1==false && K>0 && Buf_0[K-1]>Buf_1[K-1] && Buf_0[K]<Buf_1[K] && iLow(NULL,PERIOD_H1,1)<iLow(NULL,PERIOD_H1,2) && stm.hour>H1 && stm.hour<H2 && H1<H2) { send1=trade.PositionOpen(_Symbol,ORDER_TYPE_BUY,1,PriceAsk,SL1,TP1); TicketBuy1 = trade.ResultDeal(); } if(send1==true && K>0 && Buf_0[K-1]<Buf_1[K-1] && Buf_0[K]>Buf_1[K] && iHigh(NULL,PERIOD_H1,1)>iHigh(NULL,PERIOD_H1,2)) { trade.PositionClose(TicketBuy1); send1=false; } //---------Sell0 if(send0==false && K>0 && Buf_0[K-1]<Buf_1[K-1] && Buf_0[K]>Buf_1[K] && iHigh(NULL,PERIOD_H1,1)>iHigh(NULL,PERIOD_H1,2) && stm.hour>H3 && stm.hour<H4 && H3<H4) { send0=trade.PositionOpen(_Symbol,ORDER_TYPE_SELL,1,PriceBid,SL0,TP0); TicketSell0 = trade.ResultDeal(); } if(send0==true && K>0 && Buf_0[K-1]>Buf_1[K-1] && Buf_0[K]<Buf_1[K] && iLow(NULL,PERIOD_H1,1)<iLow(NULL,PERIOD_H1,2)) { trade.PositionClose(TicketSell0); send0=false; } K++; } //+------------------------------------------------------------------+
让我们同时优化的信号线期间,时间和止损订单的交易在两个方向上。
在图表线之前的一段时间内对神经网络进行训练,并对垂直红线进行优化。然后对优化后的神经网络响应进行测试。上面的图表显示了两个随机的正优化结果,优化器将其显示为最高优先级的结果。
神经网络似乎是一种黑匣子,然而,事实并非如此,因为我们可以在图层的特征图中查看神经网络突出显示的特征。这为进一步分析和提高网络质量提供了信息。让我们看看。
在 CNN 文件夹中运行 Visual.ipynb,
首先加载必要的神经网络库模块。
from tensorflow.python.keras.preprocessing.image import ImageDataGenerator from tensorflow.keras.models import Model, load_model import pandas as pd from tensorflow.python.keras.preprocessing import image import matplotlib.pyplot as plt import numpy as np
加载保存的模型。
model=load_model('cnn_Open11.hdf5')
让我们看看网络架构。
model.summary()
这些卷积层分析了什么?
加载一些图像。
img_path='Train/Buy/Buy81.png' img=image.load_img(img_path,target_size=(449,449)) plt.figure(figsize=(8, 8)) plt.imshow(img) plt.show
将图像转换为numpy数组并规格化。
x=image.img_to_array(img) x=np.expand_dims(x,axis=0) x/=255
在卷积层上裁剪模型。卷积层数是0、3、6,从0开始。实际上,我们创建了一个新的已经训练过的模型,从中我们将在分类之前得到一个中间结果。
model=Model(inputs=model.input, outputs=model.layers[0].output)
之后,我们可以查看第3层和第6层。
#model=Model(inputs=model.input, outputs=model.layers[3].output)
#model=Model(inputs=model.input, outputs=model.layers[6].output)
显示有关裁剪模型的信息。
model.summary()
检查第一个卷积层0,
得到神经网络响应。
model=model.predict(x)
打印一个特征图,18。
print(model.shape) im=model[0,:,:,18] plt.figure(figsize=(10, 10)) plt.imshow(im) plt.show()
如你所见,网络在这里突出了看涨的烛形。在这个阶段,神经网络很难区分下跌烛形和抛物线点。这是因为它们使用相同的颜色。因此,图表中的所有元素都应该用不同的颜色表示。
检查所有特征图
rows=12 filters=model.shape[-1] size=model.shape[1] cols=filters//rows display_grid=np.zeros((cols*size,rows*size)) for col in range(cols): for row in range(rows): channel_image=model[0,:,:,col*rows+row] channel_image-=channel_image.mean() channel_image/=channel_image.std() channel_image*=64 channel_image+=128 channel_image=np.clip(channel_image,0,255).astype('uint8') display_grid[col*size:(col+1)*size,row*size:(row+1)*size]=channel_image scale=1./size plt.figure(figsize=(scale*display_grid.shape[1],scale*display_grid.shape[1])) plt.grid(False) plt.imshow(display_grid,aspect='auto',cmap='viridis')
看看第三个特征图(2)。
在这里,神经网络突出所有的烛形,但使用了不同的灯芯。由于这一点,这幅画像是三维的。但是,你可以再次看到下跌烛形灯芯和抛物线有相同的颜色。
现在看下一个卷积层(3)第5张图。
在这里,抛物线点重叠,CNN 将其识别为横盘模式的标志。根据上图,神经网络对这一部分的渲染方式有所不同。因此,我们可以得出这样的结论:用于训练的图像类别已经扩展。我们需要引入另一个类别来训练神经网络-横盘。
因此,视觉检查卷积神经网络的特征图,使训练任务的规格更明确。这也可能有助于扩大CNN识别的特征类别,以及减少噪音。
利用卷积神经网络的公开工具和功能,我们可以将一种有趣且非传统的方法应用于技术分析。同时,这可以大大简化神经网络训练数据的准备。内部过程的可视化有助于分析哪些输入数据对培训质量影响最大。
最后,我想提到优化。正如我之前写的,这是一个非常简单的优化。但是,它应该与我们为网络设定的任务保持一致。根据这些任务,训练数组应该被划分为类别。此外,在创建交易机器人时应使用这些条件。
本社区仅针对特定人员开放
查看需注册登录并通过风险意识测评
5秒后跳转登录页面...
移动端课程