期货量化软件:赫兹量化系统神经网轻松学习之关注机制

在之前的文章中,我们已经测试了组织规划神经网络的各种选项。 其中包括借鉴来的图像处理算法的卷积网络[ 3 ],以及递归神经网络[ 4 ],这些神经网络不仅处理重要的数值序列,还有它们在源数据集合中的位置。

全连接和卷积神经网络具有固定的输入序列大小。 递归神经网络通过转移先前迭代中的隐藏状态,可稍微扩展所分析序列。 但是它们的有效性也随着序列的递增而降低。 在 2014 年,出于机器翻译的目的,第一次提出了关注机制。 该机制的目的在于判定并高亮显示与目标翻译词最相关的源句子(上下文)的区块。 这种直观的方法极大地提高了神经网络翻译文本的质量。

1. 关注机制

分析烛条品种图表时,我们定义了趋势和倾向,并判定出它们的交易范围。 这意味着,我们从总体图中选择一些对象,然后将注意力集中在这些对象上。 我们知晓对象会影响未来的价格行为。 为了实现这种方法,早在 2014 年,开发人员就提出了第一种算法,该算法可以分析输入和输出序列元素[8] 之间的依赖性,并高亮显示。 所提议的算法称为“泛关注机制”。 最初提议将其用在递归网络机器翻译模型之中,以便解决长句子翻译中的长期记忆问题。 这种方式大大改善了之前研究的基于 LSTM 模块[ 4 ] 的递归神经网络的结果。

采用递归网络的经典机器翻译模型由两个模块组成:编码器和解码器。 第一个模块将源语言中的输入序列编码为上下文向量,第二个模块将结果上下文解码为目标语言中的单词序列。 当输入序列的长度递增时,第一个单词对最终句子上下文的影响会递减。 后果就是,翻译品质下降。 采用 LSTM 模块略微增加了模型的效能,但它们仍然有限。

. 升级卷积层

我们从自关注算法的第一个动作开始 — 计算 Query、Key 和 Value 向量。 输入一个数据矩阵,其内包含所分析序列每根柱线特征。 逐根提取烛条的特征,然后将它们乘以权重矩阵,从而得到一个向量。 在我看来,这类似于文章[ 3 ] 中研究的卷积层。 然而,在这种情况下,输出不是数字,而是固定大小的向量。 为了解决这一难题,我们升级负责神经网络卷积层操作的 CNeuronConvOCL 类。 加入 iWindowOut 变量来存储输出向量的尺寸。 在类方法中实现相应的修改。

 
 

class CNeuronConvOCL : public CNeuronProofOCL { protected: uint iWindowOut; //--- CBufferDouble *WeightsConv; CBufferDouble *DeltaWeightsConv; CBufferDouble *FirstMomentumConv; CBufferDouble *SecondMomentumConv; //--- virtual bool feedForward(CNeuronBaseOCL *NeuronOCL); virtual bool updateInputWeights(CNeuronBaseOCL *NeuronOCL); public: CNeuronConvOCL(void) : iWindowOut(1) { activation=LReLU; } ~CNeuronConvOCL(void); virtual bool Init(uint numOutputs,uint myIndex,COpenCLMy *open_cl,uint window, uint step, uint window_out, uint units_count, ENUM_OPTIMIZATION optimization_type); //--- virtual bool SetGradientIndex(int index) { return Gradient.BufferSet(index); } //--- virtual bool calcInputGradients(CNeuronBaseOCL *NeuronOCL); virtual int Type(void) const { return defNeuronConvOCL; } //--- methods for working with files virtual bool Save(int const file_handle); virtual bool Load(int const file_handle); };

在 OpenCL 内核 FeedForwardConv 之中,添加一个获取输出矢量尺寸的参数。 另外,在卷积层输出之处,在通用向量中添加输出向量已处理片段的偏移量计算,并实现额外的循环遍历输出层元素。

 
 

__kernel void FeedForwardConv(__global double *matrix_w, __global double *matrix_i, __global double *matrix_o, int inputs, int step, int window_in, int window_out, uint activation) { int i=get_global_id(0); int w_in=window_in; int w_out=window_out; double sum=0.0; double4 inp, weight; int shift_out=w_out*i; int shift_in=step*i; for(int out=0;out<w_out;out++) { int shift=(w_in+1)*out; int stop=(w_in<=(inputs-shift_in) ? w_in : (inputs-shift_in)); for(int k=0; k<=stop; k=k+4) { switch(stop-k) { case 0: inp=(double4)(1,0,0,0); weight=(double4)(matrix_w[shift+k],0,0,0); break; case 1: inp=(double4)(matrix_i[shift_in+k],1,0,0); weight=(double4)(matrix_w[shift+k],matrix_w[shift+k+1],0,0); break; case 2: inp=(double4)(matrix_i[shift_in+k],matrix_i[shift_in+k+1],1,0); weight=(double4)(matrix_w[shift+k],matrix_w[shift+k+1],matrix_w[shift+k+2],0); break; case 3: inp=(double4)(matrix_i[shift_in+k],matrix_i[shift_in+k+1],matrix_i[shift_in+k+2],1); weight=(double4)(matrix_w[shift+k],matrix_w[shift+k+1],matrix_w[shift+k+2],matrix_w[shift+k+3]); break; default: inp=(double4)(matrix_i[shift_in+k],matrix_i[shift_in+k+1],matrix_i[shift_in+k+2],matrix_i[shift_in+k+3]); weight=(double4)(matrix_w[shift+k],matrix_w[shift+k+1],matrix_w[shift+k+2],matrix_w[shift+k+3]); break; } sum+=dot(inp,weight); } switch(activation) { case 0: sum=tanh(sum); break; case 1: sum=1/(1+exp(-clamp(sum,-50.0,50.0))); break; case 2: if(sum<0) sum*=0.01; break; default: break; } matrix_o[out+shift_out]=sum; } }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值