Halaman ini diterjemahkan oleh Cloud Translation API.
Switch to English

Pelatihan dan evaluasi dengan metode built-in

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

Mendirikan

import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers

pengantar

Panduan ini mencakup model pelatihan, evaluasi, dan prediksi (inferensi) saat menggunakan API model.fit() untuk pelatihan & validasi (seperti model.fit() , model.evaluate() , model.predict() ).

Jika Anda tertarik untuk memanfaatkan fit() saat menentukan fungsi langkah pelatihan Anda sendiri, lihat panduan "menyesuaikan apa yang terjadi di fit() " .

Jika Anda tertarik untuk menulis loop pelatihan & evaluasi Anda sendiri dari awal, lihat panduan "menulis loop pelatihan dari awal" .

Secara umum, baik Anda menggunakan loop bawaan atau menulis sendiri, pelatihan & evaluasi model bekerja secara ketat dengan cara yang sama di setiap jenis model Keras - Model sekuensial, model yang dibuat dengan API Fungsional, dan model yang ditulis dari awal melalui model subclassing.

Panduan ini tidak mencakup pelatihan terdistribusi. Untuk pelatihan terdistribusi, lihat panduan kami untuk pelatihan multi-GPU & terdistribusi .

Ringkasan API: contoh ujung ke ujung pertama

Saat meneruskan data ke loop pelatihan bawaan suatu model, Anda harus menggunakan array NumPy (jika data Anda kecil dan muat dalam memori) atau objek tf.data Dataset . Dalam beberapa paragraf berikutnya, kami akan menggunakan kumpulan data MNIST sebagai array NumPy, untuk menunjukkan cara menggunakan pengoptimal, kerugian, dan metrik.

Mari pertimbangkan model berikut (di sini, kita membangun dengan API Fungsional, tapi bisa juga model Sequential atau model subclass juga):

inputs = keras.Input(shape=(784,), name="digits")
x = layers.Dense(64, activation="relu", name="dense_1")(inputs)
x = layers.Dense(64, activation="relu", name="dense_2")(x)
outputs = layers.Dense(10, activation="softmax", name="predictions")(x)

model = keras.Model(inputs=inputs, outputs=outputs)

Berikut adalah tampilan alur kerja ujung ke ujung, yang terdiri dari:

  • Latihan
  • Validasi pada set pisahan yang dihasilkan dari data pelatihan asli
  • Evaluasi data uji

Kami akan menggunakan data MNIST untuk contoh ini.

(x_train, y_train), (x_test, y_test) = keras.datasets.mnist.load_data()

# Preprocess the data (these are NumPy arrays)
x_train = x_train.reshape(60000, 784).astype("float32") / 255
x_test = x_test.reshape(10000, 784).astype("float32") / 255

y_train = y_train.astype("float32")
y_test = y_test.astype("float32")

# Reserve 10,000 samples for validation
x_val = x_train[-10000:]
y_val = y_train[-10000:]
x_train = x_train[:-10000]
y_train = y_train[:-10000]

Kami menentukan konfigurasi pelatihan (pengoptimal, kerugian, metrik):

model.compile(
    optimizer=keras.optimizers.RMSprop(),  # Optimizer
    # Loss function to minimize
    loss=keras.losses.SparseCategoricalCrossentropy(),
    # List of metrics to monitor
    metrics=[keras.metrics.SparseCategoricalAccuracy()],
)

Kami memanggil fit() , yang akan melatih model dengan membagi data menjadi "kumpulan" ukuran "batch_size", dan berulang kali melakukan iterasi pada seluruh kumpulan data untuk sejumlah "masa" tertentu.

print("Fit model on training data")
history = model.fit(
    x_train,
    y_train,
    batch_size=64,
    epochs=2,
    # We pass some validation for
    # monitoring validation loss and metrics
    # at the end of each epoch
    validation_data=(x_val, y_val),
)
Fit model on training data
Epoch 1/2
782/782 [==============================] - 2s 2ms/step - loss: 0.3425 - sparse_categorical_accuracy: 0.9034 - val_loss: 0.1827 - val_sparse_categorical_accuracy: 0.9478
Epoch 2/2
782/782 [==============================] - 2s 2ms/step - loss: 0.1618 - sparse_categorical_accuracy: 0.9513 - val_loss: 0.1282 - val_sparse_categorical_accuracy: 0.9651

Objek "histori" yang dikembalikan menyimpan catatan nilai kerugian dan nilai metrik selama pelatihan:

history.history
{'loss': [0.3424801528453827, 0.16180744767189026],
 'sparse_categorical_accuracy': [0.903439998626709, 0.9512799978256226],
 'val_loss': [0.18268445134162903, 0.12816601991653442],
 'val_sparse_categorical_accuracy': [0.9477999806404114, 0.9650999903678894]}

Kami mengevaluasi model pada data pengujian melalui evaluate() :

# Evaluate the model on the test data using `evaluate`
print("Evaluate on test data")
results = model.evaluate(x_test, y_test, batch_size=128)
print("test loss, test acc:", results)

# Generate predictions (probabilities -- the output of the last layer)
# on new data using `predict`
print("Generate predictions for 3 samples")
predictions = model.predict(x_test[:3])
print("predictions shape:", predictions.shape)
Evaluate on test data
79/79 [==============================] - 0s 1ms/step - loss: 0.1310 - sparse_categorical_accuracy: 0.9637
test loss, test acc: [0.1309928148984909, 0.963699996471405]
Generate predictions for 3 samples
predictions shape: (3, 10)

Sekarang, mari kita tinjau setiap bagian dari alur kerja ini secara mendetail.

Metode compile() : menentukan kerugian, metrik, dan pengoptimal

Untuk melatih model dengan fit() , Anda perlu menentukan fungsi kerugian, pengoptimal, dan secara opsional, beberapa metrik untuk dipantau.

Anda meneruskan ini ke model sebagai argumen ke metode compile() :

model.compile(
    optimizer=keras.optimizers.RMSprop(learning_rate=1e-3),
    loss=keras.losses.SparseCategoricalCrossentropy(),
    metrics=[keras.metrics.SparseCategoricalAccuracy()],
)

Argumen metrics harus berupa daftar - model Anda dapat memiliki sejumlah metrik.

Jika model Anda memiliki beberapa keluaran, Anda dapat menentukan kerugian dan metrik yang berbeda untuk setiap keluaran, dan Anda dapat memodulasi kontribusi setiap keluaran ke total kerugian model. Anda akan menemukan detail lebih lanjut tentang ini di bagian "Meneruskan data ke model multi-input, multi-output" .

Perhatikan bahwa jika Anda puas dengan pengaturan default, dalam banyak kasus pengoptimal, kerugian, dan metrik dapat ditentukan melalui pengenal string sebagai pintasan:

model.compile(
    optimizer="rmsprop",
    loss="sparse_categorical_crossentropy",
    metrics=["sparse_categorical_accuracy"],
)

Untuk digunakan kembali nanti, mari letakkan definisi model dan langkah kompilasi dalam fungsi; kami akan memanggil mereka beberapa kali di berbagai contoh dalam panduan ini.

