普通的DNN和CNN容易学,但是在LSTM的学习上花了几天时间也没搞懂,今天的学习懂了一点点用法。




测试了:

  1. LSTM处理MNIST数据集
  2. 股票价格预测方法1:基于昨天的最高价
  3. 股票价格预测方法2:基于今天的多指标参数

 

 

下面的rnn来自(static_rnn要用到):

fromtensorflow.contribimportrnn

 

 

最难理解的是shape问题。

 

首先是输出输入的Placeholder


tensorflow lstm多输入单输出 tensorflow的lstm_预处理

     Input_size和output_size是指输出和输出数据的维度,比如我们的PPG问题,希望用原始信号的9各特征量(from ACC & PPG)计算出1个结果(HR),,则Input_size和output_size分别为9和1。    

       我觉得最最难理解的一个参数是 time_step,它表示我们一次喂给LSTM模型的时间步数。比如time_step设置为10,则在前述PPG问题中:求第10s的心率,我们要使用第1~10s共10s的数据作为输入;求第11s的心率,我们要使用第2~11s共10s的数据作为输入。数据数据的尺寸为Bacth_size  * time_step * input_size。

 

然后看BasicLSTMCell

tensorflow lstm多输入单输出 tensorflow的lstm_复杂度_02


       layers是指BasicLSTMcell的重复数量,越多模型越复杂。

       BasicLSTMCell中,我们要设置的主要参数只有一个num_units。源代码说明为num_units:int,ThenumberofunitsintheLSTMcell。这个参数应该表征模型的复杂度,可以随便设置,具体含义有待进一步理解。

 

x的准备

见到了两种方法

tensorflow lstm多输入单输出 tensorflow的lstm_数据_03

Unstacktogetalistof'time_step'tensorsofshape(batch_size,input_size)
直接unstack方法,原来的shape为(bacth_size , time_step,input_size);
输出shape为(time_step, batch_size,input_size)
这种方法后面跟的是rnn.static_rnn(….)

 

第二种方法如下

tensorflow lstm多输入单输出 tensorflow的lstm_预处理_04

这种方法后面跟的是tf.nn.dynamic_rnn(…)

理解之前,先看看权重

tensorflow lstm多输入单输出 tensorflow的lstm_数据_05

(图中rnn_unit就是前面说的num_units)

1. 在reshape一步,(bacth_size , time_step, input_size)的X被转化为input,其shape为(bacth_size  * time_step , input_size)
2. matmul一步,算得input_rnn的shape为(bacth_size  * time_step ,num_units)
3. 最后reshape一步,尺寸变为(bacth_size, time_step,num_units)

 

    可见两种方法结果不一样,这是不是与static_rnn和dynamic_rnn有关,有待进一步理解。经测试,果然与这个静态和动态有关,下面将详述。

    再补充:第二种方法关键理解它的shape,其实前面预处理阶段的那个w_in和biase_in的作用是增加了一个普通层而已,将input_size转换成了num_units.

 

建模中模型的输出

前面也说了,有两种方法

tensorflow lstm多输入单输出 tensorflow的lstm_预处理_06

 

tensorflow lstm多输入单输出 tensorflow的lstm_复杂度_07

结论吧:

    1. 对static_rnn,输入为time_step长度的‘list',总shape为
    (time_step, batch_size,input_size)。
    输出shape为(time_step,batch_size,num_units)
    states的shape为(2,batch_size, num_units)
    1. 对dynamic_rnn,输入shape为(bacth_size, time_step,num_units)
    输出shape为(bacth_size,time_step,num_units)
    States的shape为(2,bacth_size,num_units)

     

    输出

    静态rnn

    tensorflow lstm多输入单输出 tensorflow的lstm_复杂度_08

    输出logits的shape为(batch_size,output_size)

    动态rnn

    tensorflow lstm多输入单输出 tensorflow的lstm_复杂度_09

    则pred的shape为(bacth_size*time_step, output_size)

     

    评价loss

    静态相当于只考虑每一串time_step的最后一点,这个更符合我的直观感觉。

    动态则是对整串time_step都要管,因此需要对trian_y进行折叠预处理。

     

    评价一下:

    看例子被绕得晕晕呼呼的,原因就是这个动态和静态rnn存在很多不同的地方。我觉得把shape搞懂了,就等于基本搞懂用法了。

     

     

     

    我们回头再取读这篇博客,就能理解了。

    这里还讲了:

    对dynamic_rnn,所以我们需要tf.transpose(outputs, [1, 0, 2]),这样就可以取到最后一步的output。

    所以loss的评价也可以像static_rnn那样了。

     

    再看看这篇博客,它讲了dynamic_rnn的一个优点,我还没有搞懂。

     


     更正前面的一个错误:

    对static_rnn,输入的shape为(time_step, batch_size, anything);
    dynamic_rnn,输入shape为(batch_size,time_step, anything)。

    前面误导了,其实最后一个维度可以是任何东西。


    还有一个有趣的话题。

    就是
    cell = rnn.BasicLSTMCell(num_units = num_hidden, forget_bias=1.0)
     # cells = rnn.MultiRNNCell([cell] * 2) # 这样写时,必须input_size == num_hidden  # method 1
      cells = rnn.MultiRNNCell([rnn.BasicLSTMCell(num_hidden),rnn.BasicLSTMCell(num_hidden)])  # method 2

    如注释,method1时,必须满足 输入数据的最后一个维度 == num_hidden

    method2则没有这个要求。


    还有即使满足了相等要求时,两种方式也是不一样的,具体请用tensorboard画图测试吧