摘要:
帶你深入了解TensorFlow框架下的LSTM時間序列預測
現(xiàn)實生活中,我們經(jīng)常會遇到各式各樣的時間序列預測場景,比如、股票和黃金價格的預測商品銷量的預測等等。TensorFlowTime Series(以下簡稱TFTS)專門設計了一套針對時間序列預測問題的API,利用其提供的LSTM模型,可以實現(xiàn)在TensorFlow中快速搭建高性能時間序列預測系統(tǒng)。LSTM具有優(yōu)于傳統(tǒng)神經(jīng)網(wǎng)絡框架的優(yōu)勢。雖然用TensorFlow與LSTM結(jié)合來做時間序列預測是一個很舊的話題,然而卻一直沒有得到比較好的解決或分析。本文結(jié)合實例代碼帶你從零開始輕松搭建TensorFlow深度學習框架下LSTM高性能時間序列預測系統(tǒng)。
所謂的時間序列預測是指在某些未來時間點預測數(shù)據(jù)的值的多少。時間序列預測主要基于連續(xù)性原理。在現(xiàn)實生活中,大多數(shù)事物的基本發(fā)展趨勢將在未來繼續(xù),其產(chǎn)生的數(shù)據(jù)也將滿足時間序列的連續(xù)性原則。所以在實際應用中,時間序列預測具有較強的實用性。預測效果與預測模型的選擇密不可分。
TensorFlow是一種基于圖的計算框架。正如TensorFlow本身所表示含義。Tensor表示張量,是TensorFlow的核心數(shù)據(jù)單位,其本質(zhì)是一個任意維的數(shù)組。Flow(流)表示基于數(shù)據(jù)流圖的計算,構(gòu)建執(zhí)行流圖是TensorFlow開發(fā)過程中的重點。它表示的是張量從流圖的一端流動到另一端計算過程,正是這種基于流的架構(gòu)讓它具有了更高的靈活性。TensorFlow系統(tǒng)架構(gòu)如下圖所示
TensorFlow系統(tǒng)架構(gòu)
LSTM(LongShort-Term Memory)是傳統(tǒng)遞歸神經(jīng)網(wǎng)絡RNN(Recurrent Neural Networks)改良后的成果,是一款長短期記憶網(wǎng)絡。它是由Ho?chreiter和Schmidhuber在1997年提出的。相較于普通的RNN,LSTM增加了一個記憶單元(cell)用于判斷信息有用與否,解決了長序列訓練過程中的梯度消失和梯度爆炸問題。這一改進使得其能在更長的序列中有更好的表現(xiàn)。
記憶單元的狀態(tài)(cellstate)是LSTM的關(guān)鍵,為了保護和控制記憶單元的狀態(tài),一個記憶單元中被放置了三個控制門,分別叫做輸入門、遺忘門和輸出門。每個控制門由一個包含一個sigmoid函數(shù)的神經(jīng)網(wǎng)絡層和一個點乘操作組成。LSTM記憶單元的結(jié)構(gòu)圖如下圖所示。圖中從左方的輸入
的一條貫穿示意圖頂部的水平線即為記憶單元的狀態(tài)。遺忘門、輸入門、輸出門的神經(jīng)網(wǎng)絡層均用
關(guān)于輸入門、遺忘門和輸出門的詳細介紹如下:
一個信息進入LSTM的網(wǎng)絡當中,只有符合算法認證的信息才可以不被遺忘。完成是否遺忘判斷的是包含
來決定上一時刻的單元狀態(tài)有多少可以被保留到當前時刻。
輸入門通過sigmoid來決定當前時刻網(wǎng)絡的輸入
層的輸出相乘,以此實現(xiàn)對單元狀態(tài)
下面首先從簡單的案例來進行分析,這里只考慮單變量時間序列預測。注意,下面代碼并非完整代碼展示,主要是對程序主要步驟進行詳細說明。完整代碼請見文末。此外,這里默認大家都已經(jīng)搭建和配置好了Python環(huán)境下TensorFlow。
利用函數(shù)加隨機噪聲的方法生成一個較為復雜的實驗用時間序列數(shù)據(jù)。x對應時間序列的“觀察的時間點”,y對應時間序列的“觀察到的值”。然后將入x和y合并成data(Python中的字典)完成數(shù)據(jù)讀入。再使用NumpyReader使之轉(zhuǎn)換為Tensor形式,接著用tf.contrib.timeseries.RandomWindowInputFn將其變?yōu)閎atch訓練數(shù)據(jù)。這是一個有4個隨機序列的訓練數(shù)據(jù)batch,且每個序列長度為100。具體實現(xiàn)代碼如下:
noise= np.random.uniform(-0.2, 0.2, 1000) #隨機噪聲
y= np.sin(np.pi * x / 50 ) + np.cos(np.pi * x / 50) + np.sin(np.pi * x/ 25) + noise
tf.contrib.timeseries.TrainEvalFeatures.TIMES:x, #TFTS 讀入x
tf.contrib.timeseries.TrainEvalFeatures.VALUES:y, #TFTS 讀入y
reader= NumpyReader(data)
train_input_fn= tf.contrib.timeseries.RandomWindowInputFn(
reader, batch_size=4,window_size=100)
利用TFTS提供的LSTM模型,其中由于是單變量時間序列,每個觀測點只對應一個數(shù)值所以需要令num_features=1。num_units=128表示使用隱層為128大小的LSTM模型。在優(yōu)化器的選擇上,選用了實現(xiàn)了Adam算法的優(yōu)化器tf.train.AdamOptimizer,能基于訓練數(shù)據(jù)迭代地更新神經(jīng)網(wǎng)絡權(quán)重。
estimator= ts_estimators.TimeSeriesRegressor(model=_LSTMModel(num_features=1,num_units=128),
optimizer=tf.train.AdamOptimizer(0.001))
Estimator是一種可極大地簡化機器學習編程的高階TensorFlowAPI,借助預創(chuàng)建的Estimator可以快速實現(xiàn)訓練集的訓練、評估和預測。實現(xiàn)代碼如下:
estimator.train(input_fn=train_input_fn,steps=2000) #訓練
evaluation_input_fn= tf.contrib.timeseries.WholeDatasetInputFn(reader)
evaluation= estimator.evaluate(input_fn=evaluation_input_fn, steps=1) #評估
(predictions,)= tuple(estimator.predict(
input_fn=tf.contrib.timeseries.predict_continuation_input_fn(
定義變量分別記錄實驗生成的時間序列數(shù)據(jù),預測的時間序列數(shù)據(jù)以及向后預測的實驗數(shù)據(jù)并繪圖保存。實現(xiàn)代碼如下:
observed_times= evaluation["times"][0] #記錄實驗用時間序列數(shù)據(jù)的時間
observed= evaluation["observed"][0, :, :] #記錄實驗用時間序列數(shù)據(jù)的值
evaluated_times= evaluation["times"][0] #記錄預測值對應的時間
evaluated= evaluation["mean"][0] #記錄預測值
predicted_times= predictions['times'] #記錄向后預測的預測值對應的時間
predicted= predictions["mean"] #記錄向后預測的預測值
plt.figure(figsize=(15,5)) #定義圖片
plt.axvline(999,linestyle="dotted", linewidth=4, color='r') #畫豎直分割線
observed_lines= plt.plot(observed_times, observed, label="observation",color="k") #定義線條
evaluated_lines= plt.plot(evaluated_times, evaluated, label="evaluation",color="g")
predicted_lines= plt.plot(predicted_times, predicted, label="prediction",color="r")
plt.legend(handles=[observed_lines[0],evaluated_lines[0], predicted_lines[0]],
plt.savefig('predict_result.jpg') #保存圖片
運行后,畫出的圖像會保存成“predict_result.jpg”文件。可以得到如下圖結(jié)果:
案例1中只是針對單一變量時間序列進行了預測,這里我們通過改變變量數(shù)來進行多變量時間序列預測。依然要注意,下面的代碼并非完整代碼展示,主要是對程序主要步驟進行詳細說明。完整代碼請見文末。
所謂多變量時間序列,就是指在每個時間點上的觀測量有多個值。多變量時間序列預測與單變量時間序列預測的不同之處在于單變量預測每個時間點上的觀測值只有一個,而多變量預測則有多個。與生成實驗用時間序列數(shù)據(jù)不同,使用TFTS讀入CSV文件首先需要引入文件并且需要通過column_names參數(shù)告訴TFTS文件中那些是時間,那些是觀測量。具體實現(xiàn)代碼如下:
csv_file_name= path.join("./data/multivariate_periods.csv")
reader =tf.contrib.timeseries.CSVReader(
column_names=((tf.contrib.timeseries.TrainEvalFeatures.TIMES,) #觀測時間
+(tf.contrib.timeseries.TrainEvalFeatures.VALUES,) * 5)) #觀測量
train_input_fn= tf.contrib.timeseries.RandomWindowInputFn(
reader, batch_size=4,window_size=32)
唯一區(qū)別于單變量時間序列預測的在于,由于每個觀測時間對應的觀測量有5個,num_features=5。
estimator= ts_estimators.TimeSeriesRegressor(
model=_LSTMModel(num_features=5,num_units=128),
optimizer=tf.train.AdamOptimizer(0.001))
與單變量原理及代碼相同,這里就不再重復。同樣,最后的運行結(jié)果會保存成“predict_result.jpg”文件,如下圖所示:
通過上述兩個案例分析可以發(fā)現(xiàn),在TensorFlow框架下引入LSTM模型會很好的對單變量時間序列和多變量時間序列進行預測,預測線條與實際線條接近重合,預測效果非常直觀,見上面圖中運行結(jié)果。
本文首先介紹了TensorFlow深度學習框架和LSTM網(wǎng)絡的基本概念。通過單變量時間序列預測和多變量時間序列預測兩個案例,詳細地用實例代碼介紹了TensorFlow引入的LSTM模型。從兩次預測結(jié)果可以發(fā)現(xiàn),預測均取得了較好的效果。該模型可用于解決實際工作中的一些時間序列預測問題,具有一定的實際意義。