手把手教你用Python庫Keras做預測(附代碼)

手把手教你用Python庫Keras做預測(附代碼)

翻譯:張逸

校對:馮羽

本文約2804字,建議閱讀7分鐘。

本文將教你如何使用Keras這個Python庫完成深度學習模型的分類與迴歸預測。

當你在Keras中選擇好最合適的深度學習模型,就可以用它在新的數據實例上做預測了。但是很多初學者不知道該怎樣做好這一點,我經常能看到下面這樣的問題:

“我應該如何用Keras對我的模型作出預測?”

在本文中,你會學到如何使用Keras這個Python庫完成深度學習模型的分類與迴歸預測。

看完這篇教程,你能掌握以下幾點:

  • 如何確定一個模型,為後續的預測做準備
  • 如何用Keras對分類問題進行類及其概率的預測
  • 如何用Keras進行迴歸預測

現在就讓我們開始吧

手把手教你用Python庫Keras做預測(附代碼)

本文結構

教程共分為三個部分,分別是:

  • 模型確定
  • 分類預測
  • 迴歸預測

模型確定

在做預測之前,首先得訓練出一個最終的模型。你可能選擇k折交叉驗證或者簡單劃分訓練/測試集的方法來訓練模型,這樣做的目的是為了合理估計模型在樣本集之外數據上的表現(新數據)

當評估完成,這些模型存在的目的也達到了,就可以丟棄他們。接下來,你得用所有的可用數據訓練出一個最終的模型。關於這方面的內容,你可以在下面這個文章中得到更多的信息:

https://machinelearningmastery.com/train-final-machine-learning-model/

分類預測

對於分類問題,模型學習的是一個輸入特徵到輸出特徵之間的映射,這裡的輸出即為一個標籤。比如“垃圾郵件”和“非垃圾郵件”

下邊是Keras中為簡單的二分類問題開發的神經網絡模型的一個例子。如果說你以前沒有接觸過用Keras開發神經網絡模型的話,不妨先看看下邊這篇文章:

https://machinelearningmastery.com/tutorial-first-neural-network-python-keras/

# 訓練一個最終分類的模型

from keras.models import Sequential

from keras.layers import Dense

from sklearn.datasets.samples_generator import make_blobs

from sklearn.preprocessing import MinMaxScaler

# 生成一個二分類問題的數據集

X, y = make_blobs(n_samples=100, centers=2, n_features=2, random_state=1)

scalar = MinMaxScaler()

scalar.fit(X)

X = scalar.transform(X)

# 定義並擬合模型

model = Sequential()

model.add(Dense(4, input_dim=2, activation='relu'))

model.add(Dense(4, activation='relu'))

model.add(Dense(1, activation='sigmoid'))

model.compile(loss='binary_crossentropy', optimizer='adam')

model.fit(X, y, epochs=200, verbose=0)

建立好這個模型後,可能需要將它保存到文件中(比如通過Keras的相關API)。以後你就可以隨時加載這個模型,並用它進行預測了。有關這方面的示例,可以參考下邊的文章:

https://machinelearningmastery.com/save-load-keras-deep-learning-models/

為了本文的結構更簡潔,我們的例子中省去了這個步驟。

繼續說回到分類預測的問題。我們希望最終得到的模型能進行兩種預測:一是判斷出類別,二是給出屬於相應類別概率。

  • 類預測

一個類別預測會給定最終的模型以及若干數據實例,我們利用模型來判斷這些實例的類別。對於新數據,我們不知道輸出的是什麼結果,這就是為什麼首先需要一個模型。

在Keras中,可以利用predict_class()函數來完成我們上述所說的內容----即利用最終的模型預測新數據樣本的類別。

需要注意的是,這個函數僅適用於Sequential模型,不適於使用功能式API開發的模型。(not those models developed using the functional API.)

比如,我們在名為Xnew的數組中有若干個數據實例,它被傳入predict_classes()函數中,用來對這些數據樣本的類別進行預測。

Xnew = [[...], [...]]

ynew = model.predict_classes(Xnew)

讓我們用一個更具體的例子來說明:

# 建立一個新的分類模型

from keras.models import Sequential

from keras.layers import Dense

from sklearn.datasets.samples_generator import make_blobs

from sklearn.preprocessing import MinMaxScaler

# 生成二分類數據集

X, y = make_blobs(n_samples=100, centers=2, n_features=2, random_state=1)

scalar = MinMaxScaler()

scalar.fit(X)

X = scalar.transform(X)

# 定義並擬合最終模型

model = Sequential()

model.add(Dense(4, input_dim=2, activation='relu'))

model.add(Dense(4, activation='relu'))

model.add(Dense(1, activation='sigmoid'))

model.compile(loss='binary_crossentropy', optimizer='adam')

model.fit(X, y, epochs=500, verbose=0)

# 新的未知數據實例

Xnew, _ = make_blobs(n_samples=3, centers=2, n_features=2, random_state=1)

Xnew = scalar.transform(Xnew)

