Catat tanggalnya! Google I / O mengembalikan 18-20 Mei Daftar sekarang
Halaman ini diterjemahkan oleh Cloud Translation API.
Switch to English

Loop pelatihan dasar

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

Dalam panduan sebelumnya, Anda telah mempelajari tentang tensor , variabel , pita gradien , dan modul . Dalam panduan ini, Anda akan menyesuaikan semua ini untuk melatih model.

TensorFlow juga menyertakan tf.Keras API , API jaringan neural level tinggi yang menyediakan abstraksi berguna untuk mengurangi boilerplate. Namun, dalam panduan ini, Anda akan menggunakan kelas dasar.

Mendirikan

import tensorflow as tf

Memecahkan masalah pembelajaran mesin

Memecahkan masalah pembelajaran mesin biasanya terdiri dari langkah-langkah berikut:

  • Dapatkan data pelatihan.
  • Tentukan modelnya.
  • Tentukan fungsi kerugian.
  • Jalankan melalui data pelatihan, menghitung kerugian dari nilai ideal
  • Hitung gradien untuk kerugian itu dan gunakan pengoptimal untuk menyesuaikan variabel agar sesuai dengan data.
  • Evaluasi hasil Anda.

Untuk tujuan ilustrasi, dalam panduan ini Anda akan mengembangkan model linier sederhana, $ f (x) = x * W + b $, yang memiliki dua variabel: $ W $ (bobot) dan $ b $ (bias).

Ini adalah masalah pembelajaran mesin yang paling dasar: Diberikan $ x $ dan $ y $, cobalah untuk menemukan kemiringan dan offset garis melalui regresi linier sederhana .

Data

Pembelajaran yang diawasi menggunakan masukan (biasanya dilambangkan sebagai x ) dan keluaran (dilambangkan y , sering disebut label ). Tujuannya adalah untuk belajar dari input dan output berpasangan sehingga Anda dapat memprediksi nilai output dari sebuah input.

Setiap input data Anda, di TensorFlow, hampir selalu diwakili oleh tensor, dan seringkali berupa vektor. Dalam pelatihan yang diawasi, keluaran (atau nilai yang ingin Anda prediksi) juga merupakan tensor.

Berikut adalah beberapa data yang disintesis dengan menambahkan gangguan Gaussian (Normal) ke titik-titik di sepanjang garis.

# The actual line
TRUE_W = 3.0
TRUE_B = 2.0

NUM_EXAMPLES = 1000

# A vector of random x values
x = tf.random.normal(shape=[NUM_EXAMPLES])

# Generate some noise
noise = tf.random.normal(shape=[NUM_EXAMPLES])

# Calculate y
y = x * TRUE_W + TRUE_B + noise
# Plot all the data
import matplotlib.pyplot as plt

plt.scatter(x, y, c="b")
plt.show()

png

Tensor biasanya dikumpulkan dalam batch , atau kelompok input dan output ditumpuk bersama. Pengelompokan dapat memberikan beberapa manfaat pelatihan dan bekerja dengan baik dengan akselerator dan komputasi vektor. Mengingat betapa kecilnya kumpulan data ini, Anda dapat memperlakukan seluruh kumpulan data sebagai satu kumpulan.

Tentukan modelnya

Gunakan tf.Variable untuk merepresentasikan semua bobot dalam model. A tf.Variable menyimpan nilai dan menyediakannya dalam bentuk tensor sesuai kebutuhan. Lihat panduan variabel untuk lebih jelasnya.

Gunakan tf.Module untuk merangkum variabel dan komputasi. Anda dapat menggunakan objek Python apa pun, tetapi dengan cara ini dapat dengan mudah disimpan.

Di sini, Anda mendefinisikan w dan b sebagai variabel.

class MyModel(tf.Module):
  def __init__(self, **kwargs):
    super().__init__(**kwargs)
    # Initialize the weights to `5.0` and the bias to `0.0`
    # In practice, these should be randomly initialized
    self.w = tf.Variable(5.0)
    self.b = tf.Variable(0.0)

  def __call__(self, x):
    return self.w * x + self.b

model = MyModel()

# List the variables tf.modules's built-in variable aggregation.
print("Variables:", model.variables)

# Verify the model works
assert model(3.0).numpy() == 15.0
Variables: (<tf.Variable 'Variable:0' shape=() dtype=float32, numpy=0.0>, <tf.Variable 'Variable:0' shape=() dtype=float32, numpy=5.0>)

Variabel awal ditetapkan di sini dengan cara tetap, tetapi Keras hadir dengan sejumlah initalizers yang dapat Anda gunakan, dengan atau tanpa sisa Keras.

Tentukan fungsi kerugian

Fungsi kerugian mengukur seberapa baik keluaran model untuk masukan tertentu cocok dengan keluaran target. Tujuannya adalah untuk meminimalkan perbedaan ini selama latihan. Tentukan kerugian L2 standar, juga dikenal sebagai kesalahan "kuadrat rata-rata":

# This computes a single loss value for an entire batch
def loss(target_y, predicted_y):
  return tf.reduce_mean(tf.square(target_y - predicted_y))

Sebelum melatih model, Anda dapat memvisualisasikan nilai kerugian dengan memplot prediksi model dengan warna merah dan data pelatihan dengan warna biru:

plt.scatter(x, y, c="b")
plt.scatter(x, model(x), c="r")
plt.show()

print("Current loss: %1.6f" % loss(y, model(x)).numpy())

png

Current loss: 8.569547

Tentukan loop pelatihan

Loop pelatihan terdiri dari melakukan tiga tugas secara berulang kali secara berurutan:

  • Mengirim sekumpulan masukan melalui model untuk menghasilkan keluaran
  • Menghitung kerugian dengan membandingkan keluaran dengan keluaran (atau label)
  • Menggunakan pita gradien untuk menemukan gradien
  • Mengoptimalkan variabel dengan gradien tersebut

Untuk contoh ini, Anda dapat melatih model menggunakan penurunan gradien .

Ada banyak varian skema penurunan gradien yang ditangkap di tf.keras.optimizers . Tetapi dalam semangat membangun dari prinsip pertama, di sini Anda akan menerapkan matematika dasar sendiri dengan bantuantf.GradientTape untuk diferensiasi otomatis dan tf.assign_sub untuk menurunkan nilai (yang menggabungkan tf.assign dan tf.sub ):

# Given a callable model, inputs, outputs, and a learning rate...
def train(model, x, y, learning_rate):

  with tf.GradientTape() as t:
    # Trainable variables are automatically tracked by GradientTape
    current_loss = loss(y, model(x))

  # Use GradientTape to calculate the gradients with respect to W and b
  dw, db = t.gradient(current_loss, [model.w, model.b])

  # Subtract the gradient scaled by the learning rate
  model.w.assign_sub(learning_rate * dw)
  model.b.assign_sub(learning_rate * db)

Untuk melihat pelatihan, Anda dapat mengirim kelompok x dan y yang sama melalui loop pelatihan, dan melihat bagaimana W dan b berevolusi.

model = MyModel()

# Collect the history of W-values and b-values to plot later
Ws, bs = [], []
epochs = range(10)

# Define a training loop
def training_loop(model, x, y):

  for epoch in epochs:
    # Update the model with the single giant batch
    train(model, x, y, learning_rate=0.1)

    # Track this before I update
    Ws.append(model.w.numpy())
    bs.append(model.b.numpy())
    current_loss = loss(y, model(x))

    print("Epoch %2d: W=%1.2f b=%1.2f, loss=%2.5f" %
          (epoch, Ws[-1], bs[-1], current_loss))
print("Starting: W=%1.2f b=%1.2f, loss=%2.5f" %
      (model.w, model.b, loss(y, model(x))))

# Do the training
training_loop(model, x, y)

# Plot it
plt.plot(epochs, Ws, "r",
         epochs, bs, "b")

plt.plot([TRUE_W] * len(epochs), "r--",
         [TRUE_B] * len(epochs), "b--")

plt.legend(["W", "b", "True W", "True b"])
plt.show()
Starting: W=5.00 b=0.00, loss=8.56955
Epoch  0: W=4.63 b=0.39, loss=5.91888
Epoch  1: W=4.33 b=0.71, loss=4.19509
Epoch  2: W=4.08 b=0.96, loss=3.07394
Epoch  3: W=3.88 b=1.17, loss=2.34469
Epoch  4: W=3.72 b=1.33, loss=1.87030
Epoch  5: W=3.59 b=1.46, loss=1.56166
Epoch  6: W=3.49 b=1.57, loss=1.36086
Epoch  7: W=3.40 b=1.65, loss=1.23019
Epoch  8: W=3.33 b=1.72, loss=1.14516
Epoch  9: W=3.28 b=1.77, loss=1.08981

png

# Visualize how the trained model performs
plt.scatter(x, y, c="b")
plt.scatter(x, model(x), c="r")
plt.show()

print("Current loss: %1.6f" % loss(model(x), y).numpy())

png

Current loss: 1.089813

Solusi yang sama, tetapi dengan Keras

Ini berguna untuk membandingkan kode di atas dengan yang setara di Keras.

Mendefinisikan model terlihat persis sama jika Anda membuat subclass tf.keras.Model . Ingat bahwa model Keras pada akhirnya mewarisi dari modul.

