回歸項目實戰(zhàn):預(yù)測燃油效率 (tensorflow2.0官方教程翻譯)

最全TensorFlow2.0學(xué)習(xí)路線 www.mashangxue123.com

回歸問題中,我們的目標(biāo)是預(yù)測連續(xù)值的輸出蕴茴,如價格或概率。
將此與分類問題進(jìn)行對比,分類的目標(biāo)是從類列表中選擇一個類(例如奥喻,圖片包含蘋果或橙色,識別圖片中的哪個水果)非迹。

本章節(jié)采用了經(jīng)典的Auto MPG 數(shù)據(jù)集环鲤,并建立了一個模型來預(yù)測20世紀(jì)70年代末和80年代初汽車的燃油效率。為此憎兽,我們將為該模型提供該時段內(nèi)許多汽車的描述冷离,此描述包括以下屬性:氣缸,排量纯命,馬力和重量西剥。

此實例使用tf.keras API,有關(guān)信息信息扎附,請參閱Keras指南蔫耽。

# 使用seaborn進(jìn)行pairplot數(shù)據(jù)可視化,安裝命令
pip install seaborn
from __future__ import absolute_import, division, print_function, unicode_literals

import pathlib

import matplotlib.pyplot as plt
import pandas as pd
import seaborn as sns

# tensorflow2 安裝命令 pip install tensorflow==2.0.0-alpha0
import tensorflow as tf

from tensorflow import keras
from tensorflow.keras import layers

print(tf.__version__)

1. Auto MPG數(shù)據(jù)集

該數(shù)據(jù)集可從UCI機器學(xué)習(xí)庫獲得。

1.1. 獲取數(shù)據(jù)

首先下載數(shù)據(jù)集:

dataset_path = keras.utils.get_file("auto-mpg.data", "http://archive.ics.uci.edu/ml/machine-learning-databases/auto-mpg/auto-mpg.data")
dataset_path

用pandas導(dǎo)入數(shù)據(jù)

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()
MPG Cylinders Displacement Horsepower Weight Acceleration Model Year Origin
393 27.0 4 140.0 86.0 2790.0 15.6 82 1
394 44.0 4 97.0 52.0 2130.0 24.6 82 2
395 32.0 4 135.0 84.0 2295.0 11.6 82 1
396 28.0 4 120.0 79.0 2625.0 18.6 82 1
397 31.0 4 119.0 82.0 2720.0 19.4 82 1

1.2. 清理數(shù)據(jù)

數(shù)據(jù)集包含一些未知值

dataset.isna().sum()
MPG             0
Cylinders       0
Displacement    0
Horsepower      6
Weight          0
Acceleration    0
Model Year      0
Origin          0
dtype: int64

這是一個入門教程匙铡,所以我們就簡單地刪除這些行图甜。

dataset = dataset.dropna()

“Origin”這一列實際上是分類,而不是數(shù)字鳖眼。 所以把它轉(zhuǎn)換為獨熱編碼:

origin = dataset.pop('Origin')
dataset['USA'] = (origin == 1)*1.0
dataset['Europe'] = (origin == 2)*1.0
dataset['Japan'] = (origin == 3)*1.0
dataset.tail()
MPG Cylinders Displacement Horsepower Weight Acceleration Model Year USA Europe Japan
393 27.0 4 140.0 86.0 2790.0 15.6 82 1.0 0.0 0.0
394 44.0 4 97.0 52.0 2130.0 24.6 82 0.0 1.0 0.0
395 32.0 4 135.0 84.0 2295.0 11.6 82 1.0 0.0 0.0
396 28.0 4 120.0 79.0 2625.0 18.6 82 1.0 0.0 0.0
397 31.0 4 119.0 82.0 2720.0 19.4 82 1.0 0.0 0.0

1.3. 將數(shù)據(jù)分為訓(xùn)練集和測試集

現(xiàn)在將數(shù)據(jù)集拆分為訓(xùn)練集和測試集黑毅,我們將在模型的最終評估中使用測試集。

train_dataset = dataset.sample(frac=0.8,random_state=0)
test_dataset = dataset.drop(train_dataset.index)