def get_uncompiled_model():
    inputs = keras.Input(shape=(784,), name="digits")
    x = layers.Dense(64, activation="relu", name="dense_1")(inputs)
    x = layers.Dense(64, activation="relu", name="dense_2")(x)
    outputs = layers.Dense(10, activation="softmax", name="predictions")(x)
    model = keras.Model(inputs=inputs, outputs=outputs)
    return model


def get_compiled_model():
    model = get_uncompiled_model()
    model.compile(
        optimizer="rmsprop",
        loss="sparse_categorical_crossentropy",
        metrics=["sparse_categorical_accuracy"],
    )
    return model

Banyak pengoptimal, kerugian, dan metrik bawaan tersedia

Secara umum, Anda tidak perlu membuat kerugian, metrik, atau pengoptimal sendiri dari awal, karena yang Anda butuhkan kemungkinan besar sudah menjadi bagian dari Keras API:

Pengoptimal:

  • SGD() (dengan atau tanpa momentum)
  • RMSprop()
  • Adam()
  • dll.

Kerugian:

  • MeanSquaredError()
  • KLDivergence()
  • CosineSimilarity()
  • dll.

Metrik:

  • AUC()
  • Precision()
  • Recall()
  • dll.

Kerugian kustom

Ada dua cara untuk memberikan kerugian kustom dengan Keras. Contoh pertama membuat fungsi yang menerima input y_true dan y_pred . Contoh berikut menunjukkan fungsi kerugian yang menghitung kesalahan kuadrat rata-rata antara data nyata dan prediksi:

def custom_mean_squared_error(y_true, y_pred):
    return tf.math.reduce_mean(tf.square(y_true - y_pred))


model = get_uncompiled_model()
model.compile(optimizer=keras.optimizers.Adam(), loss=custom_mean_squared_error)

# We need to one-hot encode the labels to use MSE
y_train_one_hot = tf.one_hot(y_train, depth=10)
model.fit(x_train, y_train_one_hot, batch_size=64, epochs=1)
782/782 [==============================] - 1s 1ms/step - loss: 0.0168

<tensorflow.python.keras.callbacks.History at 0x7f75581d56a0>

Jika Anda memerlukan fungsi kerugian yang mengambil parameter di samping y_true dan y_pred , Anda dapat membuat subkelas kelas tf.keras.losses.Loss dan mengimplementasikan dua metode berikut:

  • __init__(self) : menerima parameter untuk diteruskan selama panggilan fungsi kerugian Anda
  • call(self, y_true, y_pred) : gunakan target (y_true) dan prediksi model (y_pred) untuk menghitung kerugian model

Katakanlah Anda ingin menggunakan mean squared error, tetapi dengan istilah tambahan yang akan mengurangi nilai prediksi yang jauh dari 0,5 (kami berasumsi bahwa target kategorikal adalah one-hot encoded dan mengambil nilai antara 0 dan 1). Ini menciptakan insentif bagi model untuk tidak terlalu percaya diri, yang dapat membantu mengurangi overfitting (kita tidak akan tahu apakah itu berfungsi sampai kita mencobanya!).

Inilah cara Anda melakukannya:

class CustomMSE(keras.losses.Loss):
    def __init__(self, regularization_factor=0.1, name="custom_mse"):
        super().__init__(name=name)
        self.regularization_factor = regularization_factor

    def call(self, y_true, y_pred):
        mse = tf.math.reduce_mean(tf.square(y_true - y_pred))
        reg = tf.math.reduce_mean(tf.square(0.5 - y_pred))
        return mse + reg * self.regularization_factor


model = get_uncompiled_model()
model.compile(optimizer=keras.optimizers.Adam(), loss=CustomMSE())

y_train_one_hot = tf.one_hot(y_train, depth=10)
model.fit(x_train, y_train_one_hot, batch_size=64, epochs=1)
782/782 [==============================] - 1s 2ms/step - loss: 0.0390

<tensorflow.python.keras.callbacks.History at 0x7f7558184c88>

Metrik kustom

Jika Anda memerlukan metrik yang bukan bagian dari API, Anda dapat dengan mudah membuat metrik kustom dengan membuat subclass kelas tf.keras.metrics.Metric . Anda perlu menerapkan 4 metode:

  • __init__(self) , di mana Anda akan membuat variabel status untuk metrik Anda.
  • update_state(self, y_true, y_pred, sample_weight=None) , yang menggunakan target y_true dan prediksi model y_pred untuk memperbarui variabel status.
  • result(self) , yang menggunakan variabel keadaan untuk menghitung hasil akhir.
  • reset_states(self) , yang menginisialisasi ulang status metrik.

Pembaruan update_state() dan penghitungan hasil disimpan terpisah (masing-masing dalam update_state() dan result() ) karena dalam beberapa kasus, penghitungan hasil mungkin sangat mahal, dan hanya akan dilakukan secara berkala.

Berikut adalah contoh sederhana yang menunjukkan cara mengimplementasikan metrik CategoricalTruePositives , yang menghitung berapa banyak sampel yang diklasifikasikan dengan benar sebagai milik kelas tertentu:

class CategoricalTruePositives(keras.metrics.Metric):
    def __init__(self, name="categorical_true_positives", **kwargs):
        super(CategoricalTruePositives, self).__init__(name=name, **kwargs)
        self.true_positives = self.add_weight(name="ctp", initializer="zeros")

    def update_state(self, y_true, y_pred, sample_weight=None):
        y_pred = tf.reshape(tf.argmax(y_pred, axis=1), shape=(-1, 1))
        values = tf.cast(y_true, "int32") == tf.cast(y_pred, "int32")
        values = tf.cast(values, "float32")
        if sample_weight is not None:
            sample_weight = tf.cast(sample_weight, "float32")
            values = tf.multiply(values, sample_weight)
        self.true_positives.assign_add(tf.reduce_sum(values))

    def result(self):
        return self.true_positives

    def reset_states(self):
        # The state of the metric will be reset at the start of each epoch.
        self.true_positives.assign(0.0)


model = get_uncompiled_model()
model.compile(
    optimizer=keras.optimizers.RMSprop(learning_rate=1e-3),
    loss=keras.losses.SparseCategoricalCrossentropy(),
    metrics=[CategoricalTruePositives()],
)
model.fit(x_train, y_train, batch_size=64, epochs=3)
Epoch 1/3
782/782 [==============================] - 1s 2ms/step - loss: 0.3429 - categorical_true_positives: 45146.0000
Epoch 2/3
782/782 [==============================] - 1s 2ms/step - loss: 0.1560 - categorical_true_positives: 47637.0000
Epoch 3/3
782/782 [==============================] - 1s 2ms/step - loss: 0.1155 - categorical_true_positives: 48237.0000

<tensorflow.python.keras.callbacks.History at 0x7f755801bfd0>

Menangani kerugian dan metrik yang tidak sesuai dengan tanda tangan standar

Sebagian besar kerugian dan metrik dapat dihitung dari y_true dan y_pred , di mana y_pred adalah output dari model Anda. Tapi tidak semua dari mereka. Misalnya, kerugian regularisasi mungkin hanya memerlukan aktivasi lapisan (dalam kasus ini tidak ada target), dan aktivasi ini mungkin bukan keluaran model.

