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

AMiner學術頭條發表於2019-03-26

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

第一期內容為:一萬字純乾貨|機器學習博士手把手教你入門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模型來充分利用新資料。

相關文章