1.4. 檢查數(shù)據(jù)

快速瀏覽訓(xùn)練集中幾對列的聯(lián)合分布:

sns.pairplot(train_dataset[["MPG", "Cylinders", "Displacement", "Weight"]], diag_kind="kde")
png

另外查看整體統(tǒng)計數(shù)據(jù):

train_stats = train_dataset.describe()
train_stats.pop("MPG")
train_stats = train_stats.transpose()
train_stats
count mean std min 25% 50% 75% max
Cylinders 314.0 5.477707 1.699788 3.0 4.00 4.0 8.00 8.0
Displacement 314.0 195.318471 104.331589 68.0 105.50 151.0 265.75 455.0
Horsepower 314.0 104.869427 38.096214 46.0 76.25 94.5 128.00 225.0
Weight 314.0 2990.251592 843.898596 1649.0 2256.50 2822.5 3608.00 5140.0
Acceleration 314.0 15.559236 2.789230 8.0 13.80 15.5 17.20 24.8
Model Year 314.0 75.898089 3.675642 70.0 73.00 76.0 79.00 82.0
USA 314.0 0.624204 0.485101 0.0 0.00 1.0 1.00 1.0
Europe 314.0 0.178344 0.383413 0.0 0.00 0.0 0.00 1.0
Japan 314.0 0.197452 0.398712 0.0 0.00 0.0 0.00 1.0

1.5. 從標(biāo)簽中分割特征

將目標(biāo)值或“標(biāo)簽”與特征分開钦讳,此標(biāo)簽是您訓(xùn)練的模型進(jìn)行預(yù)測的值:

train_labels = train_dataset.pop('MPG')
test_labels = test_dataset.pop('MPG')

1.6. 標(biāo)準(zhǔn)化數(shù)據(jù)

再看一下上面的train_stats塊矿瘦,注意每個特征的范圍有多么不同。

使用不同的比例和范圍對特征進(jìn)行標(biāo)準(zhǔn)化是一個很好的實踐愿卒,雖然模型可能在沒有特征標(biāo)準(zhǔn)化的情況下收斂缚去,但它使訓(xùn)練更加困難,并且它使得最終模型取決于輸入中使用的單位的選擇琼开。

注意:盡管我們僅從訓(xùn)練數(shù)據(jù)集中有意生成這些統(tǒng)計信息易结,但這些統(tǒng)計信息也將用于標(biāo)準(zhǔn)化測試數(shù)據(jù)集。我們需要這樣做柜候,將測試數(shù)據(jù)集投影到模型已經(jīng)訓(xùn)練過的相同分布中搞动。

def norm(x):
  return (x - train_stats['mean']) / train_stats['std']
normed_train_data = norm(train_dataset)
normed_test_data = norm(test_dataset)

這個標(biāo)準(zhǔn)化數(shù)據(jù)是我們用來訓(xùn)練模型的數(shù)據(jù)。

注意:用于標(biāo)準(zhǔn)化輸入的統(tǒng)計數(shù)據(jù)(平均值和標(biāo)準(zhǔn)偏差)需要應(yīng)用于輸入模型的任何其他數(shù)據(jù)渣刷,以及我們之前執(zhí)行的獨熱編碼鹦肿。這包括測試集以及模型在生產(chǎn)中使用時的實時數(shù)據(jù)。

2. 模型

2.1. 構(gòu)建模型

讓我們建立我們的模型辅柴。在這里箩溃,我們將使用具有兩個密集連接隱藏層的Sequential模型,以及返回單個連續(xù)值的輸出層碌识。模型構(gòu)建步驟包含在函數(shù)build_model中碾篡,因為我們稍后將創(chuàng)建第二個模型。

def build_model():
  model = keras.Sequential([
    layers.Dense(64, activation='relu', input_shape=[len(train_dataset.keys())]),
    layers.Dense(64, activation='relu'),
    layers.Dense(1)
  ])

  optimizer = tf.keras.optimizers.RMSprop(0.001)

  model.compile(loss='mse',
                optimizer=optimizer,
                metrics=['mae', 'mse'])
  return model
model = build_model()

2.2. 檢查模型

使用.summary方法打印模型的簡單描述

model.summary()
Model: "sequential"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
dense (Dense)                (None, 64)                640       
_________________________________________________________________
dense_1 (Dense)              (None, 64)                4160      
_________________________________________________________________
dense_2 (Dense)              (None, 1)                 65        
=================================================================
Total params: 4,865
Trainable params: 4,865
Non-trainable params: 0
_________________________________________________________________

現(xiàn)在試試這個模型筏餐。從訓(xùn)練數(shù)據(jù)中取出一批10個樣本數(shù)據(jù)并在調(diào)用model.predict函數(shù)。

example_batch = normed_train_data[:10]
example_result = model.predict(example_batch)
example_result
      array([[ 0.3297699 ],
            [ 0.25655937],
            [-0.12460149],
            [ 0.32495883],
            [ 0.50459725],
            [ 0.10887371],
            [ 0.57305855],
            [ 0.57637435],
            [ 0.12094647],
            [ 0.6864784 ]], dtype=float32)

這似乎可以工作牡拇,它產(chǎn)生預(yù)期的shape和類型的結(jié)果魁瞪。

2.3. 訓(xùn)練模型

訓(xùn)練模型1000個周期,并在history對象中記錄訓(xùn)練和驗證準(zhǔn)確性:

# 通過為每個完成的周期打印單個點來顯示訓(xùn)練進(jìn)度 
class PrintDot(keras.callbacks.Callback):
  def on_epoch_end(self, epoch, logs):
    if epoch % 100 == 0: print('')
    print('.', end='')

EPOCHS = 1000

history = model.fit(
  normed_train_data, train_labels,
  epochs=EPOCHS, validation_split = 0.2, verbose=0,
  callbacks=[PrintDot()])

使用存儲在history對象中的統(tǒng)計數(shù)據(jù)可視化模型的訓(xùn)練進(jìn)度惠呼。300

hist = pd.DataFrame(history.history)
hist['epoch'] = history.epoch
hist.tail()
loss mae mse val_loss val_mae val_mse epoch
995 2.556746 0.988013 2.556746 10.210531 2.324411 10.210530 995
996 2.597973 1.039339 2.597973 11.257273 2.469266 11.257273 996
997 2.671929 1.040886 2.671929 10.604957 2.446257 10.604958 997
998 2.634858 1.001898 2.634858 10.906935 2.373279 10.906935 998
999 2.741717 1.035889 2.741717 10.698320 2.342703 10.698319 999
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)
png
png

該圖表顯示在約100個周期之后导俘,驗證誤差幾乎沒有改進(jìn),甚至降低剔蹋。讓我們更新model.fit調(diào)用旅薄,以便在驗證分?jǐn)?shù)沒有提高時自動停止訓(xùn)練。我們將使用EarlyStopping回調(diào)來測試每個周期的訓(xùn)練狀態(tài)。如果經(jīng)過一定數(shù)量的周期而沒有顯示出改進(jìn)少梁,則自動停止訓(xùn)練洛口。

您可以了解此回調(diào)的更多信息 連接.

model = build_model()

# “patience”參數(shù)是檢查改進(jìn)的周期量 
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=0, callbacks=[early_stop, PrintDot()])

plot_history(history)
png
png

上圖顯示在驗證集上平均誤差通常約為+/-2MPG,這個好嗎凯沪?我們會把這個決定留給你第焰。

讓我們看一下使用測試集來看一下泛化模型效果,我們在訓(xùn)練模型時沒有使用測試集妨马,這告訴我們挺举,當(dāng)我們在現(xiàn)實世界中使用模型時,我們可以期待模型預(yù)測烘跺。

loss, mae, mse = model.evaluate(normed_test_data, test_labels, verbose=0)

print("Testing set Mean Abs Error: {:5.2f} MPG".format(mae))

Testing set Mean Abs Error: 2.09 MPG

2.4. 預(yù)測

最后湘纵,使用測試集中的數(shù)據(jù)預(yù)測MPG值:

test_predictions = model.predict(normed_test_data).flatten()

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])

png