Dalam kasus seperti itu, Anda dapat memanggil self.add_loss(loss_value) dari dalam metode panggilan lapisan khusus. Kerugian yang ditambahkan dengan cara ini akan ditambahkan ke kerugian "utama" selama pelatihan (yang diteruskan ke compile() ). Berikut adalah contoh sederhana yang menambahkan regularisasi aktivitas (perhatikan bahwa regularisasi aktivitas ada di dalam semua lapisan Keras - lapisan ini hanya untuk memberikan contoh konkret):

class ActivityRegularizationLayer(layers.Layer):
    def call(self, inputs):
        self.add_loss(tf.reduce_sum(inputs) * 0.1)
        return inputs  # Pass-through layer.


inputs = keras.Input(shape=(784,), name="digits")
x = layers.Dense(64, activation="relu", name="dense_1")(inputs)

# Insert activity regularization as a layer
x = ActivityRegularizationLayer()(x)

x = layers.Dense(64, activation="relu", name="dense_2")(x)
outputs = layers.Dense(10, name="predictions")(x)

model = keras.Model(inputs=inputs, outputs=outputs)
model.compile(
    optimizer=keras.optimizers.RMSprop(learning_rate=1e-3),
    loss=keras.losses.SparseCategoricalCrossentropy(from_logits=True),
)

# The displayed loss will be much higher than before
# due to the regularization component.
model.fit(x_train, y_train, batch_size=64, epochs=1)
782/782 [==============================] - 1s 2ms/step - loss: 2.4756

<tensorflow.python.keras.callbacks.History at 0x7f75501e1f98>

Anda dapat melakukan hal yang sama untuk mencatat nilai metrik, menggunakan add_metric() :

class MetricLoggingLayer(layers.Layer):
    def call(self, inputs):
        # The `aggregation` argument defines
        # how to aggregate the per-batch values
        # over each epoch:
        # in this case we simply average them.
        self.add_metric(
            keras.backend.std(inputs), name="std_of_activation", aggregation="mean"
        )
        return inputs  # Pass-through layer.


inputs = keras.Input(shape=(784,), name="digits")
x = layers.Dense(64, activation="relu", name="dense_1")(inputs)

# Insert std logging as a layer.
x = MetricLoggingLayer()(x)

x = layers.Dense(64, activation="relu", name="dense_2")(x)
outputs = layers.Dense(10, name="predictions")(x)

model = keras.Model(inputs=inputs, outputs=outputs)
model.compile(
    optimizer=keras.optimizers.RMSprop(learning_rate=1e-3),
    loss=keras.losses.SparseCategoricalCrossentropy(from_logits=True),
)
model.fit(x_train, y_train, batch_size=64, epochs=1)
782/782 [==============================] - 1s 2ms/step - loss: 0.3493 - std_of_activation: 0.9813

<tensorflow.python.keras.callbacks.History at 0x7f75500321d0>

Di API Fungsional , Anda juga dapat memanggil model.add_loss(loss_tensor) , atau model.add_metric(metric_tensor, name, aggregation) .

Berikut contoh sederhananya:

inputs = keras.Input(shape=(784,), name="digits")
x1 = layers.Dense(64, activation="relu", name="dense_1")(inputs)
x2 = layers.Dense(64, activation="relu", name="dense_2")(x1)
outputs = layers.Dense(10, name="predictions")(x2)
model = keras.Model(inputs=inputs, outputs=outputs)

model.add_loss(tf.reduce_sum(x1) * 0.1)

model.add_metric(keras.backend.std(x1), name="std_of_activation", aggregation="mean")

model.compile(
    optimizer=keras.optimizers.RMSprop(1e-3),
    loss=keras.losses.SparseCategoricalCrossentropy(from_logits=True),
)
model.fit(x_train, y_train, batch_size=64, epochs=1)
782/782 [==============================] - 1s 2ms/step - loss: 2.5230 - std_of_activation: 0.0020

<tensorflow.python.keras.callbacks.History at 0x7f74ec71d828>

Perhatikan bahwa ketika Anda melewatkan kerugian melalui add_loss() , itu menjadi mungkin untuk memanggil compile() tanpa fungsi kerugian, karena model sudah memiliki kerugian untuk diminimalkan.

Pertimbangkan layer LogisticEndpoint berikut: dibutuhkan sebagai target input & logit, dan ini melacak kerugian add_loss() melalui add_loss() . Ini juga melacak akurasi klasifikasi melalui add_metric() .

class LogisticEndpoint(keras.layers.Layer):
    def __init__(self, name=None):
        super(LogisticEndpoint, self).__init__(name=name)
        self.loss_fn = keras.losses.BinaryCrossentropy(from_logits=True)
        self.accuracy_fn = keras.metrics.BinaryAccuracy()

    def call(self, targets, logits, sample_weights=None):
        # Compute the training-time loss value and add it
        # to the layer using `self.add_loss()`.
        loss = self.loss_fn(targets, logits, sample_weights)
        self.add_loss(loss)

        # Log accuracy as a metric and add it
        # to the layer using `self.add_metric()`.
        acc = self.accuracy_fn(targets, logits, sample_weights)
        self.add_metric(acc, name="accuracy")

        # Return the inference-time prediction tensor (for `.predict()`).
        return tf.nn.softmax(logits)

Anda dapat menggunakannya dalam model dengan dua input (input data & target), yang dikompilasi tanpa argumen loss , seperti ini:

import numpy as np

inputs = keras.Input(shape=(3,), name="inputs")
targets = keras.Input(shape=(10,), name="targets")
logits = keras.layers.Dense(10)(inputs)
predictions = LogisticEndpoint(name="predictions")(logits, targets)

model = keras.Model(inputs=[inputs, targets], outputs=predictions)
model.compile(optimizer="adam")  # No loss argument!

data = {
    "inputs": np.random.random((3, 3)),
    "targets": np.random.random((3, 10)),
}
model.fit(data)
1/1 [==============================] - 0s 1ms/step - loss: 0.9344 - binary_accuracy: 0.0000e+00

<tensorflow.python.keras.callbacks.History at 0x7f7558339f28>

Untuk informasi selengkapnya tentang melatih model multi-input, lihat bagian Meneruskan data ke model multi-input, multi-output .

Secara otomatis memisahkan set pisahan validasi

Dalam contoh end-to-end pertama yang Anda lihat, kami menggunakan argumen validation_data untuk meneruskan tuple array NumPy (x_val, y_val) ke model untuk mengevaluasi kerugian validasi dan metrik validasi di akhir setiap epoch.

Berikut opsi lain: argumen validation_split memungkinkan Anda untuk secara otomatis memesan sebagian dari data pelatihan Anda untuk validasi. Nilai argumen mewakili pecahan data yang akan dicadangkan untuk validasi, jadi harus disetel ke angka yang lebih tinggi dari 0 dan lebih rendah dari 1. Misalnya, validation_split=0.2 berarti "gunakan 20% data untuk validasi", dan validation_split=0.6 berarti "menggunakan 60% data untuk validasi".

