本文經「機器人圈「ROBO_AI」」微信公眾號授權轉載!
不知道在訓練模型的過程中,你有沒有遇到這樣一個問題,很難確定你的長短期記憶網路模型是否在序列問題上表現良好。也許在模型技能上你會獲得一個不錯的分數,但是更為重要的是,要知道你的模型是否與你的數據擬合良好,或者欠擬合,或者過度擬合,以及是否能夠在不同的配置中做得更好。
在本教程中,你將知曉如何診斷LSTM模型在序列預測問題上的擬合問題。
完成本教程后,你將學會:
如何收集和繪製LSTM模型的訓練歷史。
如何診斷一個欠擬合、擬合和過度擬合模型。
如何通過平均多模型運行來開發更具魯棒性的診斷。
那接下來就開啟我們的探索之旅吧。
教程概述
本教程共分為6部分,它們分別是:
用Keras進行的訓練史
診斷圖
欠擬合範例
擬合良好範例
過度擬合範例
多次運行範例
1.用Keras進行的訓練史
你可以通過回顧它在過去時間裡的性能情況來了解模型行為。
通過調用fit函數訓練LSTM模型。此函數返回一個名為history的變數,其中包含損失追蹤以及在編譯模型時指定的任何其他指標。這些分數都記錄在每個訓練輪數的末尾。
...
history = model.fit(...)
例如,如果你的模型被編譯為優化日誌丟失(binary_crossentropy)並且測量每個訓練輪數的精確度,那麼會將損失和精確度記錄在每個訓練輪數的歷史軌跡中。
通過調用fit函數返回的歷史對象中的一個鍵即可訪問每個評分。默認情況下,在擬合模型過程中優化的損耗稱為「loss」,精確度稱為「acc」。
...
model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])
history = model.fit(X, Y, epochs=100)
print(history.history['loss'])
print(history.history['acc'])
在擬合模型的過程中,Keras允許你指定一個單獨的驗證數據集,同時也可以使用相同的損失和指標進行評估。
這可以通過在fit上設置validation_split參數,從而將訓練數據的一部分用作驗證數據集來實現。
...
history = model.fit(X, Y, epochs=100, validation_split=0.33)
這也可以通過設置validation_data參數並傳遞一個X和y數據集的元組來完成。
...
history = model.fit(X, Y, epochs=100, validation_data=(valX, valY))
在驗證數據集上評估的指標可以通過使用相同的名稱鍵入,即「val_」前綴。
...
model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])
history = model.fit(X, Y, epochs=100, validation_split=0.33)
print(history.history['loss'])
print(history.history['acc'])
print(history.history['val_loss'])
print(history.history['val_acc'])
2.診斷圖
關於LSTM模型的訓練史可用於診斷模型的行為。
你可以使用Matplotlib庫繪製模型的性能圖。 例如,你可以繪製如下訓練損失VS測試損失圖:
from matplotlib import pyplot
...
history = model.fit(X, Y, epochs=100, validation_data=(valX, valY))
pyplot.plot(history.history['loss'])
pyplot.plot(history.history['val_loss'])
pyplot.title('model train vs validation loss')
pyplot.ylabel('loss')
pyplot.xlabel('epoch')
pyplot.legend(['train', 'validation'], loc='upper right')
pyplot.show
創建並回顧這些圖可以幫助你知曉那些可能的新配置,以便從模型中獲得更好的性能。
接下來,我們將查看一些範例。 我們將根據損失最小化來考慮訓練和驗證集上的模型技能。當然,你可以使用對你的問題有意義的任何指標。
3.欠擬合範例
什麼是欠擬合?所謂欠擬合就是說,一個在訓練數據集上表現良好,但在測試數據集上表現不佳的模型。
這可以從一個訓練損失低於驗證損失的繪製圖中得以診斷,且驗證損失具有表明進一步改進有可能實現的趨勢。
下面提供了一個小巧的欠擬合LSTM模型的例子。
from keras.models import Sequential
from keras.layers import Dense
from keras.layers import LSTM
from matplotlib import pyplot
from numpy import array
# return training data
def get_train:
seq = [[0.0, 0.1], [0.1, 0.2], [0.2, 0.3], [0.3, 0.4], [0.4, 0.5]]
seq = array(seq)
X, y = seq[:, 0], seq[:, 1]
X = X.reshape((len(X), 1, 1))
return X, y
# return validation data
def get_val:
seq = [[0.5, 0.6], [0.6, 0.7], [0.7, 0.8], [0.8, 0.9], [0.9, 1.0]]
seq = array(seq)
X, y = seq[:, 0], seq[:, 1]
X = X.reshape((len(X), 1, 1))
return X, y
# define model
model = Sequential
model.add(LSTM(10, input_shape=(1,1)))
model.add(Dense(1, activation='linear'))
# compile model
model.compile(loss='mse', optimizer='adam')
# fit model
X,y = get_train
valX, valY = get_val
history = model.fit(X, y, epochs=100, validation_data=(valX, valY), shuffle=False)
# plot train and validation loss
pyplot.plot(history.history['loss'])
pyplot.plot(history.history['val_loss'])
pyplot.title('model train vs validation loss')
pyplot.ylabel('loss')
pyplot.xlabel('epoch')
pyplot.legend(['train', 'validation'], loc='upper right')
pyplot.show
運行這個例子將產生一個訓練和驗證損失的繪製圖,顯示了一個欠擬合模型的特徵。在這種情況下,通過增加訓練輪數的數量可以提高性能。
在這種情況下,通過增加訓練時期的數量可以提高性能。
診斷線圖顯示了一個欠擬合模型
或者,如果訓練集上的性能優於驗證集並且性能已經下降,那麼該模型也有可能是一個欠擬合模型。下面是一個沒有足夠記憶單元的欠擬合示例。
# return training data
def get_train:
seq = [[0.0, 0.1], [0.1, 0.2], [0.2, 0.3], [0.3, 0.4], [0.4, 0.5]]
seq = array(seq)
X, y = seq[:, 0], seq[:, 1]
X = X.reshape((5, 1, 1))
return X, y
# define model
model = Sequential
model.add(LSTM(1, input_shape=(1,1)))
model.add(Dense(1, activation='linear'))
# compile model
model.compile(loss='mae', optimizer='sgd')
# fit model
X,y = get_train
valX, valY = get_val
history = model.fit(X, y, epochs=300, validation_data=(valX, valY), shuffle=False)
# plot train and validation loss
pyplot.plot(history.history['loss'])
pyplot.plot(history.history['val_loss'])
pyplot.title('model train vs validation loss')
pyplot.ylabel('loss')
pyplot.xlabel('epoch')
pyplot.legend(['train', 'validation'], loc='upper right')
pyplot.show
運行此示例顯示出一個未能充分配置的模型的特徵。
在這種情況下,可以通過增加模型的容量來提高性能,例如隱藏層中的記憶單元的數量或隱藏層的數量。
診斷線圖通過狀態顯示了一個欠擬合模型
4.擬合示例
一個很好的擬合是指在訓練和驗證集上模型的性能都表現得很好。
這可以從訓練和驗證損失減少並在同一點穩定的情況下診斷。
下面的小例子演示了LSTM模型具有良好的擬合。
# define model
model = Sequential
model.add(LSTM(10, input_shape=(1,1)))
model.add(Dense(1, activation='linear'))
# compile model
model.compile(loss='mse', optimizer='adam')
# fit model
X,y = get_train
valX, valY = get_val
history = model.fit(X, y, epochs=800, validation_data=(valX, valY), shuffle=False)
# plot train and validation loss
pyplot.plot(history.history['loss'])
pyplot.plot(history.history['val_loss'])
pyplot.title('model train vs validation loss')
pyplot.ylabel('loss')
pyplot.xlabel('epoch')
pyplot.legend(['train', 'validation'], loc='upper right')
pyplot.show
運行示例創建一個顯示訓練和驗證損失相遇的線條圖。
理想情況下,如果可能的話,我們希望看到這樣的模型性能,儘管這可能不適用於具有大量數據的有挑戰性的問題。
診斷線圖顯示一個很好的擬合模型
5.過度擬合示例
過度擬合模型是一個在訓練上的性能良好並持續改進的模型,而驗證集上的性能提升到一個點,然後開始降級。
這可以從訓練損耗向下傾斜和驗證損失向下傾斜的曲線中診斷出來,碰到拐點,並再次開始向上傾斜。
下面的例子演示了一個LSTM過度擬合模型。
from keras.models import Sequential
from keras.layers import Dense
from keras.layers import LSTM
from matplotlib import pyplot
from numpy import array
# define model
model = Sequential
model.add(LSTM(10, input_shape=(1,1)))
model.add(Dense(1, activation='linear'))
# compile model
model.compile(loss='mse', optimizer='adam')
# fit model
X,y = get_train
valX, valY = get_val
history = model.fit(X, y, epochs=1200, validation_data=(valX, valY), shuffle=False)
# plot train and validation loss
pyplot.plot(history.history['loss'][500:])
pyplot.plot(history.history['val_loss'][500:])
pyplot.title('model train vs validation loss')
pyplot.ylabel('loss')
pyplot.xlabel('epoch')
pyplot.legend(['train', 'validation'], loc='upper right')
pyplot.show
運行此示例創建一個繪圖,顯示過度模型驗證損失中的特徵拐點。
這可能是訓練次數太多的特徵。
在這種情況下,模型訓練可以在拐點處停止。或者,可以增加訓練示例的數量。
診斷線圖顯示過度擬合模型
6.多次運行示例
LSTM是隨機的,這意味著每次運行你會得到一個不同的診斷圖。
重複診斷運行多次(例如5次,10次或30次)可能是有用的。然後,可以繪製每個運行的訓練和驗證軌跡,以便隨著時間的推移對模型的行為提供更具有魯棒性的想法。
以下示例運行多次相同的實驗,然後繪製每次運行的訓練軌跡和驗證損失。
from keras.models import Sequential
from keras.layers import Dense
from keras.layers import LSTM
from matplotlib import pyplot
from numpy import array
from pandas import DataFrame
# collect data across multiple repeats
train = DataFrame
val = DataFrame
for i in range(5):
# define model
model = Sequential
model.add(LSTM(10, input_shape=(1,1)))
model.add(Dense(1, activation='linear'))
# compile model
model.compile(loss='mse', optimizer='adam')
X,y = get_train
valX, valY = get_val
# fit model
history = model.fit(X, y, epochs=300, validation_data=(valX, valY), shuffle=False)
# story history
train[str(i)] = history.history['loss']
val[str(i)] = history.history['val_loss']
# plot train and validation loss across multiple runs
pyplot.plot(train, color='blue', label='train')
pyplot.plot(val, color='orange', label='validation')
pyplot.title('model train vs validation loss')
pyplot.ylabel('loss')
pyplot.xlabel('epoch')
pyplot.show
在生成的結果圖中,我們可以看到,五次運行的總體趨勢是持續不斷的,也許增加了訓練輪數的數量。
診斷線圖顯示模型的多個運行
進一步閱讀
如果你進一步了解,本部分將提供有關該主題的更多資源。
•Keras API回調函數的歷史(https://keras.io/callbacks/#history)
•維基百科上機器學習中的學習曲線(https://en.wikipedia.org/wiki/Learning_curve#In_machine_learning)
•在維基百科上的過度擬合(https://en.wikipedia.org/wiki/Overfitting)
C2
如何加入學會
註冊學會會員:
個人會員:
(c2_china),回復「個人會員」獲取入會申請表,按要求填寫申請表即可,如有問題,可在公眾號內進行留言。通過學會審核後方可在線進行支付寶繳納會費。
單位會員:
(c2_china),回復「單位會員」獲取入會申請表,按要求填寫申請表即可,如有問題,可在公眾號內進行留言。通過學會審核後方可繳納會費。
學會近期活動
1. CICC企業會員交流會
會議時間:(具體時間詳見後續通知)
2.2017首屆全國兵棋推演大賽總決賽
2017年9月25日
長按下方學會二維碼,關注學會微信
感謝關注