如何用LSTMs做預測?(附代碼)| 博士帶你學LSTM

 2019-03-26 14:00:03.0

本文的作者對此書進行了翻譯整理之後,分享給大家,本文是第十三期內容。

第一期內容爲:一萬字純乾貨|機器學習博士手把手教你入門LSTM(附代碼資料)

第二期內容爲:乾貨推薦|如何基於時間的反向傳播算法來訓練LSTMs?

第三期內容爲:乾貨推薦|如何準備用於LSTM模型的數據並進行序列預測?(附代碼)

第四期內容爲:機器學習博士帶你入門|一文學會如何在Keras中開發LSTMs(附代碼)

第五期內容爲:初學者如何避免在序列預測問題中遇到的陷阱?

第六期內容爲:如何開發和評估Vanilla LSTM模型?

第七期內容爲:博士帶你學LSTM|怎麼樣開發Stacked LSTMs?(附代碼)

第八期內容爲:博士帶你學LSTM|手把手教你開發CNN LSTM模型,並應用在Keras中(附代碼)

第九期內容爲:博士帶你學LSTM|開發Encoder-Decoder LSTM模型的簡單教程(附代碼)

第十期內容爲:博士帶你學LSTM|開發Bidirectional LSTM模型的簡單教程(附代碼)

第十一期內容爲:博士帶你學LSTM|怎麼開發一個LSTM模型來生成形狀?(附代碼)

第十二期內容爲:博士帶你學LSTM|如何使用學習曲線來診斷你的LSTM模型的行爲?(附代碼)

我們還將繼續推出一系列的文章來介紹裏面的詳細內容,和大家一起來共同學習。

13.0 前言

13.0.1 課程目標

本課程的目標是學習怎麼樣完成一個LSTM模型,並用它在新數據上做預測。完成本課的學習之後,你將會學習到:

  • 怎麼樣爲你的工程開發一個最終的LSTM模型;

  • 怎麼樣將LSTM模型保存到文件以便後面使用;

  • 怎麼樣在新的數據上加載LSTM模型來做預測。

13.0.2 課程概覽

本課程分爲三個部分,它們是:

  1. 什麼是最終LSTM模型;

  2. 將LSTM模型保存到文件;

  3. 在新數據上做預測。

讓我們開始吧!

13.1 完成一個LSTM模型

在本節中,你將會學習到怎麼樣去完成你的LSTM模型。

13.1.1 什麼是一個最終LSTM模型?

在本章節中,你將會發現怎麼樣定型你的LSTM模型。

最後一個LSTM模型是用來預測新數據的模型。也就是說,給定輸入數據的新示例,你希望在使用該模型來預測預期輸出。這可以是一個分類(指定一個標籤)或一個迴歸(一個實值)。你的序列預測項目的目標達到一個最好的模型,其中最好的定義是:

  • 數據:你可用的歷史數據;

  • 時間:工程上你必須花費的時間;

  • 過程:數據準備步驟,算法,以及所選擇的算法配置;

在你的工程中,你將數據聚在一起,花費你的時間,並發現數據準備過程,使用的算法,以及如何配置它。這個模型是這個過程的頂點,你尋找的目的是爲了開始實際的預測。沒有完美的模型。你能夠發現的只有最好的模型。

13.1.2 使用訓練或測試集的目的

創建你數據集的訓練和測試拆分是一種快速評估算法對問題性能的方法。訓練數據集被用來準備模型,訓練它。我們假設測試數據集是新的數據,其中輸出值從算法中被保留。我們從訓練模型中手機來自測試數據集測輸入的預測,並將它們與測試集的保留輸出值進行比較。

將測試與預測數據集中的保留輸出進行比較,使我們能夠在測試數據集上計算模型的性能度量。這是在對未知數據進行預測時對爲進行訓練的算法的技巧的估計。使用K折交叉驗證是一種更穩健和更昂貴的計算方法。我們使用我們在訓練數據集上的LSTM模型技能的估計作爲代理來估計在新的數據集上做預測時,模型的技能會是什麼樣的。

這是一個相當大的飛躍,需要:

  • 你所使用的程序是非常穩健的,技能的估計接近我們對未知數據的實際期望;

  • 性能測量的選擇準確地捕獲了我們對未知數據的預測感興趣的測量;

  • 數據準備的選擇在新數據上是很好理解的並且可重複的,如果預測需要返回到其原始規模或與原始輸入值相關則並且是可逆的;

  • 模型架構和配置的選擇對於其預期使用和操作環境(例如複雜性)是有意義的。

很多騎上在測試集或k折交叉驗證程序的整個過程的估計技能。

13.1.3 怎麼樣最終化LSTM模型?

通過在所有數據上應用所選擇的LSTM體系結構和配置來完成模型。沒有訓練和測試分割,沒有交叉驗證摺疊。把所有的數據重新組合到一個大的訓練數據集中,並擬合你的模型。就是這樣。用最終的模型,你可以:

  • 保存模型用於以後或操作使用;

  • 加載模型並對新數據進行預測。

爲什麼不保持最好的訓練模式呢?

你的LSTM模型可能需要數天或者數週來準備。在這種情況下,你可能希望將模型保持在訓練數據集上,而不是需要在訓練和測試集的組合上。這是對附加數據進行模型訓練的可能條件和用於擬合新模型的時間和計算成本之間的權衡。

最終模型上的性能會不一樣嗎?

使用魯棒的測試線束的全部想法是估計最終模型的技能。理想情況下,估計與最終模型中觀察到的技能之間的差異在測量誤差點上是次要的,或者技能被提升爲用於弄下的訓練實例的數量的函數。你可以通過對模型技能與訓練實例的數量進行敏感性分析來測試這兩個假設。

每次訓練的最後模式不會不同嗎?

你用來選擇最終模型的技能估計應該在多次運行中進行平均。這樣,你知道,平均所選的模型架構和配置是熟練的。你可以嘗試通過訓練多個最終模型和在實踐中使用它們的預測的集合或平均來控制模型的隨機性質。同樣,你可以設計一個靈敏度分析來測試這是否會導致一組更穩定的預測。

13.2 把LSTM模型保存到文件

Keras提供了一個API來允許你將你的模型保存爲文件。有兩個選項:

  1. 將模型保存爲一個單一的文件;

  2. 將模型的結構和權重分開保存爲文件。

在這兩種情況下,使用HDF5文件格式來在磁盤上大量存儲大量的數字。你需要確認你安裝了h5py的Python庫。可以安裝如下:

 
   
   
   
  1. sudo pip install h5py

表 13.1 安裝所需的h5py Python庫

13.2.1 保存爲單一文件

你可以使用模型的save()函數保存一個擬合的Keras模型到文件。例如:

 
   
   
   
  1. # define model model = Sequential()

  2. model.add(LSTM(...))

  3. # compile model

  4. model.compile(...)

  5. # fit model

  6. model.fit(...)

  7. # save model to single file

  8. model.save( 'lstm_model.h5' )

表 13.2 保存擬合LSTM模型到一個單一文件的例子

這個單一文件包含模型結構和權重。它還包括制定的損失和優化算法的規範,以便你可以恢復訓練。該模型可以使用load_model()函數來再次加載(來自於不同的Python會話中的不同腳本)。

 
   
   
   
  1. from keras.models import load_model

  2. # load model from single file

  3. model = load_model( 'lstm_model.h5' )

  4. # make predictions

  5. yhat = model.predict(X, verbose=0)

  6. print(yhat)

表 13.3 從單一文件中加載一個保存了的LSTM模型的例子

下面是一個完整的LSTM模型的例子,將它保存到一個文件中,然後加載它。雖然模型的加載在同一個腳本中,但是這個部分可以從另一個Python會話中的另一個腳本運行。運行例子將模型保存到文件lstm_model.h5文件中。

 
   
   
   
  1. from keras.models import Sequential

  2. from keras.layers import Dense

  3. from keras.layers import LSTM

  4. from numpy import array

  5. from keras.models import load_model

  6. # return training data

  7. def get_train():

  8. seq = [[0.0, 0.1], [0.1, 0.2], [0.2, 0.3], [0.3, 0.4], [0.4, 0.5]]

  9. seq = array(seq)

  10. X, y = seq[:, 0], seq[:, 1]

  11. X = X.reshape((len(X), 1, 1))

  12. return X, y

  13. # define model

  14. model = Sequential()

  15. model.add(LSTM(10, input_shape=(1,1)))

  16. model.add(Dense(1, activation= 'linear' ))

  17. # compile model

  18. model.compile(loss= 'mse' , optimizer= 'adam' )

  19. # fit model

  20. X,y = get_train()

  21. model.fit(X, y, epochs=300, shuffle=False, verbose=0)

  22. # save model to single file

  23. model.save( 'lstm_model.h5' )

  24. # snip...

  25. # later, perhaps run from another script

  26. # load model from single file

  27. model = load_model( 'lstm_model.h5' )

  28. # make predictions

  29. yhat = model.predict(X, verbose=0)

  30. print(yhat)

表 13.4 保存一個擬合的LSTM模型到一個單一的文件並稍後再次加載它的例子

13.2.2 保存到分開的文件

你可以保存模型的結構(例如,層和它們間是如何連接的)和權重(數字的數組)到分別的文件中。我推薦這種方法,因爲它允許你開發更新的模型權重並替換一個模型,同時確保模型的結構保持不變。

保存結構

Keras提供了兩種保存模型結構的格式:JSON和YAML格式。這些格式的好處是它們是人類可讀的。選擇實際上是一個口味和偏好的問題。可以調用tojson()或者toyaml()函數來將你的模型分別保存爲JSON或者YAML格式的文件。它們返回一個標準的字符串,你可以使用標準的Python文件open()和write()函數將這個字符串保存爲一個ASCII文件到硬盤。

 
   
   
   
  1. ...

  2. # convert model architecture to JSON format

  3. architecture = model.to_json()

  4. # save architecture to JSON file

  5. with open( 'architecture.json' , 'wt' ) as json_file:

  6. json_file.write(architecture)

表 13.5 保存一個擬合LSTM模型結構到文件的例子

使用 modelfromjson()或者 modelfromyaml()函數,模型結構可以被再次加載(在不同的Python會話中從不同的腳本加載)。一旦加載,modelfromjson()或者 modelfromyaml()函數可以被用作從結構中產生一個Keras模型。

 
   
   
   
  1. from keras.models import model_from_json

  2. # load architecture from JSON File

  3. json_file = open( architecture.json , rt )

  4. architecture =

  5. json_file.read()

  6. json_file.close()

  7. # create model from architecture

  8. model = model_from_json(architecture)

表 13.6 從文件中加載一個保存了的LSTM模型結構的例子

保存權重

Keras提供了一個函數在擬合模型上保存模型權重。save_weights()函數將會保存模型權重到HDF5格式文件。

 
   
   
   
  1. ...

  2. # save weights to hdf5 file

  3. model.save_weights( 'weights.h5' )

表 13.7 保存一個擬合了的LSTM模型權重到文件的例子

模型權重可以被再次加載(在不同腳本的不同的Python會話中使用load_weights()函數來加載模型對象)。這意味着你必須依據有了一個模型,要麼重新創建,要麼從加載的結構創建。

 
   
   
   
  1. ...

  2. # save weights to hdf5 file

  3. model.load_weights( 'weights.h5' )

表 13.8 從文件中加載一個保存了的LSTM模型權重的例子

例子

我們可以把它們組合成一個單獨工作的例子。下面的演示合適於一個小型的數據集上的LSTM模型。模型結構採用JSON格式保存,模型權值以HDF5格式存儲。如果你願意,可以很容易地更改例子以保存爲YAML格式的結構。然後從這些文件中加載模型並進行預測。

 
   
   
   
  1. from keras.models import Sequential

  2. from keras.layers import Dense

  3. from keras.layers import LSTM

  4. from numpy import array

  5. from keras.models import model_from_json

  6. import os

  7. os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'

  8. # return training data

  9. def get_train():

  10. seq = [[0.0, 0.1], [0.1, 0.2], [0.2, 0.3], [0.3, 0.4], [0.4, 0.5]]

  11. seq = array(seq)

  12. X, y = seq[:, 0], seq[:, 1]

  13. X = X.reshape((len(X), 1, 1))

  14. return X, y

  15. # define model

  16. model = Sequential()

  17. model.add(LSTM(10, input_shape=(1,1)))

  18. model.add(Dense(1, activation= 'linear' ))

  19. # compile model

  20. model.compile(loss= 'mse' , optimizer= 'adam' )

  21. # fit model

  22. X,y = get_train()

  23. model.fit(X, y, epochs=300, shuffle=False, verbose=0)

  24. # convert model architecture to JSON format

  25. architecture = model.to_json()

  26. # save architecture to JSON file

  27. with open( 'architecture.json' , 'wt' ) as json_file:

  28. json_file.write(architecture)

  29. # save weights to hdf5 file

  30. model.save_weights( 'weights.h5' )

  31. # snip...

  32. # later, perhaps run from another script

  33. # load architecture from JSON File

  34. json_file = open( 'architecture.json' , 'rt' )

  35. architecture = json_file.read()

  36. json_file.close()

  37. # create model from architecture

  38. model = model_from_json(architecture)

  39. # load weights from hdf5 file

  40. model.load_weights( 'weights.h5' )

  41. # make predictions

  42. yhat = model.predict(X, verbose=0)

  43. print(yhat)