Cara validasi dihitung adalah dengan mengambil sampel x% terakhir dari array yang diterima oleh panggilan fit, sebelum pengacakan.

Perhatikan bahwa Anda hanya dapat menggunakan validation_split saat berlatih dengan data NumPy.

model = get_compiled_model()
model.fit(x_train, y_train, batch_size=64, validation_split=0.2, epochs=1)
625/625 [==============================] - 1s 2ms/step - loss: 0.3753 - sparse_categorical_accuracy: 0.8927 - val_loss: 0.2252 - val_sparse_categorical_accuracy: 0.9344

<tensorflow.python.keras.callbacks.History at 0x7f755826f160>

Pelatihan & evaluasi dari tf.data Datasets

Dalam beberapa paragraf terakhir, Anda telah melihat bagaimana menangani kerugian, metrik, dan pengoptimalan, dan Anda telah melihat bagaimana menggunakan validation_data dan validation_split argumen dalam fit, ketika data Anda dilewatkan sebagai array NumPy.

Sekarang mari kita lihat kasus di mana data Anda datang dalam bentuk objek tf.data.Dataset .

API tf.data adalah sekumpulan utilitas di TensorFlow 2.0 untuk memuat dan memproses data terlebih dahulu dengan cara yang cepat dan skalabel.

Untuk panduan lengkap tentang membuat Datasets , lihat dokumentasi tf.data .

Anda bisa meneruskan instance Dataset langsung ke metode fit() , evaluate() , dan predict() :

model = get_compiled_model()

# First, let's create a training Dataset instance.
# For the sake of our example, we'll use the same MNIST data as before.
train_dataset = tf.data.Dataset.from_tensor_slices((x_train, y_train))
# Shuffle and slice the dataset.
train_dataset = train_dataset.shuffle(buffer_size=1024).batch(64)

# Now we get a test dataset.
test_dataset = tf.data.Dataset.from_tensor_slices((x_test, y_test))
test_dataset = test_dataset.batch(64)

# Since the dataset already takes care of batching,
# we don't pass a `batch_size` argument.
model.fit(train_dataset, epochs=3)

# You can also evaluate or predict on a dataset.
print("Evaluate")
result = model.evaluate(test_dataset)
dict(zip(model.metrics_names, result))
Epoch 1/3
782/782 [==============================] - 2s 2ms/step - loss: 0.3404 - sparse_categorical_accuracy: 0.9048
Epoch 2/3
782/782 [==============================] - 2s 2ms/step - loss: 0.1596 - sparse_categorical_accuracy: 0.9529
Epoch 3/3
782/782 [==============================] - 2s 2ms/step - loss: 0.1165 - sparse_categorical_accuracy: 0.9658
Evaluate
157/157 [==============================] - 0s 1ms/step - loss: 0.1147 - sparse_categorical_accuracy: 0.9659

{'loss': 0.11471886932849884,
 'sparse_categorical_accuracy': 0.9659000039100647}

Perhatikan bahwa Kumpulan Data disetel ulang di akhir setiap epoch, sehingga dapat digunakan kembali di epoch berikutnya.

Jika Anda ingin menjalankan pelatihan hanya pada sejumlah kelompok tertentu dari steps_per_epoch Data ini, Anda dapat meneruskan argumen steps_per_epoch , yang menentukan berapa banyak langkah pelatihan yang harus dijalankan model menggunakan Set Data ini sebelum melanjutkan ke epoch berikutnya.

Jika Anda melakukan ini, kumpulan data tidak disetel ulang di akhir setiap epoch, sebagai gantinya kami terus menggambar kumpulan berikutnya. Kumpulan data pada akhirnya akan kehabisan data (kecuali jika itu adalah kumpulan data yang terus berulang).

model = get_compiled_model()

# Prepare the training dataset
train_dataset = tf.data.Dataset.from_tensor_slices((x_train, y_train))
train_dataset = train_dataset.shuffle(buffer_size=1024).batch(64)

# Only use the 100 batches per epoch (that's 64 * 100 samples)
model.fit(train_dataset, epochs=3, steps_per_epoch=100)
Epoch 1/3
100/100 [==============================] - 0s 2ms/step - loss: 0.8448 - sparse_categorical_accuracy: 0.7734
Epoch 2/3
100/100 [==============================] - 0s 2ms/step - loss: 0.3912 - sparse_categorical_accuracy: 0.8922
Epoch 3/3
100/100 [==============================] - 0s 2ms/step - loss: 0.3399 - sparse_categorical_accuracy: 0.9011

<tensorflow.python.keras.callbacks.History at 0x7f74ec5cf7f0>

Menggunakan set data validasi

Anda bisa meneruskan instance Dataset sebagai argumen validation_data di fit() :

model = get_compiled_model()

# Prepare the training dataset
train_dataset = tf.data.Dataset.from_tensor_slices((x_train, y_train))
train_dataset = train_dataset.shuffle(buffer_size=1024).batch(64)

# Prepare the validation dataset
val_dataset = tf.data.Dataset.from_tensor_slices((x_val, y_val))
val_dataset = val_dataset.batch(64)

model.fit(train_dataset, epochs=1, validation_data=val_dataset)
782/782 [==============================] - 2s 2ms/step - loss: 0.3384 - sparse_categorical_accuracy: 0.9032 - val_loss: 0.1752 - val_sparse_categorical_accuracy: 0.9518

<tensorflow.python.keras.callbacks.History at 0x7f74ec4d2ba8>

Di akhir setiap epoch, model akan melakukan iterasi atas dataset validasi dan menghitung kerugian validasi dan metrik validasi.

Jika Anda ingin menjalankan validasi hanya pada sejumlah batch tertentu dari set data ini, Anda dapat meneruskan argumen validation_steps , yang menentukan berapa banyak langkah validasi yang harus dijalankan model dengan set data validasi sebelum menghentikan validasi dan melanjutkan ke epoch berikutnya:

model = get_compiled_model()

# Prepare the training dataset
train_dataset = tf.data.Dataset.from_tensor_slices((x_train, y_train))
train_dataset = train_dataset.shuffle(buffer_size=1024).batch(64)

# Prepare the validation dataset
val_dataset = tf.data.Dataset.from_tensor_slices((x_val, y_val))
val_dataset = val_dataset.batch(64)

model.fit(
    train_dataset,
    epochs=1,
    # Only run validation using the first 10 batches of the dataset
    # using the `validation_steps` argument
    validation_data=val_dataset,
    validation_steps=10,
)
782/782 [==============================] - 2s 2ms/step - loss: 0.3503 - sparse_categorical_accuracy: 0.9021 - val_loss: 0.3226 - val_sparse_categorical_accuracy: 0.9156

<tensorflow.python.keras.callbacks.History at 0x7f74ec4caa58>

Perhatikan bahwa set data validasi akan disetel ulang setelah digunakan (sehingga Anda akan selalu mengevaluasi sampel yang sama dari waktu ke waktu).

Argumen validation_split (membuat set pisahan dari data pelatihan) tidak didukung saat melatih dari objek Set Dataset , karena fitur ini memerlukan kemampuan untuk mengindeks sampel set data, yang secara umum tidak mungkin dilakukan dengan Dataset API.