class MyModelKeras(tf.keras.Model):
  def __init__(self, **kwargs):
    super().__init__(**kwargs)
    # Initialize the weights to `5.0` and the bias to `0.0`
    # In practice, these should be randomly initialized
    self.w = tf.Variable(5.0)
    self.b = tf.Variable(0.0)

  def call(self, x):
    return self.w * x + self.b

keras_model = MyModelKeras()

# Reuse the training loop with a Keras model
training_loop(keras_model, x, y)

# You can also save a checkpoint using Keras's built-in support
keras_model.save_weights("my_checkpoint")
Epoch  0: W=4.63 b=0.39, loss=5.91888
Epoch  1: W=4.33 b=0.71, loss=4.19509
Epoch  2: W=4.08 b=0.96, loss=3.07394
Epoch  3: W=3.88 b=1.17, loss=2.34469
Epoch  4: W=3.72 b=1.33, loss=1.87030
Epoch  5: W=3.59 b=1.46, loss=1.56166
Epoch  6: W=3.49 b=1.57, loss=1.36086
Epoch  7: W=3.40 b=1.65, loss=1.23019
Epoch  8: W=3.33 b=1.72, loss=1.14516
Epoch  9: W=3.28 b=1.77, loss=1.08981

Daripada menulis loop pelatihan baru setiap kali Anda membuat model, Anda dapat menggunakan fitur bawaan Keras sebagai pintasan. Ini dapat berguna saat Anda tidak ingin menulis atau men-debug loop pelatihan Python.

Jika ya, Anda perlu menggunakan model.compile() untuk menyetel parameter, dan model.fit() untuk dilatih. Ini bisa lebih sedikit kode untuk menggunakan implementasi Keras kehilangan L2 dan penurunan gradien, lagi-lagi sebagai pintasan. Kerugian dan pengoptimalan keras juga dapat digunakan di luar fungsi kenyamanan ini, dan contoh sebelumnya dapat menggunakannya.

keras_model = MyModelKeras()

# compile sets the training parameters
keras_model.compile(
    # By default, fit() uses tf.function().  You can
    # turn that off for debugging, but it is on now.
    run_eagerly=False,

    # Using a built-in optimizer, configuring as an object
    optimizer=tf.keras.optimizers.SGD(learning_rate=0.1),

    # Keras comes with built-in MSE error
    # However, you could use the loss function
    # defined above
    loss=tf.keras.losses.mean_squared_error,
)

Keras fit mengharapkan data bertumpuk atau kumpulan data lengkap sebagai larik NumPy. Array NumPy dipotong menjadi beberapa batch dan default ke ukuran batch 32.

Dalam kasus ini, untuk mencocokkan perilaku loop yang ditulis tangan, Anda harus meneruskan x sebagai satu batch berukuran 1000.

print(x.shape[0])
keras_model.fit(x, y, epochs=10, batch_size=1000)
1000
Epoch 1/10
1/1 [==============================] - 0s 342ms/step - loss: 8.5695
Epoch 2/10
1/1 [==============================] - 0s 2ms/step - loss: 5.9189
Epoch 3/10
1/1 [==============================] - 0s 2ms/step - loss: 4.1951
Epoch 4/10
1/1 [==============================] - 0s 2ms/step - loss: 3.0739
Epoch 5/10
1/1 [==============================] - 0s 2ms/step - loss: 2.3447
Epoch 6/10
1/1 [==============================] - 0s 2ms/step - loss: 1.8703
Epoch 7/10
1/1 [==============================] - 0s 2ms/step - loss: 1.5617
Epoch 8/10
1/1 [==============================] - 0s 2ms/step - loss: 1.3609
Epoch 9/10
1/1 [==============================] - 0s 2ms/step - loss: 1.2302
Epoch 10/10
1/1 [==============================] - 0s 2ms/step - loss: 1.1452
<tensorflow.python.keras.callbacks.History at 0x7f90d9f20128>

Perhatikan bahwa Keras mencetak kerugian setelah pelatihan, bukan sebelumnya, sehingga kerugian pertama muncul lebih rendah, tetapi sebaliknya ini pada dasarnya menunjukkan kinerja pelatihan yang sama.

Langkah selanjutnya

Dalam panduan ini, Anda telah melihat cara menggunakan kelas inti tensor, variabel, modul, dan pita gradien untuk membuat dan melatih model, dan selanjutnya bagaimana ide tersebut dipetakan ke Keras.

Namun, ini adalah masalah yang sangat sederhana. Untuk pengenalan yang lebih praktis, lihat Panduan pelatihan kustom .

Untuk informasi lebih lanjut tentang menggunakan loop pelatihan Keras bawaan, lihat panduan ini . Untuk informasi lebih lanjut tentang loop pelatihan dan Keras, lihat panduan ini . Untuk menulis loop pelatihan terdistribusi kustom, lihat panduan ini .