# 作出預測

ynew = model.predict_classes(Xnew)

# 顯示輸入和輸出

for i in range(len(Xnew)):

print("X=%s, Predicted=%s" % (Xnew[i], ynew[i]))

下面是對三個實例預測的結果,我們將數據和預測結果一併輸出:

X=[0.89337759 0.65864154], Predicted=[0]

X=[0.29097707 0.12978982], Predicted=[1]

X=[0.78082614 0.75391697], Predicted=[0]

如果你只有一個新的實例,那就需要將它包裝一下,變成一個數組的形式。以便傳給predict_classes()函數,比如這樣:

from keras.models import Sequential

from keras.layers import Dense

from sklearn.datasets.samples_generator import make_blobs

from sklearn.preprocessing import MinMaxScaler

from numpy import array

# 生成一個二分類數據集

X, y = make_blobs(n_samples=100, centers=2, n_features=2, random_state=1)

scalar = MinMaxScaler()

scalar.fit(X)

X = scalar.transform(X)

# 定義並擬合最終的新模型

model = Sequential()

model.add(Dense(4, input_dim=2, activation='relu'))

model.add(Dense(4, activation='relu'))

model.add(Dense(1, activation='sigmoid'))

model.compile(loss='binary_crossentropy', optimizer='adam')

model.fit(X, y, epochs=500, verbose=0)

# 未知的新實例

Xnew = array([[0.89337759, 0.65864154]])

# 作出預測

ynew = model.predict_classes(Xnew)

# 顯示輸入輸出

print("X=%s, Predicted=%s" % (Xnew[0], ynew[0]))

運行上邊這個例子,會得到對這個單獨實例的預測結果

X=[0.89337759 0.65864154], Predicted=[0]

  • 關於類別標籤的注意事項

準備數據時,應該將其中的類別標籤轉換為整數表示(比如原始數據類別可能是一個字符串),這時候你就可能會用到sklearn中的LabelEncoder。

http://scikitlearn.org/stable/modules/generated/sklearn.preprocessing.LabelEncoder.html#sklearn.preprocessing.LabelEncoder

當然,在我們使用LabelEcoder中的函數inverse_transform()時,還可以將那些整數表示的類別標籤轉換回去。

因為這個原因,在擬合最終模型時,你可能想要保存用於編碼y值的LabelEncoder結果。

概率預測

另外一種是對數據實例屬於某一類的可能性進行預測。它被稱為“概率預測”,當給定一個新的實例,模型返回該實例屬於每一類的概率值。(0-1之間)

在Keras中,我們可以調用predict_proba()函數來實現。舉個例子:

Xnew = [[...], [...]]

ynew = model.predict_proba(Xnew)

在二分類問題下,Sigmoid激活函數常被用在輸出層,預測概率是數據對象屬於類別1的可能性,或者屬於類別0的可能性(1-概率)

在多分類問題下,則是softmax激活函數常被用在輸出層。數據對象屬於每一個類別的概率作為一個向量返回。

下邊的例子對Xnew數據數組中的每個樣本進行概率預測。

from keras.models import Sequential

from keras.layers import Dense

from sklearn.datasets.samples_generator import make_blobs

from sklearn.preprocessing import MinMaxScaler

# 生成二分類數據集

X, y = make_blobs(n_samples=100, centers=2, n_features=2, random_state=1)

scalar = MinMaxScaler()

scalar.fit(X)

X = scalar.transform(X)

# 定義並擬合出最終模型

model = Sequential()

model.add(Dense(4, input_dim=2, activation='relu'))

model.add(Dense(4, activation='relu'))

model.add(Dense(1, activation='sigmoid'))

model.compile(loss='binary_crossentropy', optimizer='adam')

model.fit(X, y, epochs=500, verbose=0)

# 新的未知數據

Xnew, _ = make_blobs(n_samples=3, centers=2, n_features=2, random_state=1)

Xnew = scalar.transform(Xnew)

# 做預測

ynew = model.predict_proba(Xnew)

# 顯示輸入輸出

for i in range(len(Xnew)):

print("X=%s, Predicted=%s" % (Xnew[i], ynew[i]))

我們運行這個實例,並將輸入數據及這些實例屬於類別1的概率打印出來:

X=[0.89337759 0.65864154], Predicted=[0.0087348]

X=[0.29097707 0.12978982], Predicted=[0.82020265]

X=[0.78082614 0.75391697], Predicted=[0.00693122]

迴歸預測

迴歸預測是一個監督學習問題,該模型學習一個給定輸入樣本到輸出數值的映射。比如會輸出0.1或0.2這樣的數字。

下邊是一個Keras迴歸的模型。

# 訓練一個迴歸模型的例子

from keras.models import Sequential

from keras.layers import Dense

from sklearn.datasets import make_regression

from sklearn.preprocessing import MinMaxScaler

# 生成迴歸數據集

X, y = make_regression(n_samples=100, n_features=2, noise=0.1, random_state=1)