Mendukung format masukan lainnya

Selain array NumPy, eager tensor, dan Set Datasets TensorFlow, model Keras dapat dilatih menggunakan kerangka data Pandas, atau dari generator Python yang menghasilkan kumpulan data & label.

Khususnya, kelas keras.utils.Sequence menawarkan antarmuka sederhana untuk membuat generator data Python yang multiprosesing-aware dan dapat diacak.

Secara umum, kami menyarankan Anda menggunakan:

  • NumPy input data jika data Anda kecil dan muat di memori
  • Dataset objek jika Anda memiliki dataset yang besar dan Anda perlu melakukan pelatihan didistribusikan
  • Sequence objek jika Anda memiliki kumpulan data yang besar dan Anda perlu melakukan banyak pemrosesan sisi Python khusus yang tidak dapat dilakukan di TensorFlow (misalnya, jika Anda mengandalkan pustaka eksternal untuk pemuatan atau pemrosesan awal data).

Menggunakan objek keras.utils.Sequence sebagai input

keras.utils.Sequence adalah utilitas yang Anda dapat membuat subclass untuk mendapatkan generator Python dengan dua properti penting:

  • Ini bekerja dengan baik dengan multiprocessing.
  • Dapat diacak (misalnya saat mengoper shuffle=True in fit() ).

Sebuah Sequence harus menerapkan dua metode:

  • __getitem__
  • __len__

Metode __getitem__ harus mengembalikan kumpulan lengkap. Jika Anda ingin mengubah kumpulan data di antara zaman, Anda dapat mengimplementasikan on_epoch_end .

Berikut contoh singkatnya:

from skimage.io import imread
from skimage.transform import resize
import numpy as np

# Here, `filenames` is list of path to the images
# and `labels` are the associated labels.

class CIFAR10Sequence(Sequence):
    def __init__(self, filenames, labels, batch_size):
        self.filenames, self.labels = filenames, labels
        self.batch_size = batch_size

    def __len__(self):
        return int(np.ceil(len(self.filenames) / float(self.batch_size)))

    def __getitem__(self, idx):
        batch_x = self.filenames[idx * self.batch_size:(idx + 1) * self.batch_size]
        batch_y = self.labels[idx * self.batch_size:(idx + 1) * self.batch_size]
        return np.array([
            resize(imread(filename), (200, 200))
               for filename in batch_x]), np.array(batch_y)

sequence = CIFAR10Sequence(filenames, labels, batch_size)
model.fit(sequence, epochs=10)

Menggunakan pembobotan sampel dan pembobotan kelas

Dengan pengaturan default, bobot sampel ditentukan oleh frekuensinya dalam dataset. Ada dua metode untuk memberi bobot pada data, terlepas dari frekuensi sampel:

  • Bobot kelas
  • Berat sampel

Bobot kelas

Ini diatur dengan melewati sebuah kamus ke class_weight argumen untuk Model.fit() . Kamus ini memetakan indeks kelas ke bobot yang harus digunakan untuk sampel yang termasuk dalam kelas ini.

Ini dapat digunakan untuk menyeimbangkan kelas tanpa pengambilan sampel ulang, atau untuk melatih model yang lebih mementingkan kelas tertentu.

Misalnya, jika kelas "0" setengah dari kelas "1" dalam data Anda, Anda dapat menggunakan Model.fit(..., class_weight={0: 1., 1: 0.5}) .

Berikut adalah contoh NumPy di ​​mana kami menggunakan bobot kelas atau bobot sampel untuk lebih mementingkan klasifikasi kelas # 5 yang benar (yang merupakan digit "5" dalam dataset MNIST).

import numpy as np

class_weight = {
    0: 1.0,
    1: 1.0,
    2: 1.0,
    3: 1.0,
    4: 1.0,
    # Set weight "2" for class "5",
    # making this class 2x more important
    5: 2.0,
    6: 1.0,
    7: 1.0,
    8: 1.0,
    9: 1.0,
}

print("Fit with class weight")
model = get_compiled_model()
model.fit(x_train, y_train, class_weight=class_weight, batch_size=64, epochs=1)
Fit with class weight
782/782 [==============================] - 2s 2ms/step - loss: 0.3729 - sparse_categorical_accuracy: 0.9025

<tensorflow.python.keras.callbacks.History at 0x7f74ec265358>

Berat sampel

Untuk kontrol yang sangat baik, atau jika Anda tidak membuat pengklasifikasi, Anda dapat menggunakan "bobot sampel".

  • Ketika pelatihan dari data NumPy: Lulus sample_weight argumen untuk Model.fit() .
  • Saat melatih dari tf.data atau jenis iterator lainnya: tupel Yield (input_batch, label_batch, sample_weight_batch) .

Larik "bobot sampel" adalah larik angka yang menentukan berapa bobot yang harus dimiliki setiap sampel dalam kelompok dalam menghitung kerugian total. Ini biasanya digunakan dalam masalah klasifikasi yang tidak seimbang (idenya adalah untuk memberi bobot lebih pada kelas yang jarang terlihat).

Jika bobot yang digunakan adalah satu dan nol, larik dapat digunakan sebagai penutup untuk fungsi kerugian (sepenuhnya mengabaikan kontribusi sampel tertentu ke kerugian total).

sample_weight = np.ones(shape=(len(y_train),))
sample_weight[y_train == 5] = 2.0

print("Fit with sample weight")
model = get_compiled_model()
model.fit(x_train, y_train, sample_weight=sample_weight, batch_size=64, epochs=1)
Fit with sample weight
782/782 [==============================] - 2s 2ms/step - loss: 0.3837 - sparse_categorical_accuracy: 0.8984

<tensorflow.python.keras.callbacks.History at 0x7f74ec11afd0>

Berikut contoh Dataset cocok:

sample_weight = np.ones(shape=(len(y_train),))
sample_weight[y_train == 5] = 2.0

# Create a Dataset that includes sample weights
# (3rd element in the return tuple).
train_dataset = tf.data.Dataset.from_tensor_slices((x_train, y_train, sample_weight))

# Shuffle and slice the dataset.
train_dataset = train_dataset.shuffle(buffer_size=1024).batch(64)

model = get_compiled_model()
model.fit(train_dataset, epochs=1)
782/782 [==============================] - 2s 2ms/step - loss: 0.3792 - sparse_categorical_accuracy: 0.9030

<tensorflow.python.keras.callbacks.History at 0x7f74d47f2208>

Meneruskan data ke model multi-input, multi-output

Dalam contoh sebelumnya, kami mempertimbangkan model dengan input tunggal (tensor bentuk (764,) ) dan output tunggal (tensor prediksi bentuk (10,) ). Tapi bagaimana dengan model yang memiliki banyak input atau output?

Pertimbangkan model berikut, yang memiliki input gambar bentuk (32, 32, 3) (itu (height, width, channels) ) dan masukan deret waktu bentuk (None, 10) (itu (timesteps, features) ). Model kita akan memiliki dua keluaran yang dihitung dari kombinasi masukan ini: "skor" (dari bentuk (1,) ) dan distribusi probabilitas atas lima kelas (bentuk (5,) ).

