Tensorflow LSTM连续序列预测方法实践

本文展示了如何使用循环神经网络去估计一个向量序列,我们会使用到LSTM的网络。我在网上找的

大多数用到LSTM的例子都是用来解决自然语言处理方面问题的,还没有找到相关的例子可以用在预测连续

值序列上,所以写下了本文。


所以本文的任务是基于历史观察数据去预测一系列连续的实数。传统的神经网络做不到这一点,但是循环神经

网络可以解决该问题,因为他们能够存储历史信息来预测未来事件。


在下面的一个例子中我们将尝试预测一组函数sin、cos和x*sin(x).

首先让我们建立一个模型lstm_model, 这个模型是一系列不同时间步的lstm单元的堆叠,后接一个深层网络。

[python]  view plain  copy
  1. def lstm_model(time_steps, rnn_layers, dense_layers=None):  
  2.       """ 
  3.       Creates a deep model based on: 
  4.           * stacked lstm cells 
  5.           * an optional dense layers 
  6.       :param time_steps: the number of time steps the model will be looking at. 
  7.       :param rnn_layers: list of int or dict 
  8.                            * list of int: the steps used to instantiate the `BasicLSTMCell` cell 
  9.                            * list of dict: [{steps: int, keep_prob: int}, ...] 
  10.      :param dense_layers: list of nodes for each layer 
  11.      :return: the model definition 
  12.      """  
  13.    
  14.      def lstm_cells(layers):  
  15.          if isinstance(layers[0], dict):  
  16.              return [tf.nn.rnn_cell.DropoutWrapper(tf.nn.rnn_cell.BasicLSTMCell(layer['steps'],  
  17.                                                                                 state_is_tuple=True),  
  18.                                                    layer['keep_prob'])  
  19.                      if layer.get('keep_prob'else tf.nn.rnn_cell.BasicLSTMCell(layer['steps'],  
  20.                                                                                  state_is_tuple=True)  
  21.                      for layer in layers]  
  22.          return [tf.nn.rnn_cell.BasicLSTMCell(steps, state_is_tuple=Truefor steps in layers]  
  23.    
  24.      def dnn_layers(input_layers, layers):  
  25.          if layers and isinstance(layers, dict):  
  26.              return learn.ops.dnn(input_layers,  
  27.                                   layers['layers'],  
  28.                                   activation=layers.get('activation'),  
  29.                                   dropout=layers.get('dropout'))  
  30.          elif layers:  
  31.              return learn.ops.dnn(input_layers, layers)  
  32.          else:  
  33.              return input_layers  
  34.    
  35.      def _lstm_model(X, y):  
  36.          stacked_lstm = tf.nn.rnn_cell.MultiRNNCell(lstm_cells(rnn_layers), state_is_tuple=True)  
  37.          x_ = learn.ops.split_squeeze(1, time_steps, X)  
  38.          output, layers = tf.nn.rnn(stacked_lstm, x_, dtype=dtypes.float32)  
  39.          output = dnn_layers(output[-1], dense_layers)  
  40.          return learn.models.linear_regression(output, y)  
  41.    
  42.      return _lstm_model  

所以我们的模型接收的数据维度应该是这样的:(batch size,time steps of the first lstm cell, num_features)

下一步要做的就是把我们的数据重整成模型可以接收的格式。

[python]  view plain  copy
  1. def rnn_data(data, time_steps, labels=False):  
  2.       """ 
  3.       creates new data frame based on previous observation 
  4.         * example: 
  5.           l = [1, 2, 3, 4, 5] 
  6.           time_steps = 2 
  7.           -> labels == False [[1, 2], [2, 3], [3, 4]] 
  8.           -> labels == True [2, 3, 4, 5] 
  9.       """  
  10.      rnn_df = []  
  11.      for i in range(len(data) - time_steps):  
  12.          if labels:  
  13.              try:  
  14.                  rnn_df.append(data.iloc[i + time_steps].as_matrix())  
  15.              except AttributeError:  
  16.                  rnn_df.append(data.iloc[i + time_steps])  
  17.          else:  
  18.              data_ = data.iloc[i: i + time_steps].as_matrix()  
  19.              rnn_df.append(data_ if len(data_.shape) > 1 else [[i] for i in data_])  
  20.      return np.array(rnn_df)  
  21.    
  22.    
  23.  def split_data(data, val_size=0.1, test_size=0.1):  
  24.      """ 
  25.      splits data to training, validation and testing parts 
  26.      """  
  27.      ntest = int(round(len(data) * (1 - test_size)))  
  28.      nval = int(round(len(data.iloc[:ntest]) * (1 - val_size)))  
  29.    
  30.      df_train, df_val, df_test = data.iloc[:nval], data.iloc[nval:ntest], data.iloc[ntest:]  
  31.    
  32.      return df_train, df_val, df_test  
  33.    
  34.    
  35.  def prepare_data(data, time_steps, labels=False, val_size=0.1, test_size=0.1):  
  36.      """ 
  37.      Given the number of `time_steps` and some data, 
  38.      prepares training, validation and test data for an lstm cell. 
  39.      """  
  40.      df_train, df_val, df_test = split_data(data, val_size, test_size)  
  41.      return (rnn_data(df_train, time_steps, labels=labels),  
  42.              rnn_data(df_val, time_steps, labels=labels),  
  43.              rnn_data(df_test, time_steps, labels=labels))  
  44.    
  45.    
  46.  def generate_data(fct, x, time_steps, seperate=False):  
  47.      """generates data with based on a function fct"""  
  48.      data = fct(x)  
  49.      if not isinstance(data, pd.DataFrame):  
  50.          data = pd.DataFrame(data)  
  51.      train_x, val_x, test_x = prepare_data(data['a'if seperate else data, time_steps)  
  52.      train_y, val_y, test_y = prepare_data(data['b'if seperate else data, time_steps, labels=True)  
  53.      return dict(train=train_x, val=val_x, test=test_x), dict(train=train_y, val=val_y, test=test_y)  
这就会产生数据允许我们的模型往序列的前time_steps回看来预测未来数据。例如第一个单元

是10个time steps的单元,那么每做一次预测,我们都需要输入10个历史数据点。我们想要预测的

数值应该和数据点里的第10个相关。


首先定义超参数

[python]  view plain  copy
  1. LOG_DIR = './ops_logs'  
  2. TIMESTEPS = 5  
  3. RNN_LAYERS = [{'steps': TIMESTEPS}, {'steps': TIMESTEPS, 'keep_prob'0.5}]  
  4. DENSE_LAYERS = [2]  
  5. TRAINING_STEPS = 130000  
  6. BATCH_SIZE = 100  
  7. PRINT_STEPS = TRAINING_STEPS / 100  

现在可以建立一个回归模型

[python]  view plain  copy
  1. regressor = learn.TensorFlowEstimator(model_fn=lstm_model(TIMESTEPS, RNN_LAYERS, DENSE_LAYERS),  
  2.                                       n_classes=0,  
  3.                                       verbose=1,    
  4.                                       steps=TRAINING_STEPS,  
  5.                                       optimizer='Adagrad',  
  6.                                       learning_rate=0.03,  
  7.                                       batch_size=BATCH_SIZE)  

预测sin函数

[python]  view plain  copy
  1.  X, y = generate_data(np.sin, np.linspace(010010000), TIMESTEPS, seperate=False)  
  2.  # create a lstm instance and validation monitor  
  3.  validation_monitor = learn.monitors.ValidationMonitor(X['val'], y['val'],  
  4.                                                        every_n_steps=PRINT_STEPS,  
  5.                                                        early_stopping_rounds=1000)  
  6.  regressor.fit(X['train'], y['train'], validation_monitor, logdir=LOG_DIR)  
  7.    
  8. # > last training steps  
  9. # Step #9700, epoch #119, avg. train loss: 0.00082, avg. val loss: 0.00084  
  10. # Step #9800, epoch #120, avg. train loss: 0.00083, avg. val loss: 0.00082  
  11. # Step #9900, epoch #122, avg. train loss: 0.00082, avg. val loss: 0.00082  
  12. # Step #10000, epoch #123, avg. train loss: 0.00081, avg. val loss: 0.00081  
预测测试数据

[python]  view plain  copy
  1. mse = mean_squared_error(regressor.predict(X['test']), y['test'])  
  2. print ("Error: {}".format(mse))  
  3. # 0.000776  
同时预测 sin和cos函数
[python]  view plain  copy
  1. def sin_cos(x):  
  2.       return pd.DataFrame(dict(a=np.sin(x), b=np.cos(x)), index=x)  
  3.     
  4. X, y = generate_data(sin_cos, np.linspace(010010000), TIMESTEPS, seperate=False)  
  5. # create a lstm instance and validation monitor  
  6. validation_monitor = learn.monitors.ValidationMonitor(X['val'], y['val'],  
  7.                                                        every_n_steps=PRINT_STEPS,  
  8.                                                        early_stopping_rounds=1000)  
  9. regressor.fit(X['train'], y['train'], validation_monitor, logdir=LOG_DIR)  
  10.    
  11. # > last training steps  
  12. # Step #9500, epoch #117, avg. train loss: 0.00120, avg. val loss: 0.00118  
  13. # Step #9600, epoch #118, avg. train loss: 0.00121, avg. val loss: 0.00118  
  14. # Step #9700, epoch #119, avg. train loss: 0.00118, avg. val loss: 0.00118  
  15. # Step #9800, epoch #120, avg. train loss: 0.00118, avg. val loss: 0.00116  
  16. # Step #9900, epoch #122, avg. train loss: 0.00118, avg. val loss: 0.00115  
  17. # Step #10000, epoch #123, avg. train loss: 0.00117, avg. val loss: 0.00115  
预测测试数据
[python]  view plain  copy
  1. mse = mean_squared_error(regressor.predict(X['test']), y['test'])  
  2. print ("Error: {}".format(mse))  
  3. # 0.001144  

还有一个x*sinx的就不玩了,下面贴出英文原文

http://mourafiq.com/2016/05/15/predicting-sequences-using-rnn-in-tensorflow.html


  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值