scalarX, scalarY = MinMaxScaler(), MinMaxScaler()

scalarX.fit(X)

scalarY.fit(y.reshape(100,1))

X = scalarX.transform(X)

y = scalarY.transform(y.reshape(100,1))

# 定義並擬合模型

model = Sequential()

model.add(Dense(4, input_dim=2, activation='relu'))

model.add(Dense(4, activation='relu'))

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

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

model.fit(X, y, epochs=1000, verbose=0)

我們可以在最終的模型中調用predict()函數進行數值的預測。該函數以若干個實例組成的數組作為輸入參數。

下面的例子演示瞭如何對未知的多個數據實例進行迴歸預測。

from keras.models import Sequential

from keras.layers import Dense

from sklearn.datasets import make_regression

from sklearn.preprocessing import MinMaxScaler

# 生成迴歸數據集

X, y = make_regression(n_samples=100, n_features=2, noise=0.1, random_state=1)

scalarX, scalarY = MinMaxScaler(), MinMaxScaler()

scalarX.fit(X)

scalarY.fit(y.reshape(100,1))

X = scalarX.transform(X)

y = scalarY.transform(y.reshape(100,1))

# 定義並擬合模型

model = Sequential()

model.add(Dense(4, input_dim=2, activation='relu'))

model.add(Dense(4, activation='relu'))

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

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

model.fit(X, y, epochs=1000, verbose=0)

# 未知的新數據

Xnew, a = make_regression(n_samples=3, n_features=2, noise=0.1, random_state=1)

Xnew = scalarX.transform(Xnew)

# 作出預測

ynew = model.predict(Xnew)

# 顯示輸入輸出

for i in range(len(Xnew)):

print("X=%s, Predicted=%s" % (Xnew[i], ynew[i]))

運行上面那個多分類預測實例,然後將輸入和預測結果並排打印,進行對比。

X=[0.29466096 0.30317302], Predicted=[0.17097184]

X=[0.39445118 0.79390858], Predicted=[0.7475489]

X=[0.02884127 0.6208843 ], Predicted=[0.43370453]

同樣的,這個函數可以用於單獨實例的預測,前提是它們包裝成適當的格式。

舉例說明:

from keras.models import Sequential

from keras.layers import Dense

from sklearn.datasets import make_regression

from sklearn.preprocessing import MinMaxScaler

from numpy import array

# 生成迴歸數據集

X, y = make_regression(n_samples=100, n_features=2, noise=0.1, random_state=1)

scalarX, scalarY = MinMaxScaler(), MinMaxScaler()

scalarX.fit(X)

scalarY.fit(y.reshape(100,1))

X = scalarX.transform(X)

y = scalarY.transform(y.reshape(100,1))

# 定義並擬合模型

model = Sequential()

model.add(Dense(4, input_dim=2, activation='relu'))

model.add(Dense(4, activation='relu'))

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

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

model.fit(X, y, epochs=1000, verbose=0)

# 新的數據

Xnew = array([[0.29466096, 0.30317302]])

# 作出預測

ynew = model.predict(Xnew)

# 顯示輸入輸出

print("X=%s, Predicted=%s" % (Xnew[0], ynew[0]))

運行實例並打印出結果:

X=[0.29466096 0.30317302], Predicted=[0.17333156]

延伸閱讀

這部分提供了一些相關的資料,如果你想更深入學習的話可以看一看。

How to Train a Final Machine Learning Model:

https://machinelearningmastery.com/train-final-machine-learning-model/

Save and Load Your Keras Deep Learning Models:

https://machinelearningmastery.com/save-load-keras-deep-learning-models/

Develop Your First Neural Network in Python With Keras Step-By-Step:

https://machinelearningmastery.com/tutorial-first-neural-network-python-keras/

The 5 Step Life-Cycle for Long Short-Term Memory Models in Keras:

https://machinelearningmastery.com/5-step-life-cycle-long-short-term-memory-models-keras/

How to Make Predictions with Long Short-Term Memory Models in Keras:

https://machinelearningmastery.com/make-predictions-long-short-term-memory-models-keras/

總結:

在本教程中,你知道了如何使用Keras庫通過最終的深度學習模型進行分類和迴歸預測。

具體來說,你瞭解到:

  • 如何確定一個模型,為後續的預測做準備
  • 如何用Keras對分類問題進行類及其概率的預測
  • 如何用Keras進行迴歸預測

對本文的內容有什麼問題嗎?在下面的評論中提出來,我將盡我所能來回答。

原文鏈接:

https://machinelearningmastery.com/how-to-make-classification-and-regression-predictions-for-deep-learning-models-in-keras/

譯者簡介

手把手教你用Python庫Keras做預測(附代碼)

張逸,中國傳媒大學大三在讀,主修數字媒體技術。對數據科學充滿好奇,感慨於它創造出來的新世界。目前正在摸索和學習中,希望自己勇敢又熱烈,學最有意思的知識,交最志同道合的朋友。


分享到:


相關文章: