Halaman ini diterjemahkan oleh Cloud Translation API.
Switch to English

Regresi dasar: Memprediksi efisiensi bahan bakar

Lihat di TensorFlow.org Jalankan di Google Colab Lihat sumber di GitHub Unduh buku catatan

Dalam masalah regresi , kami bertujuan untuk memprediksi output dari nilai kontinu, seperti harga atau probabilitas. Bandingkan ini dengan masalah klasifikasi , di mana kami bertujuan untuk memilih kelas dari daftar kelas (misalnya, di mana gambar berisi apel atau jeruk, mengenali buah mana yang ada dalam gambar).

Notebook ini menggunakan Dataset Auto MPG klasik dan membuat model untuk memprediksi efisiensi bahan bakar pada akhir 1970-an dan awal 1980-an mobil. Untuk melakukan ini, kami akan memberikan model dengan deskripsi banyak mobil dari periode waktu itu. Deskripsi ini mencakup atribut seperti: silinder, perpindahan, tenaga kuda, dan berat.

Contoh ini menggunakan API tf.keras , lihat panduan ini untuk detailnya.

 # Use seaborn for pairplot
!pip install -q seaborn

# Use some functions from tensorflow_docs
!pip install -q git+https://github.com/tensorflow/docs
 
 import pathlib

import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import seaborn as sns
 
 import tensorflow as tf

from tensorflow import keras
from tensorflow.keras import layers

print(tf.__version__)
 
2.2.0

 import tensorflow_docs as tfdocs
import tensorflow_docs.plots
import tensorflow_docs.modeling
 

Dataset MPG Otomatis

Dataset tersedia dari Repositori Pembelajaran Mesin UCI .

Dapatkan datanya

Pertama unduh dataset.

 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
 
Downloading data from http://archive.ics.uci.edu/ml/machine-learning-databases/auto-mpg/auto-mpg.data
32768/30286 [================================] - 0s 4us/step

'/home/kbuilder/.keras/datasets/auto-mpg.data'

Impor menggunakan panda

 column_names = ['MPG','Cylinders','Displacement','Horsepower','Weight',
                'Acceleration', 'Model Year', 'Origin']
dataset = pd.read_csv(dataset_path, names=column_names,
                      na_values = "?", comment='\t',
                      sep=" ", skipinitialspace=True)

dataset.tail()
 

Bersihkan data

Dataset berisi beberapa nilai yang tidak diketahui.

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

Untuk menjaga agar tutorial awal ini mudah, turunkan baris-baris itu.

 dataset = dataset.dropna()
 

Kolom "Origin" benar-benar kategoris, bukan numerik. Jadi konversikan ke yang panas:

 dataset['Origin'] = dataset['Origin'].map({1: 'USA', 2: 'Europe', 3: 'Japan'})
 
 dataset = pd.get_dummies(dataset, prefix='', prefix_sep='')
dataset.tail()
 

Bagi data menjadi kereta dan uji

Sekarang pisahkan dataset menjadi satu set pelatihan dan satu set tes.

Kami akan menggunakan set tes dalam evaluasi akhir model kami.

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

Periksa datanya

Lihat distribusi bersama beberapa pasang kolom dari set pelatihan.

 sns.pairplot(train_dataset[["MPG", "Cylinders", "Displacement", "Weight"]], diag_kind="kde")
 
<seaborn.axisgrid.PairGrid at 0x7f72efffd048>

png

Lihat juga statistik keseluruhan:

 train_stats = train_dataset.describe()
train_stats.pop("MPG")
train_stats = train_stats.transpose()
train_stats
 

Pisahkan fitur dari label

Pisahkan nilai target, atau "label", dari fitur-fiturnya. Label ini adalah nilai yang akan Anda latih modelnya untuk diprediksi.

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

Normalisasi data

Lihat lagi di blok train_stats atas dan perhatikan betapa berbedanya rentang setiap fitur.

Ini adalah praktik yang baik untuk menormalkan fitur yang menggunakan skala dan rentang yang berbeda. Meskipun model mungkin bertemu tanpa normalisasi fitur, itu membuat pelatihan lebih sulit, dan itu membuat model yang dihasilkan tergantung pada pilihan unit yang digunakan dalam input.

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

Data yang dinormalisasi ini adalah apa yang akan kita gunakan untuk melatih model.

Model

Bangun model

Mari kita membangun model kita. Di sini, kita akan menggunakan model Sequential dengan dua lapisan tersembunyi yang terhubung erat, dan lapisan keluaran yang mengembalikan nilai kontinu tunggal. Langkah-langkah pembuatan model dibungkus dengan fungsi, build_model , karena kita akan membuat model kedua, nanti.

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

Periksa model

Gunakan metode .summary untuk mencetak deskripsi model yang sederhana

 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
_________________________________________________________________

Sekarang coba modelnya. Ambil batch 10 contoh dari data pelatihan dan panggil model.predict .

 example_batch = normed_train_data[:10]
example_result = model.predict(example_batch)
example_result
 
array([[-0.1648837 ],
       [-0.07093405],
       [-0.2749695 ],
       [-0.2918129 ],
       [-0.2575462 ],
       [-0.14536265],
       [-0.2421653 ],
       [-0.26370558],
       [-0.11580362],
       [-0.18530907]], dtype=float32)

Tampaknya berfungsi, dan menghasilkan hasil dari bentuk dan tipe yang diharapkan.

Latih modelnya

Latih model untuk 1000 zaman, dan catat akurasi pelatihan dan validasi dalam objek history .

 EPOCHS = 1000

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

Epoch: 0, loss:587.1881,  mae:22.9680,  mse:587.1881,  val_loss:588.6681,  val_mae:22.9440,  val_mse:588.6681,  
....................................................................................................
Epoch: 100, loss:6.2586,  mae:1.7643,  mse:6.2586,  val_loss:8.0623,  val_mae:2.1519,  val_mse:8.0623,  
....................................................................................................
Epoch: 200, loss:5.5199,  mae:1.5967,  mse:5.5199,  val_loss:8.0660,  val_mae:2.2123,  val_mse:8.0660,  
....................................................................................................
Epoch: 300, loss:4.8436,  mae:1.4971,  mse:4.8436,  val_loss:8.1721,  val_mae:2.2328,  val_mse:8.1721,  
....................................................................................................
Epoch: 400, loss:4.2909,  mae:1.3764,  mse:4.2909,  val_loss:8.4392,  val_mae:2.2052,  val_mse:8.4392,  
....................................................................................................
Epoch: 500, loss:3.9195,  mae:1.3214,  mse:3.9195,  val_loss:8.5692,  val_mae:2.2507,  val_mse:8.5692,  
....................................................................................................
Epoch: 600, loss:3.6788,  mae:1.2955,  mse:3.6788,  val_loss:8.2659,  val_mae:2.1961,  val_mse:8.2659,  
....................................................................................................
Epoch: 700, loss:3.4417,  mae:1.2700,  mse:3.4417,  val_loss:8.0492,  val_mae:2.1486,  val_mse:8.0492,  
....................................................................................................
Epoch: 800, loss:2.8846,  mae:1.0541,  mse:2.8846,  val_loss:8.2829,  val_mae:2.1932,  val_mse:8.2829,  
....................................................................................................
Epoch: 900, loss:2.8237,  mae:1.0353,  mse:2.8237,  val_loss:8.0768,  val_mae:2.1924,  val_mse:8.0768,  
....................................................................................................

Visualisasikan kemajuan pelatihan model menggunakan statistik yang tersimpan di objek history .

 hist = pd.DataFrame(history.history)
hist['epoch'] = history.epoch
hist.tail()
 
 plotter = tfdocs.plots.HistoryPlotter(smoothing_std=2)
 
 plotter.plot({'Basic': history}, metric = "mae")
plt.ylim([0, 10])
plt.ylabel('MAE [MPG]')
 
Text(0, 0.5, 'MAE [MPG]')

png

 plotter.plot({'Basic': history}, metric = "mse")
