1. 程式人生 > >Keras中長短期記憶網路LSTM的5步生命週期

Keras中長短期記憶網路LSTM的5步生命週期

                           Keras中長短期記憶網路LSTM的5步生命週期

       使用Keras在Python中建立和評估深度學習神經網路非常容易,但您必須遵循嚴格的模型生命週期。

      在這篇文章中,您將發現在Keras中建立,訓練和評估長期短期記憶(LSTM)迴歸神經網路的分步生命週期,以及如何使用訓練有素的模型進行預測。

閱讀這篇文章後,你會知道:

如何在Keras中定義,編譯,擬合和評估LSTM。
如何為迴歸和分類序列預測問題選擇標準預設值。
如何將它們結合在一起,在Keras開發和執行您的第一個LSTM迴圈神經網路。

Overview
下面概述了我們將要研究的Keras LSTM模型生命週期中的5個步驟。

定義網路
編譯網路
擬合網路
評估網路
作出預測
環境
     本教程假設您已安裝Python SciPy環境。 您可以在此示例中使用Python 2或3。本教程假設您安裝了TensorFlow或Theano後端的Keras v2.0或更高版本。本教程還假設您安裝了scikit-learn,Pandas,NumPy和Matplotlib。接下來,讓我們看看標準時間序列預測問題,我們可以將其用作此實驗的上下文。

步驟1.定義網路
      第一步是定義您的網路。神經網路在Keras中被定義為層序列。 這些圖層的容器是Sequential類。第一步是建立Sequential類的例項。 然後,您可以建立圖層並按照它們應連線的順序新增它們。 由儲存器單元組成的LSTM迴圈層稱為LSTM()。 通常跟隨LSTM層並用於輸出預測的完全連線層稱為Dense()。

      例如,我們可以分兩步完成:

model = Sequential()
model.add(LSTM(2))
model.add(Dense(1))

        但是我們也可以通過建立一個層陣列並將其傳遞給sequence的建構函式來一步完成。

layers = [LSTM(2), Dense(1)]
model = Sequential(layers)

        網路的第一層必須定義預期的輸入數量。輸入必須是三維的,包括樣本、步長和特徵。

        樣本。這些是資料中的行。

        步長。這些是對某個特性(如延遲變數)的過去觀察。

        特性。這些是資料中的列。

       假設您的資料作為一個NumPy陣列載入,您可以使用NumPy中的重塑()函式將2D資料集轉換為3D資料集。如果您希望列成為某個特性的時間步驟,可以使用:

data = data.reshape((data.shape[0], data.shape[1], 1))

      如果您希望2D資料中的列使用單步長,可以使用:

data = data.reshape((data.shape[0], 1, data.shape[1]))

       您可以指定input_shape引數,該引數期望一個包含時間步長和特徵數量的元組。例如,對於單變數時間序列,如果我們有兩個時間步驟和一個特徵,每一行有兩個滯後觀測值,它將被指定如下:

model = Sequential()
model.add(LSTM(5, input_shape=(2,1)))
model.add(Dense(1))

      可以通過將LSTM層新增到順序模型中來堆疊它們。重要的是,在疊加LSTM層時,我們必須為每個輸入輸出一個序列,而不是單個值,以便後續的LSTM層可以擁有所需的3D輸入。我們可以通過將return_sequences引數設定為True來實現這一點。例如:

model = Sequential()
model.add(LSTM(5, input_shape=(2,1), return_sequences=True))
model.add(LSTM(5))
model.add(Dense(1))

       可以將順序模型看作是一個管道,在管道的末端輸入原始資料,在管道的另一端輸出預測。在Keras中,這是一個有用的容器,傳統上與層關聯的關注點也可以分離出來,並作為單獨的層新增,清楚地顯示它們在從輸入到預測的資料轉換中的角色。

      例如,可以提取從層中的每個神經元轉換求和訊號的啟用函式,並將其作為類層物件(稱為啟用)新增到序列中。