看起來我們的模型預(yù)測得相當(dāng)好,我們來看看錯誤分布:

error = test_predictions - test_labels
plt.hist(error, bins = 25)
plt.xlabel("Prediction Error [MPG]")
_ = plt.ylabel("Count")
png

上圖看起來不是很高斯(正態(tài)分布)滤淳,很可能是因為樣本數(shù)據(jù)非常少梧喷。

3. 結(jié)論

本章節(jié)介紹了一些處理回歸問題的技巧:

  • 均方誤差(MSE)是用于回歸問題的常見損失函數(shù)(不同的損失函數(shù)用于分類問題)。

  • 同樣娇钱,用于回歸的評估指標(biāo)與分類不同伤柄,常見的回歸度量是平均絕對誤差(MAE)。

  • 當(dāng)數(shù)字輸入數(shù)據(jù)特征具有不同范圍的值時文搂,應(yīng)將每個特征獨立地縮放到相同范圍适刀。

  • 如果沒有太多訓(xùn)練數(shù)據(jù),應(yīng)選擇隱藏層很少的小網(wǎng)絡(luò)煤蹭,以避免過擬合笔喉。

  • 盡早停止是防止過擬合的有效技巧。

最新版本:https://www.mashangxue123.com/tensorflow/tf2-tutorials-keras-basic_regression.html
英文版本:https://tensorflow.google.cn/alpha/tutorials/keras/basic_regression
最全TensorFlow2.0學(xué)習(xí)路線 www.mashangxue123.com

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末硝皂,一起剝皮案震驚了整個濱河市常挚,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌稽物,老刑警劉巖奄毡,帶你破解...
    沈念sama閱讀 216,470評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異贝或,居然都是意外死亡吼过,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,393評論 3 392
  • 文/潘曉璐 我一進(jìn)店門咪奖,熙熙樓的掌柜王于貴愁眉苦臉地迎上來盗忱,“玉大人,你說我怎么就攤上這事羊赵√说瑁” “怎么了?”我有些...
    開封第一講書人閱讀 162,577評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長闲昭。 經(jīng)常有香客問我罐寨,道長,這世上最難降的妖魔是什么汤纸? 我笑而不...
    開封第一講書人閱讀 58,176評論 1 292
  • 正文 為了忘掉前任衩茸,我火速辦了婚禮,結(jié)果婚禮上贮泞,老公的妹妹穿的比我還像新娘楞慈。我一直安慰自己,他們只是感情好啃擦,可當(dāng)我...
    茶點故事閱讀 67,189評論 6 388
  • 文/花漫 我一把揭開白布囊蓝。 她就那樣靜靜地躺著,像睡著了一般令蛉。 火紅的嫁衣襯著肌膚如雪聚霜。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,155評論 1 299
  • 那天珠叔,我揣著相機與錄音蝎宇,去河邊找鬼。 笑死祷安,一個胖子當(dāng)著我的面吹牛姥芥,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播汇鞭,決...
    沈念sama閱讀 40,041評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼凉唐,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了霍骄?” 一聲冷哼從身側(cè)響起台囱,我...
    開封第一講書人閱讀 38,903評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎读整,沒想到半個月后簿训,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,319評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡米间,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,539評論 2 332
  • 正文 我和宋清朗相戀三年煎楣,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片车伞。...
    茶點故事閱讀 39,703評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖喻喳,靈堂內(nèi)的尸體忽然破棺而出另玖,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 35,417評論 5 343
  • 正文 年R本政府宣布谦去,位于F島的核電站慷丽,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏鳄哭。R本人自食惡果不足惜要糊,卻給世界環(huán)境...
    茶點故事閱讀 41,013評論 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望妆丘。 院中可真熱鬧锄俄,春花似錦、人聲如沸勺拣。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,664評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽药有。三九已至毅戈,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間愤惰,已是汗流浹背苇经。 一陣腳步聲響...
    開封第一講書人閱讀 32,818評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留宦言,地道東北人扇单。 一個月前我還...
    沈念sama閱讀 47,711評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像蜡励,于是被迫代替她去往敵國和親令花。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,601評論 2 353

推薦閱讀更多精彩內(nèi)容