精华内容
下载资源
问答
  • 对于航空发动机寿命预测问题,它难点在于特征数数多,而且特征也是传感器所收集到数据,传感器一般带有噪声,会造成拟合过程中不准确性,设计一个多变量输入,单变量输出预测模型,而RNN(循环神经网络)是...
  • LSTM算法+数据预测

    万次阅读 多人点赞 2018-11-06 20:43:20
    传统的神经网络一般都是全连接结构,且非相邻两层之间是没有连接的。对输入为时序的样本无法解决,因此引入了...1 LSTM算法小结  LSTM:是对RNN算法的改进,通过不同三个门控制之前信息对当前信息的影响即(1:那...

           传统的神经网络一般都是全连接结构,且非相邻两层之间是没有连接的。对输入为时序的样本无法解决,因此引入了RNN(可以查看具体的RNN含义和推导),但是会存在梯度消失(不同的隐层之间会存在过去时刻对当前时刻的影响因素,但随着时间跨度的变大这种影响会削弱)。因此引入LSTM

    1 LSTM算法小结
        LSTM:是对RNN算法的改进,通过不同三个门控制之前信息对当前信息的影响即(1:那些单元状态应该被遗忘2)那些新的状态应该被加入3)根据当前的状态和现在输入,输出应该是什么)
    https://www.cnblogs.com/azheng333/p/5908025.html详系

    描述LSTM门的作用。然后通过BPTT(https://blog.csdn.net/appleml/article/details/53317001目前找到可以一看的推导)来计算反向传播的误差,然后通过梯度下降更新参数求得模型。

    2 LSTM的优缺点和应用场景

            应用场景:适合于处理和预测时间序列中间隔和延迟相对较长的重要事件,如学习翻译语言,控制聊天机器人,预测疾病,点击率和股票等
      优点:1)分类的准确度高; 2)并行分布处理能力强,分布存储及学习能力强; 3)对噪声神经有较强的鲁棒性和容错能力,能充分逼近复杂的非线性关系; 4)具备联想记忆的功能。

      缺点:1)神经网络需要大量的参数,如网络拓扑结构,权值和阈值的初始值; 2)不能观察之间的学习过程,输出结果难以解释,会影响到结果的可信度和可接受程度; 3)学习时间过长,甚至可能达不到学习的目的。

    3算法运行过程
        通过数据训练模型,在网络的构建过程中本例使用tensorflow中自带的API封装进行使用。训练了一个简单的LSTM网络进行数据的预测。将训练好的模型可以保存,使用时进行调用,最后根据运行结果进行调优

    4具体历程

     4.1简单网上股票数据的预测

    import pandas as pd  #数据分析包
    import numpy as np   #提供多维数组对象的库
    import matplotlib.pyplot as plt  #画图的库
    import tensorflow as tf          #深度学习框架
    
    #导入数据
    f=open('stock_dataset.csv')  
    df=pd.read_csv(f)     #读入股票数据
    data=np.array(df['最高价'])   #获取最高价序列
    data=data[::-1]      #反转,使数据按照日期先后顺序排列
    #以折线图展示data
    plt.figure()
    plt.plot(data)
    plt.show()
    normalize_data=(data-np.mean(data))/np.std(data)  #标准化
    normalize_data=normalize_data[:,np.newaxis]       #增加维度
    
    
    #生成训练集
    #设置常量
    time_step=20      #时间步
    rnn_unit=10       #hidden layer units
    batch_size=60     #每一批次训练多少个样例
    input_size=1      #输入层维度
    output_size=1     #输出层维度
    lr=0.0006         #学习率
    train_x,train_y=[],[]   #训练集
    for i in range(len(normalize_data)-time_step-1):
        x=normalize_data[i:i+time_step]
        y=normalize_data[i+1:i+time_step+1]
        train_x.append(x.tolist())  #将数组转化成列表
        train_y.append(y.tolist()) 
    
    
    
    #定义神经网络变量
    X=tf.placeholder(tf.float32, [None,time_step,input_size])    #每批次输入网络的tensor/定义placeholder
    Y=tf.placeholder(tf.float32, [None,time_step,output_size])   #每批次tensor对应的标签
    #输入层、输出层权重、偏置
    weights={
             'in':tf.Variable(tf.random_normal([input_size,rnn_unit])),
             'out':tf.Variable(tf.random_normal([rnn_unit,1]))
             }
    biases={
            'in':tf.Variable(tf.constant(0.1,shape=[rnn_unit,])),
            'out':tf.Variable(tf.constant(0.1,shape=[1,]))
            }
    
    
    
    #定义神经网络变量
    def lstm(batch):      #参数:输入网络批次数目
        w_in=weights['in']
        b_in=biases['in']
        input=tf.reshape(X,[-1,input_size])  #需要将tensor转成2维进行计算,计算后的结果作为隐藏层的输入
        input_rnn=tf.matmul(input,w_in)+b_in #表示矩阵乘法
        input_rnn=tf.reshape(input_rnn,[-1,time_step,rnn_unit])  #将tensor转成3维,作为lstm cell的输入
        cell=tf.nn.rnn_cell.BasicLSTMCell(rnn_unit)  #定义单个基本的LSTM单元
        init_state=cell.zero_state(batch,dtype=tf.float32)  #这个函数用于返回全0的state tensor
    	#dynamic_rnn 用于创建由RNNCell细胞指定的循环神经网络,对inputs进行动态展开
    	#output_rnn是记录lstm每个输出节点的结果,final_states是最后一个cell的结果
        output_rnn,final_states=tf.nn.dynamic_rnn(cell, input_rnn,initial_state=init_state, dtype=tf.float32)
        #函数的作用是将tensor变换为参数shape的形式。 	
        output=tf.reshape(output_rnn,[-1,rnn_unit]) 
        w_out=weights['out']
        b_out=biases['out']
        pred=tf.matmul(output,w_out)+b_out #表示矩阵乘法
        return pred,final_states
    
    
    
    #训练模型
    def train_lstm():
        global batch_size
        pred,_=lstm(batch_size) #调用的构建的lstm变量
        #损失函数 平均平方误差(MSE)
        loss=tf.reduce_mean(tf.square(tf.reshape(pred,[-1])-tf.reshape(Y, [-1])))
    	#实现梯度下降算法的优化器,优化损失函数
        train_op=tf.train.AdamOptimizer(lr).minimize(loss)
    	#保存和恢复模型的方法;方法返回checkpoint文件的路径。可以直接传给restore() 进行调用
        saver=tf.train.Saver(tf.global_variables())
        with tf.Session() as sess:
            sess.run(tf.global_variables_initializer())
            #重复训练10000次
            for i in range(10000):
                step=0
                start=0
                end=start+batch_size
                while(end<len(train_x)):
                    _,loss_=sess.run([train_op,loss],feed_dict={X:train_x[start:end],Y:train_y[start:end]})
                    start+=batch_size
                    end=start+batch_size
                    #每10步保存一次参数
                    if step%10==0:
                        print(i,step,loss_)
                        print("保存模型:",saver.save(sess,'stock.model'))
                    step+=1
    
    
    train_lstm()
    
    
    #预测模型
    def prediction():
        pred,_=lstm(1)      #预测时只输入[1,time_step,input_size]的测试数据
        saver=tf.train.Saver(tf.global_variables())
        with tf.Session() as sess:
            #参数恢复
            module_file = tf.train.latest_checkpoint(base_path+'module2/')
            saver.restore(sess, module_file) 
    
            #取训练集最后一行为测试样本。shape=[1,time_step,input_size]
            prev_seq=train_x[-1]
            predict=[]
            #得到之后100个预测结果
            for i in range(100):
                next_seq=sess.run(pred,feed_dict={X:[prev_seq]})
                predict.append(next_seq[-1])
                #每次得到最后一个时间步的预测结果,与之前的数据加在一起,形成新的测试样本
                prev_seq=np.vstack((prev_seq[1:],next_seq[-1]))
            #以折线图表示结果
            plt.figure()
            plt.plot(list(range(len(normalize_data))), normalize_data, color='b')
            plt.plot(list(range(len(normalize_data), len(normalize_data) + len(predict))), predict, color='r')
            plt.show()
    
    prediction() 
    

       本例程实现简单的数据预测,只考虑到股票最高值的单一变量,其实还有很多影响因素需要考虑。另外历程中对用的tensorflow中的调用函数及代码功能做了较为详细的注解。

      运行的结果:蓝色的线为之前的数据,红色的只有100个数据点。

         

    展开全文
  • LSTM算法原理理解

    2019-04-11 11:51:00
    其实神经网络本质就是学习从输入到输出函数映射,因为遇到一个未知问题,无法对问题进行函数建模,利用神经网络学习出函数模型,这个学习结果最终其实是每一层神经元权重。  每一个神经元都...

    神经网络

      模拟人类大脑神经网络结构,每个神经元和其他的神经元相互连接,当它兴奋的时候会向相连的神经元发送化学物质,从而改变神经元的电位,当神经元的电位超过阈值,它会被激活,向其他神经元发送化学物质。其实神经网络的本质就是学习从输入到输出的函数映射,因为遇到一个未知的问题,无法对问题进行函数建模,利用神经网络学习出函数模型,这个学习的结果最终其实是每一层神经元的权重。

      每一个神经元都会在线性运算后的结果上(W*x+b),套上一个激活函数。激活函数的作用其实就是增强网络模型的非线性性,因为激活函数就是一个非线性函数,当如果每一层神经元后不添加激活函数,那么输出其实就是输入的线性组合,不管网络有多少层,输出就是输入的线性组合。常见的激活函数有tanh(-1,1),sigmod(0,1),relu[0,1)。

    RNN

      普通的神经网络假设输入和输入之间是相互独立的,但是很多时候人类理解事物都是基于上下文的。RNN和普通的神经网络的区别在于,不仅仅每层之间的神经元存在连接,同一层之间的神经元也存在连接,上一个时刻的状态能作用与下一个时刻的状态。但是当网络层数过深的时候,RNN不好训练,可能会造成梯度消失或是梯度爆炸的问题。RNN采用基于时间的反向传播法(BPTT)进行训练,这种训练方法也是一种梯度下降法。当网络结构太深,造成网络结构太深,网络权重不稳定,本质来说是因为梯度反向传播中的连乘效应。

      当梯度消失时,会造成神经网络参数无法更新,停止了学习。梯度爆炸则是更新速率太快,大幅度更新网络权重,可能无法学习到权重最佳值,也可能造成权重值为NaN而无法更新权重。

    RNN图示结构:

     

    LSTM

      RNN无法解决长期依赖问题,输出和前面很长一段序列有关。LSTM则设计用来解决这种问题,LSTM相比RNN来说,就是添加了三个门:遗忘门,输入门,输出门。

      遗忘门:决定从细胞状态中丢弃什么信息

      输入门:决定让多少新的信息加入细胞状态,这一步将输出细胞状态

      输出门:确定输出值,该输出值基于细胞状态 

    转载于:https://www.cnblogs.com/xiaobaituyun/p/10688732.html

    展开全文
  • 循环神经网络是神经网络的一种...循环神经网络不仅仅会接受上一层的输入,并且会接受上一时刻本层神经元的信息。循环神经网络可以有效解决之前的神经网络解决序列问题时的缺陷,但也存在着当神经网络过深或者时序数...

    LSTM总结目录(持续更新中

    背景知识


    循环神经网络是神经网络的一种,循环神经网络适合于解决序列问题。传统的神经网络不同层之间是全连接的, 而同一层内的神经元相互之间并无沟通。而在序列处理的过程中,前一阶段的输出会对下一阶段的输出产生影响。鉴于此,可以使用循环神经网络。循环神经网络不仅仅会接受上一层的输入,并且会接受上一时刻本层神经元的信息。循环神经网络可以有效解决之前的神经网络解决序列问题时的缺陷,但也存在着当神经网络过深或者时序数过多时的梯度爆炸或者是梯度消失的问题。

    循环神经网络示意图
    循环神经网络中的 LSTM 可以解决这种问题,即长短期记忆网络。并且循环神经网络得以广泛应用的关键就在LSTM 。输入门用来接受近期有用的信息,遗忘门用来对久远的、无用的信息选择性的遗忘。输出门的输出为根据当前状态决定的输出。
    LSTM示意图

    • 遗忘门:它决定了上一时刻的单元状态1C_(t-1)有多少保留到当前时刻C_t。
    • 输入门:它决定了当前时刻网络的输入X_t 有多少保存到单元状态 C_t。
    • 输出门:控制单元状态C_t有多少输出到LSTM的当前输出值h_t 。
      LSTM 的输入有三个,上一时刻的单元状态C_(t-1),上一时刻的输出h_(t-1),本次的最新输入信息X_t 。
      输出有两个,这一时刻的单元状态C_t , 和这一时刻的单元输出hth_{t}

    LSTM算法

    门的表达实际上是系数。如果系数为零,代表与之关联的任何信息均不能通过,如果系数为零,则与之相乘的任何信息均为零,即无法表达到最后的结果中。如果系数为1,则任何信息均不能过滤到最后的结果当中。

    • 遗忘门:
      在这里插入图片描述

    • 输入门:
      在这里插入图片描述

    • 输出门:
      在这里插入图片描述
      总的算法计算公式(已经描述的不再赘述):
      在这里插入图片描述
      在这里插入图片描述
      在这里插入图片描述
      LSTM 的神经单元示意图如下所示:
      在这里插入图片描述
      对于W权重的维度解析,注解如下:
      在这里插入图片描述
      在这里插入图片描述
      需要确定的参数项共有八个,分别为 WfW_{f}WiW_{i}WcW_{c}WoW_{o},以及对应的偏置项。
      训练过程可以简述为:
      1、 前向计算每个神经元的输出值,一共有 5 个变量,计算方法就是前一部分,
      2、反向计算每个神经元的误差项值。与 RNN 一样,LSTM 误差项的反向传播也是包括两个方向:
      一个是沿时间的反向传播,即从当前 t 时刻开始,计算每个时刻的误差项;
      一个是将误差项向上一层传播。
      3、根据相应的误差项,计算每个权重的梯度。

    训练技巧

    • LSTM 的常见问题是容易过拟合,对待过拟合问题可以通过随机丢失,数据正则化等手段。
      -可以对因子进行单独训练,以获知它们对最终结果的影响大小。

    • 训练的参数应该小于等于样本数。

    • 在一系列超参数中,学习率是最重要的超参数。

    • 多个LSTM 层的堆积,可以较快较好的解决问题。

    • 激活函数使用SOFTMAX效果较好。

    参考文献

    [1]LSTM原理详解:https://blog.csdn.net/qq_31278903/article/details/88690959
    [2]理解 LSTM(Long Short-Term Memory, LSTM) 网络:https://www.cnblogs.com/wangduo/p/6773601.html?utm_source=itdadao&utm_medium=referral
    [3] 详解LSTM:https://www.jianshu.com/p/dcec3f07d3b5
    [4]零基础入门深度学习(6) - 长短时记忆网络(LSTM):https://zybuluo.com/hanbingtao/note/581764


    1. LSTM 中长期状态信息的保留称为注脚 。 ↩︎

    展开全文
  • 针对传统基于模板匹配、关键词共现、人工特征集合等方法问答机器人存在用户意图识别耗时、费力且扩展性不强问题,本文结合地质领域文献中结构化知识问答复杂特点,使用了基于网格记忆网络(LSTM+CRF+Lattice)...
  • Tensorflow LSTM实现多维输入输出预测实践详解

    千次阅读 热门讨论 2021-02-21 20:14:43
    最近,看到股票持续走低为我增强了信心,发现为行为...算法模型基于动态多隐层LSTM RNN搭建,损失函数使用cross_entropy损失最大值,输入M维度、输出N维度,并预测长时间。代码基于Python3.6.X和Tensorflow1.13.X实现。

    摘要:算法模型基于动态多隐层LSTM RNN搭建,损失函数使用cross_entropy损失最大值,输入M维度、输出N维度。代码基于Python3.6.X和Tensorflow1.13.X实现。

    1. 前言

    对于新零售、金融、供应链、在线教育、银行、证券等行业的产品而言,以数据为驱动的用户行为分析尤为重要。用户行为分析的目的是:推动产品迭代、实现精准营销,提供定制服务,驱动产品决策。

    我们以新零售加油站业务场景为例开始,我们在去给车加油时,面临着花钱,还面临让人头疼的堵车和加油排队的等耗费时间的问题。通常,我们大概每周都有可能去一次加油站加油,还可能顺便进便利店买些非油物品,或者还能顺便洗车。
    在这里插入图片描述

    如上图所示的行为事件分析是根据运营关键指标,对用户特定事件加油卡交易数据进行分析。通过按时序追踪或记录用户行为事件,可以快速的了解到事件的趋势走向和加油客户的完成情况。

    对于预测股票近期、未来的价格,也是属于时序交易行为分析范畴,我们比较容易获取股票交易数据,也比较明显的对标预测结果。现如今,业界有可参考使用CNN+LSTM算法做行为分析,股票价格预测的案例。由于新零售等业务缺少数据,我们先用股票数据研究算法模型。

    2. 时序预测分析,深度学习LSTM算法概述

    在深度学习中有适合处理序列数据的神经网络,那就是循环神经网络 RNN,在NLP上应用较多,效果也比较好,而在金融量化分析上也有所应用,特别是在行为分析、股票价格预测上也有较多的应用。我们这里不深入研究算法模型,仅从应用角度介绍关键内容。

    2.1. 循环神经网络 RNN概述

    循环神经网络(Rerrent Neural Network, RNN )出现于20世纪80年代,是指一个随着时间序列的推移,重复发生循环的简单神经网络结构,它由输入层、隐藏层、输出层组成。
    在这里插入图片描述
    时间序列预测分析就是利用过去一段时间内某事件时间的特征来预测未来一段时间内该事件的特征。这是一类相对比较复杂的预测建模问题,和回归分析模型的预测不同,时间序列模型是依赖于事件发生的先后顺序的,同样大小的值改变顺序后输入模型产生的结果是不同的。

    RNN 是在有顺序的数据上进行学习的,为了记住这些数据,RNN 会像人一样产生对先前发生事件的记忆。

    2.2. 长短期记忆循环神经网络LSTM概述

    普通的 RNN 就像一个老爷爷,有时候比较健忘,为什么会这样呢?普通的RNN,对于输入使用手机软件的信息,要经过很长的路径才能抵达最后一个时间点。然后,我们得到误差,而且在反向传递得到的误差的时候,他在每一步都会乘以一个自己的参数W。如果这个W 是一个小于1 的数,经不断乘以误差,误差传到初始时间点也会是一个接近于零的数,误差相当于就消失了。我们把这个问题叫做梯度消失或者梯度弥散。反之如果W是一个大于1 的数,则到最后变成了无穷大的数,这种情况我们叫做剃度爆炸。这就是普通 RNN 没有办法回忆起久远记忆的原因。

    LSTM 就是为了解决这个问题而诞生的,LSTM 和普通 RNN 相比,多出了三个控制器:输入门、输出门、遗忘门。如下图所示为LSTM内部的结果概况。
    在这里插入图片描述

    ft=σ(Wf[ht1,xt]+bf)f_t=σ(W_f \cdot [h_{t-1},x_t ]+b_f )
    it=σ(Wi[ht1,xt]+bi)i_t=σ(W_i \cdot [h_{t-1},x_t ]+b_i )
    ot=σ(Wo[ht1,xt]+bo)o_t=σ(W_o \cdot [h_{t-1},x_t ]+b_o )
    C~t=tanh(Wc[ht1,xt]+bc)\tilde {C}_t = tanh(W_c \cdot [h_{t-1},x_t ]+b_c)
    Ct=ft×Ct1+it×C~tC_t=f_t \times C_{t-1}+i_t \times \tilde {C}_t
    ht=ot×tanh(Ct)h_t = o_t \times tanh(C_t)

    其中,ftf_t是遗忘门,iti_t是输入门,oto_t是输出门,CtC_t是神经元状态,hth_t是隐藏层状态值,W和b分别是权重和偏置。

    LSTM多出了一个控制全局的记忆,我们在图中表示为主线,相当于剧本中的主线剧情。而普通的 RNN体系就是分线剧情。我们先看输入的分线剧情对于剧终结果十分重要,输入控制就会将这个分线剧情按重要程度写入主线剧情进行分析,对于遗忘方面,如果此时的分线剧情更改了我们对之前剧情的想法,那么遗忘控制就会将之前的某些主线剧情忘记,按比例替换成现在的新剧情。LSTM 就像延缓记忆衰退的良药,可以带来更好的结果。

    对于LSTM算法模型,输出states是个tuple,分别代表CtC_{t}hth_{t},其中hth_{t}与outputs中对应的最后一个时刻(即最后一个cell)的输出相等。

    3. LSTM算法模型预测股票价格实践

    3.1. 基于Tensorflow1.13.X构建LSTM回归模型

    我们以类(class MultiLSTM)的方式定义LSTM RNN的主体结构,此RNN由3个组成部分 ( input_layer, cell, output_layer):

    (1)定义输入层:

            with tf.name_scope('inputs'):
                self.xs = tf.placeholder(tf.float32, [None, n_steps, input_size], name='xs')
                self.ys = tf.placeholder(tf.float32, [None, n_steps, output_size], name='ys')
                self.batch_size = tf.placeholder(tf.int32, [], name='batch_size')
                #节点不被dropout的概率
                self.keep_prob = tf.placeholder(tf.float32, name='keep_prob')
    

    其中,输入层另外包括batch_size(训练数据批次大小)和keep_prob(避免过拟合,不被删掉节点的概率)。

    (2)定义隐藏层:

    构建多隐层神经网络。

        # 定义多层LSTM    
        def add_multi_cell(self):
            cell_list = tf.contrib.rnn.BasicLSTMCell(self.cell_size, forget_bias=1.0, state_is_tuple=True) 
    
            with tf.name_scope('dropout'):
                if self.is_training:
                    # 添加dropout.为了防止过拟合,在它的隐层添加了 dropout 正则
                    cell_list = tf.contrib.rnn.DropoutWrapper(cell_list, output_keep_prob=self.keep_prob)
                    tf.summary.scalar('dropout_keep_probability', self.keep_prob)
            
            lstm_cell = [cell_list for _ in range(self.num_layers)]
            lstm_cell = tf.contrib.rnn.MultiRNNCell(lstm_cell, state_is_tuple=True) #遗漏过?, state_is_tuple=True
    
            with tf.name_scope('initial_state'):
                self.cell_init_state = lstm_cell.zero_state(self.batch_size, dtype=tf.float32)
            self.cell_outputs, self.cell_final_state = tf.nn.dynamic_rnn(
                lstm_cell, self.l_in_y, initial_state=self.cell_init_state, time_major=False)
    

    在RNN中进行dropout时,对于RNN的部分不进行dropout,仅在同一个t时刻中,多层cell之间传递信息的时候进行dropout。

    tf.nn.dynamic_rnn(cell, inputs)中的 time_major 参数会针对不同 inputs 格式有不同的值:

    • 如果 inputs 为 (batches, steps, inputs)则对应为 time_major=False; 如果 inputs
    • 为 (steps, batches, inputs) 则对应为time_major=True;

    (3)定义输出层:

    输出层实现不带激活函数的全连接,也就是线性的yi=wixi+biy_i=w_ix_i+b_i

        # 定义输出全连接层
        def add_output_layer(self):    
            l_out_x = tf.reshape(self.cell_outputs, [-1, self.cell_size], name='2_2D')        
            Ws_out = self._weight_variable([self.cell_size, self.output_size])
            bs_out = self._bias_variable([self.output_size, ])
            # shape = (batch * steps, output_size)
            with tf.name_scope('Wx_plus_b'):
                self.pred = tf.matmul(l_out_x, Ws_out) + bs_out
    

    (4)定义损失函数:

    使用tf.contrib.legacy_seq2seq.sequence_loss_by_example定义损失函数,由于是多输出模型,取均值将影响结果,我采用取最大值方案。

        def compute_cost(self):
            losses = tf.contrib.legacy_seq2seq.sequence_loss_by_example(
                [tf.reshape(self.pred, [-1], name='reshape_pred')], 
                [tf.reshape(self.ys, [-1], name='reshape_target')],       
                [tf.ones([self.batch_size * self.n_steps*self.output_size], dtype=tf.float32)], 
                average_across_timesteps=True,
                softmax_loss_function=self.ms_error,
                name='losses'
            )
          
            with tf.name_scope('average_cost'):
                # 取最大损失值
                self.cost = tf.reduce_max(losses, name='average_cost')
                '''
                self.cost = tf.div(
                    tf.reduce_sum(losses, name='losses_sum'),
                    self.batch_size_,
                    name='average_cost')
                '''
                tf.summary.scalar('cost', self.cost)
            print('self.cost shape is {}'.format(self.cost.shape))
    

    (5)搭建LSTM网络常见问题及注意事项:

    1. 多对多是 RNN 中最经典的结构,其输入、输出都是等长的序列数据;
    2. 在Tensorflow1.x的中,batch_size应设置为不定值,方便测试和模型应用时,不必再构造batch_size;
    3. 在做losse时,例如均方差过程中,注意数据个数为batch_sizen_stepsoutput_size;
    4. 由于数据集大小所限,当timestep过大,而训练集长度较小时,训练出来的模型进行预测会出现结果波动不大,呈一条直线的情况,建议缩短timestep。

    至此,多层LSTM模型构建完成,整合代码如下

    class MultiLSTM(object):
        def __init__(self, n_steps, input_size, output_size, cell_size, batch_size,num_layers,is_training):
            self.n_steps = n_steps
            self.input_size = input_size
            self.output_size = output_size
            self.cell_size = cell_size # LSTM神经单元数
            
            self.batch_size_ = batch_size # 输入batch_size大小
            self.num_layers = num_layers # LSTM层数
            #是否是训练状态
            self.is_training = is_training
            with tf.name_scope('inputs'):
                self.xs = tf.placeholder(tf.float32, [None, n_steps, input_size], name='xs')
                self.ys = tf.placeholder(tf.float32, [None, n_steps, output_size], name='ys')
                self.batch_size = tf.placeholder(tf.int32, [], name='batch_size')
                #节点不被dropout的概率
                self.keep_prob = tf.placeholder(tf.float32, name='keep_prob')
            
            with tf.variable_scope('in_hidden'):
                self.add_input_layer()
            with tf.variable_scope('Multi_LSTM'):
                self.add_multi_cell()            
            with tf.variable_scope('out_hidden'):
                self.add_output_layer()
            with tf.name_scope('cost'):
                self.compute_cost()
            with tf.name_scope('train'):
                self.train_op = tf.train.AdamOptimizer(LR).minimize(self.cost)
    
        def add_input_layer(self,):
            l_in_x = tf.reshape(self.xs, [-1, self.input_size], name='2_2D')  # (batch*n_step, in_size)
            Ws_in = self._weight_variable([self.input_size, self.cell_size])
            bs_in = self._bias_variable([self.cell_size,])
            with tf.name_scope('Wx_plus_b'):
                l_in_y = tf.matmul(l_in_x, Ws_in) + bs_in
            self.l_in_y = tf.reshape(l_in_y, [-1, self.n_steps, self.cell_size], name='2_3D')
            
        # 定义多层LSTM    
        def add_multi_cell(self):
            cell_list = tf.contrib.rnn.BasicLSTMCell(self.cell_size, forget_bias=1.0, state_is_tuple=True) 
    
            with tf.name_scope('dropout'):
                if self.is_training:
                    # 添加dropout.为了防止过拟合,在它的隐层添加了 dropout 正则
                    cell_list = tf.contrib.rnn.DropoutWrapper(cell_list, output_keep_prob=self.keep_prob)
                    tf.summary.scalar('dropout_keep_probability', self.keep_prob)
            
            lstm_cell = [cell_list for _ in range(self.num_layers)]
            lstm_cell = tf.contrib.rnn.MultiRNNCell(lstm_cell, state_is_tuple=True) #遗漏过?, state_is_tuple=True
    
            with tf.name_scope('initial_state'):
                self.cell_init_state = lstm_cell.zero_state(self.batch_size, dtype=tf.float32)
            self.cell_outputs, self.cell_final_state = tf.nn.dynamic_rnn(
                lstm_cell, self.l_in_y, initial_state=self.cell_init_state, time_major=False)
         
        # 定义输出全连接层
        def add_output_layer(self):    
            l_out_x = tf.reshape(self.cell_outputs, [-1, self.cell_size], name='2_2D')       
            Ws_out = self._weight_variable([self.cell_size, self.output_size])
            bs_out = self._bias_variable([self.output_size, ])
            with tf.name_scope('Wx_plus_b'):
                self.pred = tf.matmul(l_out_x, Ws_out) + bs_out
    
        def compute_cost(self):
            losses = tf.contrib.legacy_seq2seq.sequence_loss_by_example(
                [tf.reshape(self.pred, [-1], name='reshape_pred')], 
                [tf.reshape(self.ys, [-1], name='reshape_target')],       
                [tf.ones([self.batch_size * self.n_steps*self.output_size], dtype=tf.float32)], 
                average_across_timesteps=True,
                softmax_loss_function=self.ms_error,
                name='losses'
            )
            
            with tf.name_scope('average_cost'):
                self.cost = tf.reduce_max(losses, name='average_cost')
                '''
                self.cost = tf.div(
                    tf.reduce_sum(losses, name='losses_sum'),
                    self.batch_size_,
                    name='average_cost')
                '''
                tf.summary.scalar('cost', self.cost)
            print('self.cost shape is {}'.format(self.cost.shape))
            
        @staticmethod
        def ms_error(labels, logits):
            return tf.square(tf.subtract(labels, logits))
    
        def _weight_variable(self, shape, name='weights'):
            initializer = tf.random_normal_initializer(mean=0., stddev=1.,)
            return tf.get_variable(shape=shape, initializer=initializer, name=name)
    
        def _bias_variable(self, shape, name='biases'):
            initializer = tf.constant_initializer(0.1)
            return tf.get_variable(name=name, shape=shape, initializer=initializer)
    
    

    注:
    代码原型参考莫烦Python相关代码“LSTM回归”。
    多隐层数量不同的写法,官方推荐为:

    # 官方推荐的写法,使用列表生成器:
      num_units = [128, 64]
      cells = [BasicLSTMCell(num_units=n) for n in num_units]
      stacked_rnn_cell = MultiRNNCell(cells)
    

    3.2. 股票数据集

    股票数据来自Tushare,是一个免费、开源的python财经数据接口包。我使用的是Pro版,其数据更稳定质量更好了,Pro依然是个开放的,免费的平台,推荐:Tushare大数据社区 分享此链接。

    本实践案例使用后复权某股票数据,以及输入上证指数、深成指数、纳斯达克指数、道琼斯指数、恒生指数(由于计算机性能原因,只保留额外保留上证指数、深成指数)。
    在这里插入图片描述
    构建训练数据集,拆分出收盘股价、交易量、上证指数、深成指数为输出(OUTPUT_SIZE = 4),由于数据集时间序列比较少,时序取15组时序数据(TIME_STEPS = 15),从最早的时刻开始,逐个取15组全列数据为输入,15组后续15组4列为输出,则最后的输入为当前数据集最后日期减去15(PRED_SIZE=15)。

    拆分数据集过程代码如下所示,其中包括最后15组数据为预测未来15天(PRED_SIZE=15)的输入数据。

    def get_train_data():
        df = pd.read_csv('share20210302.csv')
        return df
    
    def get_test_data():
        df = pd.read_csv('share20210302.csv')
        #df = df.iloc[-(TIME_STEPS+1):] #由于要删除一行,需要多取一行(美国股市与中国差一天)
        df = df.iloc[-TIME_STEPS:]
        return df
    
    def get_pred_data(y,z,sc):
        yy = np.concatenate((y, z),axis=1)
        y=sc.inverse_transform(yy)
        return y
    
    # 设置数据集    
    def set_datas(df,train=True,sc=None):        
        df['Year'] = df['trade_date'].apply(lambda x:int(str(x)[0:4]))
        df['Month'] = df['trade_date'].apply(lambda x:int(str(x)[4:6]))
        df['Day'] = df['trade_date'].apply(lambda x:int(str(x)[6:8]))
    
        df['Week'] = df['trade_date'].apply(lambda x:datetime.datetime.strptime(str(x),'%Y%m%d').weekday())
        #纳仕达克、道琼斯指数,需要下移一条记录
        #shift_columns = ['open3','high3','close3','low3','change3','pct_chg3','open4','high4','close4','low4','change4','pct_chg4']
        #df[shift_columns] = df[shift_columns].shift(1)
        # 重排表的列,便于数据提取
        ##df = df.reindex(columns=col_name)
        df = df.drop('trade_date',axis=1)
        #df = df[1:].reset_index(drop=True)  #删除第一行,从0开始
        col_name = df.columns.tolist()
        #列移动归集位置
        col_name.remove('close1')
        col_name.remove('close2')
        col_name.remove('vol0')
        #删除不重要的列
        #del_list = ['high3','low3','change3','pct_chg3','high4','low4','change4','pct_chg4','high5','low5','change5','pct_chg5']
        #for name in del_list:
        #    col_name.remove(name)    
        col_name.insert(0,'close1')
        col_name.insert(1,'close2')
        col_name.insert(2,'vol0')
        df = df[col_name]
        #sc = MinMaxScaler(feature_range= (0,1)) 预测值超过最大值?
        if train:
            sc = MinMaxScaler(feature_range= (0,1))
            training_set = sc.fit_transform(df)
        else:
            # 测试集,也需要使用原Scaler归一化
            training_set = sc.transform(df)
        # 按时序长度构造数据集
        def get_batch(train_x,train_y):
            data_len = len(train_x) - TIME_STEPS
            seq = []
            res = []
            for i in range(data_len):
                seq.append(train_x[i:i + TIME_STEPS])
                res.append(train_y[i:i + TIME_STEPS]) #取后5组数据
                #res.append(train_y[i:i + TIME_STEPS]) 
             
            seq ,res = np.array(seq),np.array(res)
        
            return  seq, res
        
        if train:
            seq, res = get_batch(training_set[:-PRED_SIZE], training_set[PRED_SIZE:][:,0:OUTPUT_SIZE]) #0:9
        else:
            seq, res = training_set, training_set[:,0:OUTPUT_SIZE]
            seq, res = seq[np.newaxis,:,:], res[np.newaxis,:,:]
      
        return seq, res, training_set[:,OUTPUT_SIZE:],sc,col_name,df
    

    注意事项:
    训练集和测试集,在做归一化处理后,需要采用统一标准,也就是对MinMaxScaler用一次fit_transform,后续使用transform即可。(容易在这个小河沟里翻船!)

    3.3. 模型训练及参数

    在模型训练中,使用tf.data.Dataset.from_tensor_slices迭代器,分批次获取batche数据。训练过程日志数据记录到“logs”目录下,通过tensorboard工具查看。

    import tensorflow as tf
    import numpy as np
    import pandas as pd
    import datetime
    from sklearn.preprocessing import MinMaxScaler
    import matplotlib.pyplot as plt
    
    BATCH_START = 0
    TIME_STEPS = 15
    BATCH_SIZE = 30
    INPUT_SIZE = 25
    OUTPUT_SIZE = 4
    PRED_SIZE = 15 #预测输出15天序列数据
    CELL_SIZE = 256
    NUM_LAYERS = 3
    LR = 0.00001
    EPOSE = 40000
    
    if __name__ == '__main__':
    
        model = MultiLSTM(TIME_STEPS, INPUT_SIZE, OUTPUT_SIZE, CELL_SIZE, BATCH_SIZE, NUM_LAYERS,True)
        sess = tf.Session()
        merged = tf.summary.merge_all()
        writer = tf.summary.FileWriter("logs", sess.graph)
        # tf.initialize_all_variables() no long valid from
        # 2017-03-02 if using tensorflow >= 0.12
        if int((tf.__version__).split('.')[1]) < 12 and int((tf.__version__).split('.')[0]) < 1:
            init = tf.initialize_all_variables()
        else:
            init = tf.global_variables_initializer()
        sess.run(init)
        # relocate to the local dir and run this line to view it on Chrome (http://localhost:6006/):
        # $ tensorboard --logdir logs
        state = 0
        xs = 0
        df = get_train_data()
        train_x,train_y,z,sc,col_name,df = set_datas(df,True)
        
        # 使用from_tensor_slices将数据放入队列,使用batch和repeat划分数据批次,且让数据序列无限延续
        dataset = tf.data.Dataset.from_tensor_slices((train_x,train_y))
        dataset = dataset.batch(BATCH_SIZE).repeat()
        
        # 使用生成器make_one_shot_iterator和get_next取数据
        # 单次迭代器只能循环使用一次数据,而且单次迭代器不需要手动显示调用sess.run()进行初始化即可使用
        #iterator = dataset.make_one_shot_iterator()
        # 可初始化的迭代器可以重新初始化进行循环,但是需要手动显示调用sess.run()才能循环
        iterator = dataset.make_initializable_iterator()
        next_iterator = iterator.get_next()    
        losse = []
        for i in range(EPOSE):
            # 这是显示初始化,当我们的迭代器是dataset.make_initializable_iterator()的时候,才需要调用这个方法,否则不需要
            sess.run(iterator.initializer)
            seq, res = sess.run(next_iterator)
            if i == 0:
                feed_dict = {
                        model.xs: seq,
                        model.ys: res,
                        model.batch_size:BATCH_SIZE,
                        model.keep_prob:0.75,
                        # create initial state
                }
            else:
                feed_dict = {
                    model.xs: seq,
                    model.ys: res,
                    model.batch_size:BATCH_SIZE,
                    model.keep_prob:0.75,
                    model.cell_init_state: state    # use last state as the initial state for this run
                }
    
            _, cost, state, pred = sess.run(
                [model.train_op, model.cost, model.cell_final_state, model.pred],
                feed_dict=feed_dict)
            losse.append(cost)
    
            if i % 20 == 0:
                #print(state)
                print('cost: ', round(cost, 5))
                result = sess.run(merged, feed_dict)
                writer.add_summary(result, i)
        plt.rcParams['font.sans-serif']=['SimHei'] #显示中文标签
        plt.rcParams['axes.unicode_minus']=False
        losse = np.array(losse)/max(losse)
        plt.plot(losse, label='Training Loss')
        plt.title('Training Loss')
        plt.legend()
        plt.show()
        #训练结束
    

    在命令行窗口中,进入当前程序目录,使用tensorboard --logdir logs命令。计算图如下:
    在这里插入图片描述
    训练过程如下,cost值达到0.013X。

    在这里插入图片描述

    3.4. 预测结果及分析

    使用数据集最后15条记录做为预测未来15天的输入,输出结果如下:

        df = get_test_data()
        seq,res,z,sc,col_name,df = set_datas(df,False,sc) 
        seq = seq.reshape(-1,TIME_STEPS,INPUT_SIZE)
        share_close = df['close0'].values
        share_vol = df['vol0'].values/10000
        share_sh = df['close1'].values
        share_sz = df['close2'].values
        model.is_training = False
    
        feed_dict = {
            model.xs: seq,
            model.batch_size:1,
            model.keep_prob:1.0
        } 
        #pred,state = sess.run([model.pred,model.cell_init_state], feed_dict=feed_dict)
        pred = sess.run([model.pred], feed_dict=feed_dict)  
        #print(pred[0])
        y=get_pred_data(pred[0].reshape(TIME_STEPS,OUTPUT_SIZE),z,sc) 
        df= pd.DataFrame(y,columns=col_name)   
        df.to_csv('y.csv') 
        share_close1 = df['close0'].values
        share_vol1 = df['vol0'].values/10000
        share_sh1 = df['close1'].values
        share_sz1 = df['close2'].values
        #合并预测移动移位PRED_SIZE
        share_close1 = np.concatenate((share_close[:PRED_SIZE],share_close1),axis=0)
        share_vol1 = np.concatenate((share_vol[:PRED_SIZE],share_vol1),axis=0)
        share_sh1 = np.concatenate((share_sh[:PRED_SIZE],share_sh1),axis=0)
        share_sz1 = np.concatenate((share_sz[:PRED_SIZE],share_sz1),axis=0)
        
        plt.plot(share_sh, label='收盘沪指指数')
        plt.plot(share_sh1, label='预测收盘沪指指数')
        plt.plot(share_sz, label='收盘深证指数')
        plt.plot(share_sz1, label='预测收盘深证指数')
            
        plt.plot(share_close, label='收盘实际值')
        plt.plot(share_vol, label='成交量实际值')
        plt.plot(share_vol1, label='成交量预测值')
        plt.plot(share_close1, label='收盘预测值')
            
        plt.title('Test Loss')
        plt.legend()
        plt.show()      
    

    预测结果是从下图中横坐标14开始,连续预测15天。输入数据时间序列中间经历过中国年假期,所选的数据集可能不合适。

    在这里插入图片描述
    注意:由于前15天数据与输入重合,图像上覆盖使线略微变深,而看不出另一条线。

    4. 小结

    最近,看到股票持续走低为我增强了信心,发现为行为分析准备的模型预研还是很有意义的。

    多隐层,多输入、输出,而且输入、输出不同维度LSTM预测模型,在行为分析预测中,还是实际意义,如果结合上CNN或特征工程作为输入,将会有更好的结果。

    对于RNN Cell中神经元数量设置,通过多轮训练实践,一般是输入的10倍以上,特别是数据集数量偏少情况下,更应多些。但是,这样将带来训练难度加大,周期变成的情况。

    由于作者水平有限,欢迎反馈交流。

    参考:

    1.《什么是 LSTM 循环神经网络》莫烦PYTHON, 莫烦 ,2016年11月
    2.《LSTM的训练和测试长度(batch_size)不一样报错的解决方案》CSDN博客 ,David-Chow ,2019年4月
    3.《tf.nn.dynamic_rnn 详解》知乎 ,应钟有微 ,2018年8月
    4.《用户研究:如何做用户行为分析?》人人都是产品经理,朱学敏,2019年12月
    5.《基于Keras的LSTM多变量时间序列股票预测》CSDN博客 ,肖永威, 2020年4月
    6.《TensorFlow1.4之LSTM的使用》51CTO博客 , mybabe0312 ,2019年2月
    7.《LSTM中的参数计算》知乎 ,忆臻 ,2018年12月

    展开全文
  • 自古以来,我们就希望预知未来,现如今,随着大数据人工智能技术发展,我们早已经不满足传统...深度学习神经网络为我们提供较为通用解决方案,我们将在这里实践基于Python Keras LSTM多维输入输出时序预测模型。
  • LSTM的加速算法:QRNN和SRU

    千次阅读 2019-09-22 14:05:37
    LSTM的公式可以表示如下所示,其中分别表示输入门,输出门,遗忘门。对LSTM还不熟悉同学可以先阅读:理解LSTM网络或者直接阅读Christopher Olah 原博文:Understanding LSTM Networks 从上述公式中,我们先来...
  • 算法接受视频序列作为输入,先利用卷积网络提取视频帧空间特征,然后利用LSTM模块得到时间维度特征,最后利用全卷积网络预测最终检测结果。将所提算法与其他典型的算法进行比较,实验结果表明所提算法具有更...
  • 针对传统阿兹海默症(AD)分类3D...最后结合特征序列与LSTM的隐藏状态进行分类。实验结果显示,相比3D模型,该算法有着更少参数,对于NC与AD分类达到了93.93%准确率,对于NC与MCI分类达到了86.27%准确率。
  • 如下图所示(图片来自网络)。...如下图所示,这三个LSTM细胞参数是相同,不同输入值不同,因此输出值Ht和Ct也不同。 对应数学模型为 如果我们使用随机梯度下降法对网络进行优化,则输入数据和输...
  • DGA(域名生成算法)是一种利用随机字符来生成C&C域名,从而逃避域名黑名单检测技术手段。例如,一个由Cryptolocker创建DGA生成域xeogrhxquuubt.com,如果我们进程尝试其它建立连接,那么我们机器就可能...
  • 如果您是想了解LSTM算法,您不必往下阅读,因为本博文是关于torch.nn.LSTM()一些详解,是在读者有LSTM算法思想之后复现LSTM时用到。 输入的参数列表包括: input_size: 输入数据特征维数,通常就是embedding_dim...
  • 浅说 Lstm

    2018-11-09 15:19:00
     LSTM算法的全称是长短期记忆网络(long short–term memory),由LSTM算法对标准的RNN进行的改进,它规避了标准的RNN中的梯度爆炸和梯度消失的问题,学习速度更快。 二 原理  lstm 结构:  一个一个神经元...
  • LSTM是一类递归神经网络体系结构(及其关联学习算法),尽管在相关输入之间存在噪声并且任意长时间存在时间滞后,但在其他一些问题上,LSTM仍然能够有效学习和归纳其能力,从而提供了大量经验支持。网络类型...
  • 我们展示了如何准备、建模和部署基于深度学习 LSTM 分类算法来识别机械空气压缩机状况或输出。 我们展示了如何执行深度学习工作流程以下部分示例: 第 1 部分 - 数据准备第 2 部分 - 建模第 3 部分 - ...
  • LSTM模型结构1、LSTM模型结构2、LSTM网络3、LSTM的输入结构4、Pytorch中的LSTM4.1、pytorch中定义的LSTM模型4.2、喂给LSTM的数据格式4.3、LSTM的output格式5、LSTM和其他网络组合 1、LSTM模型结构 BP网络和CNN网络...
  • reshape训练集和测试集,适配LSTM网络的输入尺寸 设置 batch_size和epochs,开始训练 使用粒子群算法PSO遍历LSTM的网络结构,从而找到最优参数,要遍历的参数有:神经网络第一层神经元个数,dropout比率,batch_size ...
  • RNN是对时间序列数据的一种预测算法,被大量用于...RNN中有个状态变量(cell state),上一时间的状态变量和输入数据一起,共同组成本次时间的输入。 常用的RNN结构有LSTM(Long Short-Term Memory, 长短期记忆网络)...
  • reshape训练集和测试集,适配LSTM网络的输入尺寸 设置 batch_size和epochs,开始训练 使用粒子群算法PSO遍历LSTM的网络结构(要花点时间),从而找到最优参数,要遍历的参数有:神经网络第一层神经元个
  • RNN 与 LSTM 应用

    2016-06-21 15:45:00
    之前已经介绍过关于 Recurrent Neural Nnetwork 与 Long Short-Trem Memory 网络结构与参数求解算法( 递归神经网络(Recurrent Neural Networks,RNN),LSTM网络(Long Short-Term Memory )),本文将列举一些 ...
  • 第一种架构类别:从输入和输出序列长度角度 1)N:N(最为常见架构) 2)N:M(Seq2Seq或者Encoder-Decoder模型) 3)1:N(处理如图片标注问题,x是图像特征,y是一个句子) 4)N:1(处理如序列分类问题...
  • 学习参考:Tensorflow实战Google...在全链接神经网络或者卷积神经网络中,网络结构都是从输入层到隐含层再到输出层,层与层之间是全链接或者部分链接,但每层之间节点是无链接。RNN来源就是为了刻画一个序列...
  • 对于match-lstm,将hi文本与输出match-lstm(由si,hi,qi)组合重新输入LSTM网络中,以端对端操作理念。 参考博客:https://blog.csdn.net/laddie132/article/details/79159895 #MATCH-LSTM原理 ...
  • LSTM 中引⼊了3个⻔,即遗忘⻔(input gate)、输入⻔(forget gate)和输出⻔(output gate),以及与隐藏状态形状相同记忆细胞(某些⽂献把记忆细胞当成⼀种特殊隐藏状态),从而记录额外信息。 LSTM关键:...
  • 一般神经网络隐层计算是h=g(w * x),其中g是激活函数,相比于一般神经网络,RNN需要考虑之前序列信息,因此它隐藏h计算除了当前输入还要考虑上一个状态隐藏,h=g(w*x+w'*h'),其中h'是上一次计算隐层,...
  • LSTM架构详解

    千次阅读 多人点赞 2019-05-25 16:53:49
    LSTM 是深度学习中很常见也很有用一种算法,特别是在自然语言处理中更是经常用到,那么 LSTM 架构中内部结构又是什么样子呢?首先我们来看 LSTM 整体框架: 在这幅图中,中间是一个 LSTM 模块,有三个输入...

空空如也

空空如也

1 2 3 4 5 ... 10
收藏数 194
精华内容 77
关键字:

lstm算法的输入