網頁

2019年7月2日 星期二

Regression with Keras (Deep Learning with Keras – Part 3)



Regression
經過兩個入門教學後,開始構建我們的第一個神經網絡,來處理一個簡單的回歸問題。 回歸是模型學習預測給定輸入數據的連續值輸出的過程,例如, 預測價格,長度,寬度等

Problem Definition
我們的目標是建立預測模型,從一系列房屋特徵預測房價。我們將使用波士頓住房數據集,該數據集由美國人口普查局收集,涉及波士頓馬薩諸塞州的住房。它是從StatLib檔案中獲得的,並且已在整個文獻中廣泛用於benchmark演算法。

數據集很小,只有506個案例。它包含14個特徵描述如下:
CRIM:城鎮人均犯罪率
ZN:佔地面積超過25,000平方英尺的住宅用地比例。
INDUS:城鎮中非商業用地的所占比例。
CHAS:查爾斯河虛擬變量(dummy variable)(被河道包圍,則為1;否則為0)
NOX:一氧化氮濃度(每千萬份)
RM:每棟住宅的平均房間數
AGE:1940年以前建造的自住單位比例
DIS:到波士頓五個就業中心的加權距離
RAD:無障礙徑向高速公路指數
TAX:每一萬美元的不動產稅率
PTRATIO:城鎮的師生比例
B:1000(Bk-0.63)²其中Bk是城鎮黑人的比例
LSTAT:地區有多少百分比的房東屬於低收入階層
MEDV:自有房屋的中位數價值1000美元(要預測的變量

回歸問題背後的目標是使用13個特徵來預測MEDV的值(代表住房價格)。

Loading the Data
幸運的是,Keras有一組已經可用的數據集。 您可以從keras.dataset訪問它們。

from keras.datasets import boston_housing
(X_train, y_train), (X_test, y_test) = boston_housing.load_data()

# let us view on sample from the features
print(X_train[0], y_train[0])
# output
# (array([  1.23247,   0.     ,   8.14   ,   0.     ,   0.538  ,   6.142  ,
#         91.7    ,   3.9769 ,   4.     , 307.     ,  21.     , 396.9    ,
#         18.72   ]), 15.2)

數據以兩個tuples的形式返回,代表訓練和測試分化(training and testing splits)。 X_train和X_test包含特徵列,而y_train和y_test包含標籤/輸出列。

Preprocessing
正如前一篇文章中所討論的,我們需要在將數據提供給網絡之前對其進行預處理(preprocess)。 顯然,我們的數據需要重新調整。
from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()

# first we fit the scaler on the training dataset
scaler.fit(X_train)

# then we call the transform method to scale both the training and testing data
X_train_scaled = scaler.transform(X_train)
X_test_scaled = scaler.transform(X_test)

# a sample output
print(X_train_scaled[0])

# array([-0.27224633, -0.48361547, -0.43576161, -0.25683275, -0.1652266 ,
#      -0.1764426 ,  0.81306188,  0.1166983 , -0.62624905, -0.59517003,
#       1.14850044,  0.44807713,  0.8252202 ])

請注意,我們只重新調整功能,而不是標籤列。 該數據集很簡單,無需進一步預處理。

Building the Model
我們將以sequential方式逐層構建模型。 為此,我們必須導入 1)model class 2)和layer class。
from keras import models, layers

然後,我們創建模型:
model = models.Sequential()

我們開始添加layer:
model.add(layers.Dense(8, activation='relu', input_shape=[X_train.shape[1]]))
model.add(layers.Dense(16, activation='relu'))

# output layer
model.add(layers.Dense(1))

請注意,我們只為第一層指定輸入形狀,之後所有層將自動知道它們的輸入形狀。

此處的激活函數要指定在layer層數的下一項,來計算output = activation(X * W + bias)。 Relu是一種激活函數,用於打破模型的線性。 還有許多其他激活函數,但Relu是這種網絡中最受歡迎的功能之一。

輸出層只是一個具有一個神經元和線性激活函數的層,因為我們只預測一個連續值。

Compiling the Model
在構建網絡之後,我們需要指定兩個重要的事情:1)優化器 2)損失函數。 優化器負責選擇最佳模型參數,而優化器使用損失函數(最小化或最大化)來了解如何更新和計算影響模型訓練和模型輸出的網絡參數,使其逼近或達到最優值。
model.compile(optimizer='rmsprop', loss='mse', metrics=['mae'])

Keras支援除RMSprop之外的其他優化器,您應該進行trial and error過程以選擇最適合您的問題。 但通常RMSprop的默認參數可以正常工作。

使用的損失函數(loss functions)是均方誤差(Mean Squared Error),是是指參數估計值與參數真值之差平方的期望值;可以評價數據的變化程度,MSE的值越小,說明預測模型描述實驗數據具有更好的精確度。

metrics結果不會真正用於訓練,只用來顯示(作爲參考),比主要的損失值更容易評估。 例如:絕對值損失(absolute value loss)比平方誤差(squared error)更容易評估和理解。

Model Training
history = model.fit(X_train_scaled, y_train, validation_split=0.2, epochs=100)

擬合(fit)方法同時採用特徵(feature)和標籤(label),驗證分割表明模型必須將20%的數據保留為驗證集。 epoch表示數據的迭代次數。

當我們執行上面的程式碼時,我們將獲得如下輸出:
Train on 323 samples, validate on 81 samples
Epoch 1/100
323/323 [==============================] - 0s 516us/step - loss: 581.6925 - mean_absolute_error: 22.2193 - val_loss: 648.7472 - val_mean_absolute_error: 23.6661
Epoch 2/100
323/323 [==============================] - 0s 48us/step - loss: 570.4857 - mean_absolute_error: 21.9364 - val_loss: 639.6261 - val_mean_absolute_error: 23.4443
...
...
...
Epoch 100/100 323/323 [==============================] - 0s 42us/step - loss: 19.0644 - mean_absolute_error: 3.0359 - val_loss: 20.4928 - val_mean_absolute_error: 3.4002 

驗證損失從648減少到20。

根據epoch數繪製訓練和驗證誤差(validation error)收斂:



我們開始時每個預測誤差為20K,並且下降到大約3K。 對於房價而言,這是一個非常可接受的誤差值。

Evaluation on Test Data
在Keras,模型評估非常簡單。 檢查以下內容:
model.evaluate(X_test_scaled, y_test)
# output
# [26.68399990306181, 3.7581424339144838]

輸出值表示loss(Mean Squared Error)和metrics(Mean Absolute Error)。

Model Prediction
使用模型進行預測比您預期的要簡單。 如以下所示:
# we get a sample data (the first 2 inputs from the training data)
to_predict = X_train_scaled[:2]
# we call the predict method
predictions = model.predict(to_predict)
# print the predictions
print(predictions)
# output
# array([[13.272537], [39.808475]], dtype=float32)
# print the real values
print(y_train[:2])
# array([15.2, 42.3])

如圖所示,我們每個房子只有大約3K的錯誤。

Final Thoughts
這篇主要目的是如何構建回歸模型,對其進行評估,並使用它來預測新的數據值。



參考
https://www.marktechpost.com/2019/06/17/regression-with-keras-deep-learning-with-keras-part-3/

沒有留言:

張貼留言