表 13.9 保存一個擬合LSTM模型到分別的文件並稍後再次加載它的例子

運行這個例子保存模型結構到architecture.json文件並保存權重到weights.h5文件。然後從這些相同的文件加載模型。雖然模型加載在同一個腳本中演示,但是也可以在另外另外一個腳本文件的一個Python會話中輕鬆地運行該段腳本。

13.3 在新數據上做預測

在進行預測之前,對你的訓練數據進行任何數據準備也必須應用於任何新的數據。例如,如果你的訓練數據被標準化,那麼所有你希望預測的新數據也必須被規範化。反過來,這意味着,用於規範數據(例如,最大值和最小值)的稀疏必須保存爲模型化的一部分,並在需要預測時加載。

這適用於其他形式的數據準備,例如對數變換、標準化值和使系列平穩。原始數據被轉換成其矢量化形式的特定方式也必須被複制。這包括序列的填充或截斷,並且重要的是,將原始序列整形成樣本的3D格式、時間步長和特徵。

根據問題的框架,預測時的樣本數可以指輸入輸出序列的數量,以便於輸出預測。對於單個預測,它可能是1。想想所有在將原始數據轉換成用於訓練作爲管道的模型的數據時所做的數據準備。這個管道也必須在任何時候進行預測。

13.3.2 預測值

預測是很容易的一部分。我們在第4張中介紹了基本API,但是我們將更加詳細地複習它。它包括將準備好的輸入數據(X)和調用Keras預測方法之一加載模型。記住,用於預測(X)的輸入僅由預測所需的輸入序列數組成,而不是所有先前的訓練數據。在預測一個序列中的下一個值的情況下,輸入序列將是1個樣本,具有固定的時間步長和在定義和擬合模型時使用的特徵。

例如,在輸出層的激活函數的形狀和尺度上的原始預測可以通過調用模型上的predict()函數來實現:

 
   
   
   
  1. X = ...

  2. model = ...

  3. yhat = model.predict(X)

表 13.10 在新數據上用一個擬合的LSTM模型做預測的例子

預測一個類的索引可以通過在模型上調用predict_classes()函數實現。

 
   
   
   
  1. X = ...

  2. model = ...

  3. yhat = model.predict_classes(X)

表 13.11 在新數據上用一個擬合的LSTM模型預測分類的例子

預測可能性可以通過在模型上調用predict_proba()函數來實現。

 
   
   
   
  1. X = ...

  2. model = ...

  3. yhat = model.predict_proba(X)

表 13.12 在新數據上用一個擬合LSTM預測可能性的例子

13.4 擴展閱讀

13.4.1 API

  • How can I save a Keras model? in the Keras FAQ.

  • Save and Load Keras API.

13.5 擴展

你想更深入地學習一個完成LSTM模型嗎?本章節列出了本課程中的一些有挑戰性的擴展:

  • 列出一個或多個預測問題,在這裏你想開發一個LSTM模型並保存它用於以後的預測中;

  • 從書中的模型部分更新一個例子,以將模型保存到多個文件中,然後再次從另外一個腳本加載並進行預測;

  • 從書中的模型部分更新一個示例,用一個分類輸出來預測概率,並以圖形方式呈現概率;

  • 從書中的模型部分更新一個示例,使用一個分類輸出來使用predict()函數,然後使用argmax()函數來將結果解釋爲類值;

  • 從書中模型部分選擇一個例子,通過聚焦模型結構(例如,層數、存儲單元等)來調優性能。你可能需要增加問題的難度。

  • 從書中模型部分選擇一個例子,並通過關注模型行爲(例如,週期數、訓練例子、批次等)來調整性能。你可能需要增加這個問題的難度。

13.6 總結

在本章節中你學習到了在更新你的最終化的LSTM模型中充分利用新數據。特別地,你學習到了:

  • 怎麼樣爲你的工程開發一個最終的LSTM模型;

  • 怎麼樣將LSTM模型保存到文件以便後面使用;

  • 怎麼樣在新的數據上加載LSTM模型來做預測。

在下面的課程中,你將會學習到怎麼樣更新一個完成的LSTM模型來充分利用新數據。

文章來源:機器之心