plt.ylim([0, 20])
plt.ylabel('MSE [MPG^2]')
 
Text(0, 0.5, 'MSE [MPG^2]')

png

Grafik ini menunjukkan sedikit peningkatan, atau bahkan penurunan dalam kesalahan validasi setelah sekitar 100 zaman. Mari kita perbarui model.fit panggilan untuk secara otomatis menghentikan pelatihan ketika skor validasi tidak membaik. Kami akan menggunakan panggilan balik EarlyStopping yang menguji kondisi pelatihan untuk setiap zaman. Jika sejumlah waktu yang ditentukan berlalu tanpa menunjukkan peningkatan, maka secara otomatis menghentikan pelatihan.

Anda dapat mempelajari lebih lanjut tentang panggilan balik ini di sini .

 model = build_model()

# The patience parameter is the amount of epochs to check for improvement
early_stop = keras.callbacks.EarlyStopping(monitor='val_loss', patience=10)

early_history = model.fit(normed_train_data, train_labels, 
                    epochs=EPOCHS, validation_split = 0.2, verbose=0, 
                    callbacks=[early_stop, tfdocs.modeling.EpochDots()])
 

Epoch: 0, loss:558.2405,  mae:22.3958,  mse:558.2405,  val_loss:542.6919,  val_mae:22.0385,  val_mse:542.6919,  
.......................................................................
 plotter.plot({'Early Stopping': early_history}, metric = "mae")
plt.ylim([0, 10])
plt.ylabel('MAE [MPG]')
 
Text(0, 0.5, 'MAE [MPG]')

png

Grafik menunjukkan bahwa pada set validasi, kesalahan rata-rata biasanya sekitar +/- 2 MPG. Apakah ini bagus? Kami akan menyerahkan keputusan itu kepada Anda.

Mari kita lihat seberapa baik model tersebut digeneralisasikan dengan menggunakan set tes , yang tidak kami gunakan saat melatih model. Ini memberi tahu kita seberapa baik kita dapat memperkirakan model untuk diprediksi ketika kita menggunakannya di dunia nyata.

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

print("Testing set Mean Abs Error: {:5.2f} MPG".format(mae))
 
3/3 - 0s - loss: 6.4735 - mae: 2.0304 - mse: 6.4735
Testing set Mean Abs Error:  2.03 MPG

Membuat prediksi

Akhirnya, prediksi nilai MPG menggunakan data dalam set pengujian:

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

a = plt.axes(aspect='equal')
plt.scatter(test_labels, test_predictions)
plt.xlabel('True Values [MPG]')
plt.ylabel('Predictions [MPG]')
lims = [0, 50]
plt.xlim(lims)
plt.ylim(lims)
_ = plt.plot(lims, lims)

 

png

Sepertinya model kami memprediksi dengan cukup baik. Mari kita lihat distribusi kesalahan.

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

png

Ini tidak cukup gaussian, tetapi kita mungkin berharap itu karena jumlah sampel sangat kecil.

Kesimpulan

Notebook ini memperkenalkan beberapa teknik untuk menangani masalah regresi.

  • Mean Squared Error (MSE) adalah fungsi kerugian umum yang digunakan untuk masalah regresi (fungsi kerugian yang berbeda digunakan untuk masalah klasifikasi).
  • Demikian pula, metrik evaluasi yang digunakan untuk regresi berbeda dari klasifikasi. Metrik regresi umum adalah Mean Absolute Error (MAE).
  • Ketika fitur input data numerik memiliki nilai dengan rentang berbeda, setiap fitur harus diskalakan secara independen ke rentang yang sama.
  • Jika tidak ada banyak data pelatihan, satu teknik adalah memilih jaringan kecil dengan beberapa lapisan tersembunyi untuk menghindari overfitting.
  • Menghentikan dini adalah teknik yang berguna untuk mencegah overfitting.
 
#
# Copyright (c) 2017 François Chollet
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the "Software"),
# to deal in the Software without restriction, including without limitation
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
# and/or sell copies of the Software, and to permit persons to whom the
# Software is furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
# DEALINGS IN THE SOFTWARE.