image_input = keras.Input(shape=(32, 32, 3), name="img_input")
timeseries_input = keras.Input(shape=(None, 10), name="ts_input")

x1 = layers.Conv2D(3, 3)(image_input)
x1 = layers.GlobalMaxPooling2D()(x1)

x2 = layers.Conv1D(3, 3)(timeseries_input)
x2 = layers.GlobalMaxPooling1D()(x2)

x = layers.concatenate([x1, x2])

score_output = layers.Dense(1, name="score_output")(x)
class_output = layers.Dense(5, name="class_output")(x)

model = keras.Model(
    inputs=[image_input, timeseries_input], outputs=[score_output, class_output]
)

Mari kita plot model ini, sehingga Anda dapat dengan jelas melihat apa yang kita lakukan di sini (perhatikan bahwa bentuk yang ditampilkan di plot adalah bentuk batch, bukan bentuk per sampel).

keras.utils.plot_model(model, "multi_input_and_output_model.png", show_shapes=True)

png

Pada waktu kompilasi, kita dapat menentukan kerugian yang berbeda untuk keluaran yang berbeda, dengan meneruskan fungsi kerugian sebagai daftar:

model.compile(
    optimizer=keras.optimizers.RMSprop(1e-3),
    loss=[keras.losses.MeanSquaredError(), keras.losses.CategoricalCrossentropy()],
)

Jika kita hanya meneruskan satu fungsi kerugian ke model, fungsi kerugian yang sama akan diterapkan ke setiap keluaran (yang tidak sesuai di sini).

Begitu juga untuk metrik:

model.compile(
    optimizer=keras.optimizers.RMSprop(1e-3),
    loss=[keras.losses.MeanSquaredError(), keras.losses.CategoricalCrossentropy()],
    metrics=[
        [
            keras.metrics.MeanAbsolutePercentageError(),
            keras.metrics.MeanAbsoluteError(),
        ],
        [keras.metrics.CategoricalAccuracy()],
    ],
)

Karena kami memberi nama pada lapisan keluaran kami, kami juga dapat menentukan kerugian dan metrik per keluaran melalui sebuah dict:

model.compile(
    optimizer=keras.optimizers.RMSprop(1e-3),
    loss={
        "score_output": keras.losses.MeanSquaredError(),
        "class_output": keras.losses.CategoricalCrossentropy(),
    },
    metrics={
        "score_output": [
            keras.metrics.MeanAbsolutePercentageError(),
            keras.metrics.MeanAbsoluteError(),
        ],
        "class_output": [keras.metrics.CategoricalAccuracy()],
    },
)

Kami merekomendasikan penggunaan nama dan dicts eksplisit jika Anda memiliki lebih dari 2 keluaran.

Dimungkinkan untuk memberikan bobot yang berbeda untuk kerugian khusus keluaran yang berbeda (misalnya, seseorang mungkin ingin mengistimewakan kerugian "skor" dalam contoh kita, dengan memberikan 2x pentingnya kelas yang hilang), menggunakan argumen loss_weights :

model.compile(
    optimizer=keras.optimizers.RMSprop(1e-3),
    loss={
        "score_output": keras.losses.MeanSquaredError(),
        "class_output": keras.losses.CategoricalCrossentropy(),
    },
    metrics={
        "score_output": [
            keras.metrics.MeanAbsolutePercentageError(),
            keras.metrics.MeanAbsoluteError(),
        ],
        "class_output": [keras.metrics.CategoricalAccuracy()],
    },
    loss_weights={"score_output": 2.0, "class_output": 1.0},
)

Anda juga dapat memilih untuk tidak menghitung kerugian untuk keluaran tertentu, jika keluaran ini dimaksudkan untuk prediksi tetapi bukan untuk pelatihan:

# List loss version
model.compile(
    optimizer=keras.optimizers.RMSprop(1e-3),
    loss=[None, keras.losses.CategoricalCrossentropy()],
)

# Or dict loss version
model.compile(
    optimizer=keras.optimizers.RMSprop(1e-3),
    loss={"class_output": keras.losses.CategoricalCrossentropy()},
)

Meneruskan data ke model multi-input atau multi-output yang sesuai bekerja dengan cara yang sama seperti menentukan fungsi kerugian dalam kompilasi: Anda dapat meneruskan daftar array NumPy (dengan pemetaan 1: 1 ke output yang menerima fungsi kerugian) atau dicts memetakan nama keluaran ke array NumPy .

model.compile(
    optimizer=keras.optimizers.RMSprop(1e-3),
    loss=[keras.losses.MeanSquaredError(), keras.losses.CategoricalCrossentropy()],
)

# Generate dummy NumPy data
img_data = np.random.random_sample(size=(100, 32, 32, 3))
ts_data = np.random.random_sample(size=(100, 20, 10))
score_targets = np.random.random_sample(size=(100, 1))
class_targets = np.random.random_sample(size=(100, 5))

# Fit on lists
model.fit([img_data, ts_data], [score_targets, class_targets], batch_size=32, epochs=1)

# Alternatively, fit on dicts
model.fit(
    {"img_input": img_data, "ts_input": ts_data},
    {"score_output": score_targets, "class_output": class_targets},
    batch_size=32,
    epochs=1,
)
4/4 [==============================] - 0s 6ms/step - loss: 20.0184 - score_output_loss: 0.5383 - class_output_loss: 19.4800
4/4 [==============================] - 0s 4ms/step - loss: 17.7266 - score_output_loss: 0.3122 - class_output_loss: 17.4145

<tensorflow.python.keras.callbacks.History at 0x7f755022feb8>

Berikut kasus penggunaan Dataset : sama seperti yang kita lakukan untuk array NumPy, Dataset harus mengembalikan tupel dicts.

train_dataset = tf.data.Dataset.from_tensor_slices(
    (
        {"img_input": img_data, "ts_input": ts_data},
        {"score_output": score_targets, "class_output": class_targets},
    )
)
train_dataset = train_dataset.shuffle(buffer_size=1024).batch(64)

model.fit(train_dataset, epochs=1)
2/2 [==============================] - 0s 8ms/step - loss: 17.2156 - score_output_loss: 0.2522 - class_output_loss: 16.9634

<tensorflow.python.keras.callbacks.History at 0x7f75c56c1128>

Menggunakan panggilan balik

Callback di Keras adalah objek yang dipanggil di berbagai titik selama pelatihan (di awal epoch, di akhir batch, di akhir epoch, dll.) Dan yang dapat digunakan untuk mengimplementasikan perilaku seperti:

  • Melakukan validasi di berbagai titik selama pelatihan (di luar validasi per epoch bawaan)
  • Memeriksa model secara berkala atau ketika melebihi ambang akurasi tertentu
  • Mengubah kecepatan pembelajaran model saat pelatihan tampaknya tidak berubah
  • Melakukan fine-tuning pada lapisan atas saat pelatihan tampaknya tidak berubah
  • Mengirim email atau pemberitahuan pesan instan ketika pelatihan berakhir atau ketika ambang kinerja tertentu terlampaui
  • Dll

Callback dapat dikirimkan sebagai daftar untuk panggilan Anda agar fit() :