model = Sequential()
model.add(LSTM(5, input_shape=(2,1)))
model.add(Dense(1))
model.add(Activation('sigmoid'))

        啟用函式的選擇對於輸出層來說是最重要的,因為它將定義預測所採用的格式。

        例如,下面是一些常見的預測建模問題型別,以及可以在輸出層使用的結構和標準啟用函式:

        迴歸:線性啟用函式,或“線性”,以及匹配輸出數量的神經元數量。

        二元分類(2類):邏輯啟用函式,或稱“乙狀結腸”,輸出層有一個神經元。

       多類分類(>2類):Softmax啟用函式,或“Softmax”,每個類值有一個輸出神經元,假設有一個熱編碼輸出模式。

 

      步驟2:編譯網路

       一旦定義了網路,就必須編譯它。編譯是一個有效的步驟。它將我們定義的簡單層序列轉換為一組高效的矩陣轉換,其格式旨在在GPU或CPU上執行,具體取決於如何配置Keras。可以將編譯看作是網路的預計算步驟。定義模型之後總是需要它。編譯需要指定許多引數,這些引數是專門為訓練您的網路而定製的。具體來說,用優化演算法來訓練網路,用損失函式來評價被優化演算法最小化的網路。例如,下面是一個編譯已定義模型並指定隨機梯度下降(sgd)優化演算法和均值平方誤差(mean_squared_error)損失函式的例子,這是一個迴歸型別問題。

model.compile(optimizer='sgd', loss='mean_squared_error')

     另外,優化器可以在作為編譯步驟的引數提供之前建立和配置。

algorithm = SGD(lr=0.1, momentum=0.3)
model.compile(optimizer=algorithm, loss='mean_squared_error')

         預測建模問題的型別對可以使用的損失函式的型別施加了約束。

        例如,以下是針對不同預測模型型別的一些標準損失函式:

         迴歸:平均平方誤差或“平均平方誤差”。

         二元分類(2類):對數損失,也稱為交叉熵或“binary_crossentropy”。

         多類分類(>2類):多類對數損失或“categorical_crossentropy”。

        最常見的優化演算法是隨機梯度下降,但Keras還支援一組其他最先進的優化演算法,這些演算法在配置很少或沒有配置的情況下工作良好。也許最常用的優化演算法,因為他們通常更好的效能是:

         隨機梯度下降法(sgd):需要調整學習速率和動量。

         ADAM:需要調整學習速度。

         RMSprop:需要調整學習速率。

        最後,除了損失函式之外,您還可以指定在擬合模型時要收集的指標。通常,需要收集的最有用的附加度量是分類問題的準確性。要收集的指標由陣列中的名稱指定。

       例如:

model.compile(optimizer='sgd', loss='mean_squared_error', metrics=['accuracy'])

        步驟3:擬合網路

       一旦網路被編譯,它就可以被擬合,這意味著調整訓練資料集上的權重。擬合網路需要指定訓練資料,輸入模式矩陣X和匹配輸出模式陣列y。利用反向傳播演算法對網路進行訓練,並根據優化演算法和模型編譯時指定的損失函式進行優化。反向傳播演算法要求對網路進行特定次數的訓練。每個epoch可以劃分為一組稱為批的輸入-輸出模式對。這定義了網路在一個epoch內更新權重之前所暴露的模式的數量。它也是一種效率優化,確保一次不會有太多的輸入模式載入到記憶體中。

         擬合網路的最小例子如下:

history = model.fit(X, y, batch_size=10, epochs=100)

        一旦擬合,將返回一個history物件,該物件提供訓練期間模型效能的摘要。這既包括損失,也包括在編譯模型時指定的任何額外指標,記錄每個epoch。訓練可能需要很長時間,根據網路的大小和訓練資料的大小,從幾秒鐘到幾小時到幾天不等。預設情況下,命令列上會顯示每個紀元的進度條。這可能會給您帶來太多的噪音,或者可能會給您的環境帶來問題,例如,如果您在互動式筆記本或IDE中。通過將詳細引數設定為2,可以將顯示的資訊量減少到每個epoch的損失。您可以通過將verbose設定為1關閉所有輸出。

      例如:

history = model.fit(X, y, batch_size=10, epochs=100, verbose=1)

       步驟4:評估網路

      一旦網路被訓練,它就可以被評估。可以根據訓練資料對網路進行評估,但這不能作為預測模型提供網路效能的有用指示,因為以前已經看到了所有這些資料。我們可以在一個單獨的資料集上評估網路的效能,在測試期間是看不到的。這將提供網路在預測未來不可見資料方面的效能評估。模型評估跨所有測試模式的損失,以及在編譯模型時指定的任何其他度量,如分類精度。返回一個評估指標列表。

       例如,對於使用精度度量標準編譯的模型,我們可以在新的資料集上對其進行如下評估:

                                  損失,精度=模型。評估(X, y)

loss, accuracy = model.evaluate(X, y)

       通過對網路的擬合,給出了詳細的輸出,給出了評價模型的進展情況。我們可以通過將詳細引數設定為0來關閉它。

loss, accuracy = model.evaluate(X, y, verbose=0)

        第5步:作出預測

       一旦我們對fit模型的效能感到滿意,就可以使用它對新資料進行預測。這與在模型上使用新的輸入模式陣列呼叫predict()函式一樣簡單。
例如:

predictions = model.predict(X)

        預測將以網路輸出層提供的格式返回。在迴歸問題中,這些預測可能直接以問題的形式出現,由線性啟用函式提供。對於二元分類問題,預測可能是第一類的概率陣列,可以通過四捨五入將其轉換為1或0。對於多類分類問題,結果可能以概率陣列的形式出現(假設一個熱編碼輸出變數),可能需要使用argmax() NumPy函式將其轉換為單個類輸出預測。另外,對於分類問題,我們可以使用predict_classes()函式,該函式將自動將不清晰的預測轉換為清晰的整數類值。

predictions = model.predict_classes(X)

        通過對網路進行擬合和評價,給出了詳細的輸出,以瞭解模型預測的進展情況。我們可以通過將詳細引數設定為0來關閉它。

predictions = model.predict(X, verbose=0)

        端到端工作的例子

       讓我們用一個簡單的例子把所有這些聯絡起來。本例將使用一個簡單的問題來學習10個數字序列。我們將向網路顯示一個數字,如0.0,並期望它預測0.1。然後顯示它0.1,並期望它預測0.2,以此類推到0.9。

        定義網路:我們將構建一個LSTM神經網路,在可見層有1個輸入時間步和1個輸入特徵,在LSTM隱層有10個記憶單元,在完全連線的輸出層有1個神經元,具有線性(預設)啟用函式。

         編譯網路:由於是一個迴歸問題,我們將使用具有預設配置和均方誤差損失函式的高效ADAM優化演算法。

         擬合網路:擬合網路1000個時點,使用與訓練集中模式數量相等的批處理大小,關閉所有冗餘輸出。

         評估網路。我們將在訓練資料集上對網路進行評估。通常我們會在測試或驗證集上評估模型。

        作出預測。我們將對訓練輸入資料進行預測。通常我們會對不知道正確答案的資料進行預測。

        下面提供了完整的程式碼清單:

# Example of LSTM to learn a sequence
from pandas import DataFrame
from pandas import concat
from keras.models import Sequential
from keras.layers import Dense
from keras.layers import LSTM
# create sequence
length = 10
sequence = [i/float(length) for i in range(length)]
print(sequence)
# create X/y pairs
df = DataFrame(sequence)
df = concat([df.shift(1), df], axis=1)
df.dropna(inplace=True)
# convert to LSTM friendly format
values = df.values
X, y = values[:, 0], values[:, 1]
X = X.reshape(len(X), 1, 1)
# 1. define network
model = Sequential()
model.add(LSTM(10, input_shape=(1,1)))
model.add(Dense(1))
# 2. compile network
model.compile(optimizer='adam', loss='mean_squared_error')
# 3. fit network
history = model.fit(X, y, epochs=1000, batch_size=len(X), verbose=0)
# 4. evaluate network
loss = model.evaluate(X, y, verbose=0)
print(loss)
# 5. make predictions
predictions = model.predict(X, verbose=0)
print(predictions[:, 0])

      執行此示例將生成以下輸出,顯示10個數字的原始輸入序列、預測整個序列時網路的平均平方誤差損失以及每個輸入模式的預測。為了便於閱讀,輸出被隔開了。我們可以看到,這個數列學得很好,尤其是如果我們把預測四捨五入到小數點前一位。

[0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9]

4.54527471447e-05

[ 0.11612834 0.20493418 0.29793766 0.39445466 0.49376178 0.59512401
0.69782174 0.80117452 0.90455914]