RNN的一種類型模型被稱為長短期記憶網絡(LSTM)。我覺得這是一個有趣的名字。它聽起來也意味着:短期模式長期不會被遺忘。
LSTM的精確實現細節不在本文的范圍之內。相信我,如果只學習LSTM模型會分散我們的注意力,因為它還沒有確定的標准
我們現在開始我們的教程。首先從編寫我們的代碼開始,先創建一個新的文件,叫做simple_regression.py。導入相關的庫,如步驟1所示。
步驟1:導入相關庫
import numpy as np
import tensorflow as tf
from tensorflow.contrib import rnn
接着,定義一個類叫做SeriesPredictor。如步驟2所示,構造函數里面設置模型超參數,權重和成本函數。
步驟2:定義一個類及其構造函數
class SeriesPredictor:
def __init__(self, input_dim, seq_size, hidden_dim=10):
self.input_dim = input_dim //#A
self.seq_size = seq_size //#A
self.hidden_dim = hidden_dim //#A
self.W_out = tf.Variable(tf.random_normal([hidden_dim, 1]),name='W_out') //#B
self.b_out = tf.Variable(tf.random_normal([1]), name='b_out') //#B
self.x = tf.placeholder(tf.float32, [None, seq_size, input_dim]) //#B
self.y = tf.placeholder(tf.float32, [None, seq_size]) //#B
self.cost = tf.reduce_mean(tf.square(self.model() - self.y)) //#C
self.train_op = tf.train.AdamOptimizer().minimize(self.cost) //#C
self.saver = tf.train.Saver() //#D
#A超參數。
#B權重變量和輸入占位符。
#C成本優化器(cost optimizer)。
#D輔助操作
接下來,我們使用TensorFlow的內置RNN模型,名為BasicLSTMCell。LSTM單元的隱藏維度是通過時間的隱藏狀態的維度。我們可以使用該rnn.dynamic_rnn函數處理這個單元格數據,以檢索輸出結果。步驟3詳細介紹了如何使用TensorFlow來實現使用LSTM的預測模型。
步驟3:定義RNN模型
def model(self):
"""
:param x: inputs of size [T, batch_size, input_size]
:param W: matrix of fully-connected output layer weights
:param b: vector of fully-connected output layer biases
"""
cell = rnn.BasicLSTMCell(self.hidden_dim) #A
outputs, states = tf.nn.dynamic_rnn(cell, self.x, dtype=tf.float32) #B
num_examples = tf.shape(self.x)[0]
W_repeated = tf.tile(tf.expand_dims(self.W_out, 0), [num_examples, 1, 1])#C
out = tf.matmul(outputs, W_repeated) + self.b_out
out = tf.squeeze(out)
return out
#A創建一個LSTM單元。
#B運行輸入單元,獲取輸出和狀態的張量。
#C將輸出層計算為完全連接的線性函數。
通過定義模型和成本函數,我們現在可以實現訓練函數,該函數學習給定示例輸入/輸出對的LSTM權重。如步驟4所示,你打開會話並重復運行優化器。
另外,你可以使用交叉驗證來確定訓練模型的迭代次數。在這里我們假設固定數量的epocs。
訓練后,將模型保存到文件中,以便稍后加載使用。
步驟4:在一個數據集上訓練模型
def train(self, train_x, train_y):
with tf.Session() as sess:
tf.get_variable_scope().reuse_variables()
sess.run(tf.global_variables_initializer())
for i in range(1000): #A
mse = sess.run([self.train_op, self.cost], feed_dict={self.x: train_x, self.y: train_y})
if i % 100 == 0:
print(i, mse)
save_path = self.saver.save(sess, 'model.ckpt')
print('Model saved to {}'.format(save_path))
#A訓練1000次
我們的模型已經成功地學習了參數。接下來,我們想評估利用其他數據來評估以下預測模型的性能。步驟5加載已保存的模型,並通過饋送一些測試數據以此來運行模型。如果學習的模型在測試數據上表現不佳,那么我們可以嘗試調整LSTM單元格的隱藏維數
步驟5:測試學習的模型
def test(self, test_x):
with tf.Session() as sess:
tf.get_variable_scope().reuse_variables()
self.saver.restore(sess, './model.ckpt')
output = sess.run(self.model(), feed_dict={self.x: test_x})
print(output)
但為了完善自己的工作,讓我們組成一些數據,並嘗試訓練預測模型。在步驟6中,我們將創建輸入序列,稱為train_x,和相應的輸出序列,稱為train_y。
步驟6訓練並測試一些虛擬數據
if __name__ == '__main__':
predictor = SeriesPredictor(input_dim=1, seq_size=4, hidden_dim=10)
train_x = [[[1], [2], [5], [6]],
[[5], [7], [7], [8]],
[[3], [4], [5], [7]]]
train_y = [[1, 3, 7, 11],
[5, 12, 14, 15],
[3, 7, 9, 12]]
predictor.train(train_x, train_y)
test_x = [[[1], [2], [3], [4]], #A
[[4], [5], [6], [7]]] #B
predictor.test(test_x)
#A預測結果應為1,3,5,7。
#B預測結果應為4,9,11,13。
你可以將此預測模型視為黑盒子,並用現實世界的時間數據進行測試。