model = get_compiled_model()

callbacks = [
    keras.callbacks.EarlyStopping(
        # Stop training when `val_loss` is no longer improving
        monitor="val_loss",
        # "no longer improving" being defined as "no better than 1e-2 less"
        min_delta=1e-2,
        # "no longer improving" being further defined as "for at least 2 epochs"
        patience=2,
        verbose=1,
    )
]
model.fit(
    x_train,
    y_train,
    epochs=20,
    batch_size=64,
    callbacks=callbacks,
    validation_split=0.2,
)
Epoch 1/20
625/625 [==============================] - 1s 2ms/step - loss: 0.3816 - sparse_categorical_accuracy: 0.8913 - val_loss: 0.2325 - val_sparse_categorical_accuracy: 0.9304
Epoch 2/20
625/625 [==============================] - 1s 2ms/step - loss: 0.1773 - sparse_categorical_accuracy: 0.9477 - val_loss: 0.2088 - val_sparse_categorical_accuracy: 0.9343
Epoch 3/20
625/625 [==============================] - 1s 2ms/step - loss: 0.1293 - sparse_categorical_accuracy: 0.9606 - val_loss: 0.1515 - val_sparse_categorical_accuracy: 0.9568
Epoch 4/20
625/625 [==============================] - 1s 2ms/step - loss: 0.1009 - sparse_categorical_accuracy: 0.9700 - val_loss: 0.1376 - val_sparse_categorical_accuracy: 0.9607
Epoch 5/20
625/625 [==============================] - 1s 2ms/step - loss: 0.0821 - sparse_categorical_accuracy: 0.9747 - val_loss: 0.1533 - val_sparse_categorical_accuracy: 0.9545
Epoch 6/20
625/625 [==============================] - 1s 2ms/step - loss: 0.0704 - sparse_categorical_accuracy: 0.9794 - val_loss: 0.1319 - val_sparse_categorical_accuracy: 0.9616
Epoch 00006: early stopping

<tensorflow.python.keras.callbacks.History at 0x7f74d46abdd8>

Banyak callback bawaan tersedia

  • ModelCheckpoint : Simpan model secara berkala.
  • EarlyStopping : Hentikan pelatihan saat pelatihan tidak lagi meningkatkan metrik validasi.
  • TensorBoard : menulis log model secara berkala yang dapat divisualisasikan di TensorBoard (detail selengkapnya di bagian "Visualisasi").
  • CSVLogger : mengalirkan data kerugian dan metrik ke file CSV.
  • dll.

Lihat dokumentasi callback untuk daftar lengkapnya.

Menulis panggilan balik Anda sendiri

Anda bisa membuat callback kustom dengan memperluas kelas dasar keras.callbacks.Callback . Callback memiliki akses ke model terkaitnya melalui properti kelas self.model .

Pastikan untuk membaca panduan lengkap untuk menulis panggilan balik khusus .

Berikut adalah contoh sederhana menyimpan daftar nilai kerugian per batch selama pelatihan:

class LossHistory(keras.callbacks.Callback):
    def on_train_begin(self, logs):
        self.per_batch_losses = []

    def on_batch_end(self, batch, logs):
        self.per_batch_losses.append(logs.get("loss"))

Model pos pemeriksaan

Saat Anda melatih model pada set data yang relatif besar, penting untuk menyimpan checkpoint model Anda pada interval yang sering.

Cara termudah untuk melakukannya adalah dengan callback ModelCheckpoint :

model = get_compiled_model()

callbacks = [
    keras.callbacks.ModelCheckpoint(
        # Path where to save the model
        # The two parameters below mean that we will overwrite
        # the current checkpoint if and only if
        # the `val_loss` score has improved.
        # The saved model name will include the current epoch.
        filepath="mymodel_{epoch}",
        save_best_only=True,  # Only save a model if `val_loss` has improved.
        monitor="val_loss",
        verbose=1,
    )
]
model.fit(
    x_train, y_train, epochs=2, batch_size=64, callbacks=callbacks, validation_split=0.2
)
Epoch 1/2
608/625 [============================>.] - ETA: 0s - loss: 0.3797 - sparse_categorical_accuracy: 0.8940
Epoch 00001: val_loss improved from inf to 0.23986, saving model to mymodel_1
WARNING:tensorflow:From /tmpfs/src/tf_docs_env/lib/python3.6/site-packages/tensorflow/python/training/tracking/tracking.py:111: Model.state_updates (from tensorflow.python.keras.engine.training) is deprecated and will be removed in a future version.
Instructions for updating:
This property should not be used in TensorFlow 2.0, as updates are applied automatically.
WARNING:tensorflow:From /tmpfs/src/tf_docs_env/lib/python3.6/site-packages/tensorflow/python/training/tracking/tracking.py:111: Layer.updates (from tensorflow.python.keras.engine.base_layer) is deprecated and will be removed in a future version.
Instructions for updating:
This property should not be used in TensorFlow 2.0, as updates are applied automatically.
INFO:tensorflow:Assets written to: mymodel_1/assets
625/625 [==============================] - 2s 3ms/step - loss: 0.3765 - sparse_categorical_accuracy: 0.8949 - val_loss: 0.2399 - val_sparse_categorical_accuracy: 0.9276
Epoch 2/2
606/625 [============================>.] - ETA: 0s - loss: 0.1758 - sparse_categorical_accuracy: 0.9474
Epoch 00002: val_loss improved from 0.23986 to 0.19765, saving model to mymodel_2
INFO:tensorflow:Assets written to: mymodel_2/assets
625/625 [==============================] - 2s 3ms/step - loss: 0.1751 - sparse_categorical_accuracy: 0.9477 - val_loss: 0.1976 - val_sparse_categorical_accuracy: 0.9409

<tensorflow.python.keras.callbacks.History at 0x7f7550171f28>

Callback ModelCheckpoint dapat digunakan untuk mengimplementasikan toleransi kesalahan: kemampuan untuk memulai ulang pelatihan dari status model yang terakhir disimpan jika pelatihan diinterupsi secara acak. Inilah contoh dasarnya:

import os

# Prepare a directory to store all the checkpoints.
checkpoint_dir = "./ckpt"
if not os.path.exists(checkpoint_dir):
    os.makedirs(checkpoint_dir)


def make_or_restore_model():
    # Either restore the latest model, or create a fresh one
    # if there is no checkpoint available.
    checkpoints = [checkpoint_dir + "/" + name for name in os.listdir(checkpoint_dir)]
    if checkpoints:
        latest_checkpoint = max(checkpoints, key=os.path.getctime)
        print("Restoring from", latest_checkpoint)
        return keras.models.load_model(latest_checkpoint)
    print("Creating a new model")
    return get_compiled_model()


