大家好!我是【AI 菌】,一枚愛彈吉他的程序員。我
熱愛AI、熱愛分享、熱愛開源
! 這博客是我對學習的一點總結與思考。如果您也對深度學習、機器視覺、數據結構與算法、編程
等感興趣,可以關注我的動態,我們一起學習,一起進步~
我的博客地址爲:【AI 菌】的博客
我的Github項目地址是:【AI 菌】的Github
前言:
這個專欄我將分享我的 TensorFlow2 學習過程,力爭打造一個的輕鬆而高效的TensorFlow2入門學習教程,想學習的小夥伴可以關注我的動態!我們一起學習,一起進步!
相關文章:【TF2.0深度學習實戰——圖像分類】
文章目錄
一、迴歸問題
機器學習中有兩大基本問題:分類問題和迴歸問題。分類(classification) 的目的是從一系列的類別中選擇出一個分類,如果是針對圖片進行分類,就是圖片分類問題,這一部分可參見我上一個專欄:【TF2.0深度學習實戰——圖像分類】。在機器學習中,另一個重要的問題就是迴歸問題 (regression) 。它的目的是預測出如價格或概率這樣連續的輸出值。
本次我們學習一個基本的迴歸問題,用來預測汽車消耗燃油的效率。我們使用經典的 Auto MPG 數據集,構建了一個用來預測70年代末到80年代初汽車燃油效率的模型。爲了做到這一點,我們將爲該模型提供許多那個時期的汽車描述。這個描述包含:氣缸數,排量,馬力以及重量等。
Auto MPG 數據集部分樣本如下表所示:
二、數據集準備
(1)數據集下載與導入
# 下載AUTO-MPG數據集
dataset_path = keras.utils.get_file("auto-mpg.data", "http://archive.ics.uci.edu/ml/machine-learning-databases/auto-mpg/auto-mpg.data")
# 使用pandas導入數據集
column_names = ['MPG','Cylinders','Displacement','Horsepower','Weight',
'Acceleration', 'Model Year', 'Origin']
raw_dataset = pd.read_csv(dataset_path, names=column_names,
na_values = "?", comment='\t',
sep=" ", skipinitialspace=True)
dataset = raw_dataset.copy()
dataset.tail()
(2)數據清洗
dataset.isna().sum() # 數據集中包括一些未知值
dataset = dataset.dropna() # 刪除未知行
# origin列實際上代表分類,將origin列轉換爲獨熱碼(one-hot)
origin = dataset.pop('Origin')
dataset['USA'] = (origin == 1)*1.0
dataset['Europe'] = (origin == 2)*1.0
dataset['Japan'] = (origin == 3)*1.0
dataset.tail()
將origin列轉換爲獨熱碼後,原來數據集樣本變爲:
(3)數據集劃分
# 拆分訓練數據集和測試數據集
train_dataset = dataset.sample(frac=0.8, random_state=0)
test_dataset = dataset.drop(train_dataset.index)
(4)數據檢查
使用 seaborn 庫快速查看訓練集中幾對列的聯合分佈。
# 使用seaborn進行數據檢查
sns.pairplot(train_dataset[["MPG", "Cylinders", "Displacement", "Weight"]], diag_kind="kde")
聯合分佈如下:
(5)分離標籤
由於標籤MPG列存在於下載的數據集中,因此需要單獨分離開來。
train_labels = train_dataset.pop('MPG')
test_labels = test_dataset.pop('MPG')
(6)數據規範化
def norm(x):
return (x - train_stats['mean']) / train_stats['std']
normed_train_data = norm(train_dataset)
normed_test_data = norm(test_dataset)
三、模型搭建與訓練
(1)模型的搭建
model = keras.Sequential([
layers.Dense(64, activation='relu', input_shape=[len(train_dataset.keys())]),
layers.Dense(64, activation='relu'),
layers.Dense(1)
])
(2)模型的裝配
optimizer = tf.keras.optimizers.RMSprop(0.001)
model.compile(loss='mse',
optimizer=optimizer,
metrics=['mae', 'mse'])
(3)模型的訓練
EPOCHS = 1000
history = model.fit(
normed_train_data, train_labels,
epochs=EPOCHS, validation_split=0.2, verbose=2)
(4)訓練的可視化
def plot_history(history):
hist = pd.DataFrame(history.history)
hist['epoch'] = history.epoch
plt.figure()
plt.xlabel('Epoch')
plt.ylabel('Mean Abs Error [MPG]')
plt.plot(hist['epoch'], hist['mae'],
label='Train Error')
plt.plot(hist['epoch'], hist['val_mae'],
label='Val Error')
plt.ylim([0, 5])
plt.legend()
plt.figure()
plt.xlabel('Epoch')
plt.ylabel('Mean Square Error [$MPG^2$]')
plt.plot(hist['epoch'], hist['mse'],
label='Train Error')
plt.plot(hist['epoch'], hist['val_mse'],
label='Val Error')
plt.ylim([0, 20])
plt.legend()
plt.show()
plot_history(history)
可視化結果:
上圖表顯示在約80個 epochs 之後誤差非但沒有改進,反而出現惡化。 因此我們可以更新 model.fit 調用,當驗證值沒有提高上是自動停止訓練。 具體的作法就是:使用一個 EarlyStopping callback 來測試每個 epoch 的訓練條件。如果經過一定數量的 epochs 後沒有改進,就自動停止訓練。
四、停訓與預測
(1)提前停止訓練
由於訓練到一定epochs後,模型的誤差可能不再變化,甚至在惡化,這時就可以提前停止訓練,節省時間。
# patience 值用來檢查改進 epochs 的數量
early_stop = keras.callbacks.EarlyStopping(monitor='val_loss', patience=10)
history = model.fit(normed_train_data, train_labels, epochs=EPOCHS,
validation_split=0.2, verbose=1, callbacks=[early_stop])
使用 EarlyStopping callback 連續檢測10個epochs,如果誤差沒有變小,就停止訓練。結果如下:
從上圖可以發現:加了 EarlyStopping callback 後,模型提前停止訓練了,在訓練到50個epochs左右時,誤差就沒有再縮小,從而提前停止訓練。
(2)預測效果
以上都是在訓練和驗證集上的測試效果,下面我們將對測試集進行預測,來測試模型的泛化效果。
# 平均預測誤差
loss, mae, mse = model.evaluate(normed_test_data, test_labels, verbose=2)
print("Testing set Mean Abs Error: {:5.2f} MPG".format(mae))
test_predictions = model.predict(normed_test_data).flatten()
# 可視化預測效果:prediction-truth圖
plt.figure()
plt.scatter(test_labels, test_predictions)
plt.xlabel('True Values [MPG]')
plt.ylabel('Predictions [MPG]')
plt.axis('equal')
plt.axis('square')
plt.xlim([0,plt.xlim()[1]])
plt.ylim([0,plt.ylim()[1]])
_ = plt.plot([-100, 100], [-100, 100])
# 誤差分佈圖
plt.figure()
error = test_predictions - test_labels
plt.hist(error, bins = 25)
plt.xlabel("Prediction Error [MPG]")
_ = plt.ylabel("Count")
plt.show()
測試集上的預測效果如下:
- 平均誤差。平均誤差爲1.98。
Testing set Mean Abs Error: 1.98 MPG
- prediction-truth圖。橫軸表示真實的值,縱軸表示的是預測的值。可見預測值很貼近真實值。
- 誤差分佈。橫軸是預測誤差,縱軸是統計的每個誤差對應的樣本數。
由上圖可見,它不是完全的高斯分佈,可以推斷出,這是因爲樣本的數量很小所導致的。
完整代碼已經上傳github倉庫:https://github.com/Keyird/TensorFlow2-for-beginner
如果對你有幫助的話,歡迎star收藏~
最好的關係是互相成就,各位的「三連」就是【AI 菌】創作的最大動力,我們下期見!