model = make_or_restore_model()
callbacks = [
    # This callback saves a SavedModel every 100 batches.
    # We include the training loss in the saved model name.
    keras.callbacks.ModelCheckpoint(
        filepath=checkpoint_dir + "/ckpt-loss={loss:.2f}", save_freq=100
    )
]
model.fit(x_train, y_train, epochs=1, callbacks=callbacks)
Creating a new model
  94/1563 [>.............................] - ETA: 3s - loss: 0.9261 - sparse_categorical_accuracy: 0.7420INFO:tensorflow:Assets written to: ./ckpt/ckpt-loss=0.90/assets
 192/1563 [==>...........................] - ETA: 6s - loss: 0.6734 - sparse_categorical_accuracy: 0.8097INFO:tensorflow:Assets written to: ./ckpt/ckpt-loss=0.66/assets
 292/1563 [====>.........................] - ETA: 6s - loss: 0.5676 - sparse_categorical_accuracy: 0.8390INFO:tensorflow:Assets written to: ./ckpt/ckpt-loss=0.56/assets
 393/1563 [======>.......................] - ETA: 6s - loss: 0.5077 - sparse_categorical_accuracy: 0.8543INFO:tensorflow:Assets written to: ./ckpt/ckpt-loss=0.51/assets
 490/1563 [========>.....................] - ETA: 5s - loss: 0.4665 - sparse_categorical_accuracy: 0.8652INFO:tensorflow:Assets written to: ./ckpt/ckpt-loss=0.46/assets
 589/1563 [==========>...................] - ETA: 5s - loss: 0.4356 - sparse_categorical_accuracy: 0.8735INFO:tensorflow:Assets written to: ./ckpt/ckpt-loss=0.43/assets
 690/1563 [============>.................] - ETA: 4s - loss: 0.4077 - sparse_categorical_accuracy: 0.8813INFO:tensorflow:Assets written to: ./ckpt/ckpt-loss=0.41/assets
 791/1563 [==============>...............] - ETA: 4s - loss: 0.3883 - sparse_categorical_accuracy: 0.8873INFO:tensorflow:Assets written to: ./ckpt/ckpt-loss=0.39/assets
 892/1563 [================>.............] - ETA: 3s - loss: 0.3715 - sparse_categorical_accuracy: 0.8921INFO:tensorflow:Assets written to: ./ckpt/ckpt-loss=0.37/assets
 992/1563 [==================>...........] - ETA: 3s - loss: 0.3569 - sparse_categorical_accuracy: 0.8964INFO:tensorflow:Assets written to: ./ckpt/ckpt-loss=0.36/assets
1092/1563 [===================>..........] - ETA: 2s - loss: 0.3444 - sparse_categorical_accuracy: 0.8994INFO:tensorflow:Assets written to: ./ckpt/ckpt-loss=0.34/assets
1194/1563 [=====================>........] - ETA: 2s - loss: 0.3315 - sparse_categorical_accuracy: 0.9025INFO:tensorflow:Assets written to: ./ckpt/ckpt-loss=0.33/assets
1293/1563 [=======================>......] - ETA: 1s - loss: 0.3217 - sparse_categorical_accuracy: 0.9056INFO:tensorflow:Assets written to: ./ckpt/ckpt-loss=0.32/assets
1383/1563 [=========================>....] - ETA: 1s - loss: 0.3145 - sparse_categorical_accuracy: 0.9077INFO:tensorflow:Assets written to: ./ckpt/ckpt-loss=0.31/assets
1478/1563 [===========================>..] - ETA: 0s - loss: 0.3057 - sparse_categorical_accuracy: 0.9102INFO:tensorflow:Assets written to: ./ckpt/ckpt-loss=0.30/assets
1563/1563 [==============================] - 9s 6ms/step - loss: 0.2996 - sparse_categorical_accuracy: 0.9119

<tensorflow.python.keras.callbacks.History at 0x7f74ec20d668>

Anda menelepon juga menulis panggilan balik Anda sendiri untuk menyimpan dan memulihkan model.

Untuk panduan lengkap tentang serialisasi dan penyimpanan, lihat panduan untuk menyimpan dan membuat serial Model .

Menggunakan jadwal kecepatan pembelajaran

Pola umum saat melatih model pembelajaran yang dalam adalah mengurangi pembelajaran secara bertahap saat pelatihan berlangsung. Ini umumnya dikenal sebagai "peluruhan kecepatan pembelajaran".

Jadwal peluruhan pembelajaran dapat bersifat statis (ditetapkan sebelumnya, sebagai fungsi dari periode saat ini atau indeks batch saat ini), atau dinamis (menanggapi perilaku model saat ini, khususnya kerugian validasi).

Meneruskan jadwal ke pengoptimal

Anda dapat dengan mudah menggunakan jadwal peluruhan kecepatan pembelajaran statis dengan meneruskan objek jadwal sebagai argumen learning_rate di pengoptimal Anda:

initial_learning_rate = 0.1
lr_schedule = keras.optimizers.schedules.ExponentialDecay(
    initial_learning_rate, decay_steps=100000, decay_rate=0.96, staircase=True
)

optimizer = keras.optimizers.RMSprop(learning_rate=lr_schedule)

Beberapa jadwal InverseTimeDecay tersedia: ExponentialDecay , PiecewiseConstantDecay , PolynomialDecay , dan InverseTimeDecay .

Menggunakan callback untuk menerapkan jadwal kecepatan pembelajaran dinamis

Jadwal kecepatan pembelajaran dinamis (misalnya, menurunkan kecepatan pembelajaran saat kehilangan validasi tidak lagi meningkat) tidak dapat dicapai dengan objek jadwal ini karena pengoptimal tidak memiliki akses ke metrik validasi.

Namun, callback memiliki akses ke semua metrik, termasuk metrik validasi! Dengan demikian, Anda dapat mencapai pola ini dengan menggunakan callback yang mengubah kecepatan pembelajaran saat ini di pengoptimal. Nyatanya, ini bahkan sudah ada di ReduceLROnPlateau sebagai callback ReduceLROnPlateau .

Memvisualisasikan kerugian dan metrik selama pelatihan

Cara terbaik untuk mengawasi model Anda selama pelatihan adalah dengan menggunakan TensorBoard , aplikasi berbasis browser yang dapat Anda jalankan secara lokal yang menyediakan:

  • Plot langsung dari kerugian dan metrik untuk pelatihan dan evaluasi
  • (opsional) Visualisasi histogram aktivasi lapisan Anda
  • (opsional) Visualisasi 3D dari ruang embedding yang dipelajari oleh lapisan Embedding Anda

Jika Anda telah menginstal TensorFlow dengan pip, Anda seharusnya dapat meluncurkan TensorBoard dari baris perintah:

tensorboard --logdir=/full_path_to_your_logs

Menggunakan callback TensorBoard

Cara termudah untuk menggunakan TensorBoard dengan model Keras dan metode fit adalah callback TensorBoard .

Dalam kasus yang paling sederhana, cukup tentukan di mana Anda ingin callback menulis log, dan Anda siap melakukannya:

keras.callbacks.TensorBoard(
    log_dir="/full_path_to_your_logs",
    histogram_freq=0,  # How often to log histogram visualizations
    embeddings_freq=0,  # How often to log embedding visualizations
    update_freq="epoch",
)  # How often to write logs (default: once per epoch)
<tensorflow.python.keras.callbacks.TensorBoard at 0x7f74ec5179e8>

Untuk informasi selengkapnya, lihat dokumentasi untuk callback TensorBoard .