Pelatihan dan evaluasi dengan metode bawaan

Tetap teratur dengan koleksi Simpan dan kategorikan konten berdasarkan preferensi Anda.

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

Mempersiapkan

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

pengantar

Ini panduan meliputi pelatihan, evaluasi, dan prediksi (inferensi) model saat menggunakan built-in API untuk pelatihan & validasi (seperti Model.fit() , Model.evaluate() dan Model.predict() ).

Jika Anda tertarik memanfaatkan fit() sementara menetapkan fungsi langkah pelatihan Anda sendiri, lihat Menyesuaikan apa yang terjadi di fit() panduan .

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

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

Panduan ini tidak mencakup pelatihan didistribusikan, yang tercakup dalam kami panduan untuk multi-GPU & pelatihan didistribusikan .

Ikhtisar API: contoh ujung ke ujung pertama

Ketika melewati data ke built-in melatih loop dari model, anda harus menggunakan NumPy array (jika data Anda kecil dan cocok di memori) atau tf.data Dataset objek. Dalam beberapa paragraf berikutnya, kita akan menggunakan dataset MNIST sebagai array NumPy, untuk mendemonstrasikan cara menggunakan pengoptimal, kehilangan, dan metrik.

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

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)

Seperti inilah alur kerja ujung ke ujung yang khas, yang terdiri dari:

  • Pelatihan
  • Validasi pada set ketidaksepakatan yang dihasilkan dari data pelatihan asli
  • Evaluasi pada 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 menyebutnya fit() , yang akan melatih model dengan mengiris data ke "batch" ukuran batch_size , dan berulang kali iterasi seluruh dataset untuk sejumlah tertentu dari epochs .

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 [==============================] - 3s 3ms/step - loss: 0.3387 - sparse_categorical_accuracy: 0.9050 - val_loss: 0.1957 - val_sparse_categorical_accuracy: 0.9426
Epoch 2/2
782/782 [==============================] - 2s 3ms/step - loss: 0.1543 - sparse_categorical_accuracy: 0.9548 - val_loss: 0.1425 - val_sparse_categorical_accuracy: 0.9593

Itu kembali history objek memegang rekor nilai kerugian dan nilai-nilai metrik selama pelatihan:

history.history
{'loss': [0.3386789858341217, 0.1543138176202774],
 'sparse_categorical_accuracy': [0.9050400257110596, 0.9548400044441223],
 'val_loss': [0.19569723308086395, 0.14253544807434082],
 'val_sparse_categorical_accuracy': [0.9426000118255615, 0.9592999815940857]}

Kami mengevaluasi model pada data uji 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 2ms/step - loss: 0.1414 - sparse_categorical_accuracy: 0.9569
test loss, test acc: [0.14140386879444122, 0.9569000005722046]
Generate predictions for 3 samples
predictions shape: (3, 10)

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

The compile() metode: menentukan kerugian, metrik, dan optimizer

Untuk melatih model dengan fit() , Anda perlu menentukan fungsi kerugian, sebuah optimizer, dan opsional, beberapa metrik ke monitor.

Anda lulus ini untuk model sebagai argumen untuk compile() metode:

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

The metrics Argumen harus 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 terhadap total kerugian model. Anda akan menemukan rincian lebih lanjut tentang ini dalam data Melewati untuk multi-input, multi-output bagian model.

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

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

Untuk digunakan kembali nanti, mari kita masukkan definisi model kita 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 Anda sendiri dari awal, karena apa yang Anda butuhkan kemungkinan 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

Jika Anda perlu membuat custom loss, Keras menyediakan dua cara untuk melakukannya.

Metode pertama melibatkan menciptakan 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 [==============================] - 2s 2ms/step - loss: 0.0162
<keras.callbacks.History at 0x7ff8881ba250>

Jika Anda membutuhkan fungsi kerugian yang mengambil parameter samping y_true dan y_pred , Anda dapat subclass tf.keras.losses.Loss kelas dan menerapkan dua metode berikut:

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

Katakanlah Anda ingin menggunakan kesalahan kuadrat rata-rata, tetapi dengan istilah tambahan yang akan mengurangi nilai prediksi jauh dari 0,5 (kami berasumsi bahwa target kategorikal dikodekan satu kali 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 berhasil 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 [==============================] - 2s 2ms/step - loss: 0.0388
<keras.callbacks.History at 0x7ff8882130d0>

Metrik khusus

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

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

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

Berikut adalah contoh sederhana yang menunjukkan bagaimana menerapkan CategoricalTruePositives metrik yang penting berapa banyak sampel yang benar diklasifikasikan 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_state(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 [==============================] - 2s 3ms/step - loss: 0.3404 - categorical_true_positives: 45217.0000
Epoch 2/3
782/782 [==============================] - 2s 3ms/step - loss: 0.1588 - categorical_true_positives: 47606.0000
Epoch 3/3
782/782 [==============================] - 2s 3ms/step - loss: 0.1168 - categorical_true_positives: 48278.0000
<keras.callbacks.History at 0x7ff8880a3610>

Menangani kerugian dan metrik yang tidak sesuai dengan tanda tangan standar

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

Dalam kasus tersebut, Anda dapat menghubungi self.add_loss(loss_value) dari dalam metode panggilan dari lapisan kustom. Kerugian ditambahkan dengan cara ini akan ditambahkan ke hilangnya "utama" selama pelatihan (yang dioper ke compile() ). Berikut adalah contoh sederhana yang menambahkan regularisasi aktivitas (perhatikan bahwa regularisasi aktivitas sudah terpasang di 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 [==============================] - 2s 2ms/step - loss: 2.4545
<keras.callbacks.History at 0x7ff87c53f310>

Anda dapat melakukan hal yang sama untuk penebangan nilai-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 [==============================] - 2s 2ms/step - loss: 0.3461 - std_of_activation: 0.9929
<keras.callbacks.History at 0x7ff87c3d5bd0>

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

Berikut ini contoh sederhana:

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 [==============================] - 2s 3ms/step - loss: 2.4647 - std_of_activation: 0.0017
<keras.callbacks.History at 0x7ff87c216f90>

Perhatikan bahwa ketika Anda melewati kerugian melalui add_loss() , menjadi mungkin untuk panggilan compile() tanpa fungsi kerugian, karena model sudah memiliki kerugian untuk meminimalkan.

Pertimbangkan hal berikut LogisticEndpoint lapisan: dibutuhkan sebagai masukan target & logits, dan melacak kerugian crossentropy melalui add_loss() . Hal ini juga trek akurasi klasifikasi via 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 masukan (input data & target), yang disusun tanpa loss argumen, 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 414ms/step - loss: 0.9889 - binary_accuracy: 0.0000e+00
<keras.callbacks.History at 0x7ff87c0848d0>

Untuk informasi lebih lanjut tentang pelatihan model multi-input, lihat bagian Passing data ke multi-input, model multi-output.

Secara otomatis memisahkan set ketidaksepakatan validasi

Dalam contoh pertama end-to-end Anda melihat, kami menggunakan validation_data argumen untuk lulus tuple dari NumPy array (x_val, y_val) untuk model untuk mengevaluasi kerugian validasi dan metrik validasi pada akhir setiap zaman.

Berikut pilihan lain: argumen validation_split memungkinkan Anda untuk secara otomatis cadangan bagian dari data training untuk validasi. Nilai argumen mewakili sebagian kecil dari data yang akan disediakan untuk validasi, sehingga harus ditetapkan ke nomor yang lebih tinggi dari 0 dan menurunkan dari 1. Misalnya, validation_split=0.2 berarti "menggunakan 20% dari data untuk validasi", dan validation_split=0.6 berarti "menggunakan 60% dari data untuk validasi".

Cara validasi dihitung adalah dengan mengambil yang terakhir x% sampel dari array yang diterima oleh fit() call, sebelum menyeret apapun.

Catatan bahwa Anda hanya dapat menggunakan validation_split saat pelatihan dengan data NumPy.

model = get_compiled_model()
model.fit(x_train, y_train, batch_size=64, validation_split=0.2, epochs=1)
625/625 [==============================] - 2s 3ms/step - loss: 0.3682 - sparse_categorical_accuracy: 0.8957 - val_loss: 0.2276 - val_sparse_categorical_accuracy: 0.9301
<keras.callbacks.History at 0x7ff81c680890>

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 di fit() , ketika data Anda dilewatkan sebagai array NumPy.

Mari sekarang kita lihat kasus di mana data Anda datang dalam bentuk tf.data.Dataset objek.

The tf.data API adalah satu set utilitas di TensorFlow 2.0 untuk loading dan data preprocessing dengan cara yang cepat dan terukur.

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

Anda dapat melewati Dataset contoh 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 3ms/step - loss: 0.3372 - sparse_categorical_accuracy: 0.9047
Epoch 2/3
782/782 [==============================] - 2s 3ms/step - loss: 0.1596 - sparse_categorical_accuracy: 0.9523
Epoch 3/3
782/782 [==============================] - 2s 3ms/step - loss: 0.1171 - sparse_categorical_accuracy: 0.9655
Evaluate
157/157 [==============================] - 0s 2ms/step - loss: 0.1211 - sparse_categorical_accuracy: 0.9648
{'loss': 0.12107347697019577,
 'sparse_categorical_accuracy': 0.9648000001907349}

Perhatikan bahwa Dataset diatur ulang di akhir setiap epoch, sehingga dapat digunakan kembali di epoch berikutnya.

Jika Anda ingin menjalankan pelatihan hanya pada jumlah tertentu batch dari Dataset ini, Anda dapat melewati steps_per_epoch argumen, yang menentukan berapa banyak pelatihan langkah model harus dijalankan dengan menggunakan Dataset ini sebelum pindah ke zaman berikutnya.

Jika Anda melakukan ini, kumpulan data tidak disetel ulang di akhir setiap epoch, melainkan kami terus menggambar kumpulan berikutnya. Dataset pada akhirnya akan kehabisan data (kecuali jika itu adalah dataset yang berulang tanpa batas).

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 [==============================] - 1s 3ms/step - loss: 0.7937 - sparse_categorical_accuracy: 0.7894
Epoch 2/3
100/100 [==============================] - 0s 3ms/step - loss: 0.3699 - sparse_categorical_accuracy: 0.8938
Epoch 3/3
100/100 [==============================] - 0s 3ms/step - loss: 0.3155 - sparse_categorical_accuracy: 0.9061
<keras.callbacks.History at 0x7ff81c587e90>

Menggunakan kumpulan data validasi

Anda dapat melewati Dataset misalnya sebagai validation_data argumen dalam 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 [==============================] - 3s 3ms/step - loss: 0.3380 - sparse_categorical_accuracy: 0.9035 - val_loss: 0.2015 - val_sparse_categorical_accuracy: 0.9405
<keras.callbacks.History at 0x7ff81c30e450>

Di akhir setiap epoch, model akan mengulangi set data validasi dan menghitung kehilangan validasi dan metrik validasi.

Jika Anda ingin menjalankan validasi hanya pada jumlah tertentu batch dari dataset ini, Anda dapat melewati validation_steps argumen, yang menetapkan berapa validasi langkah model harus dijalankan dengan dataset validasi sebelum mengganggu validasi dan pindah ke zaman 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 [==============================] - 3s 3ms/step - loss: 0.3369 - sparse_categorical_accuracy: 0.9036 - val_loss: 0.2953 - val_sparse_categorical_accuracy: 0.9187
<keras.callbacks.History at 0x7ff81c30e310>

Perhatikan bahwa dataset validasi akan diatur ulang setelah setiap penggunaan (sehingga Anda akan selalu mengevaluasi sampel yang sama dari zaman ke zaman).

Argumen validation_split (menghasilkan satu set ketidaksepakatan dari data training) tidak didukung saat pelatihan dari Dataset objek, karena fitur ini membutuhkan kemampuan untuk indeks sampel dari dataset, yang tidak mungkin secara umum dengan Dataset API.

Format input lain yang didukung

Selain NumPy array, tensor bersemangat, dan TensorFlow Datasets , itu mungkin untuk melatih model Keras menggunakan Panda dataframes, atau dari generator Python yang batch hasil data & label.

Secara khusus, keras.utils.Sequence menawarkan kelas antarmuka yang sederhana untuk membangun generator Data Python yang multiprocessing-sadar dan dapat dikocok.

Secara umum, kami menyarankan Anda menggunakan:

  • Input data NumPy 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 dataset yang besar dan Anda perlu melakukan banyak kebiasaan pengolahan Python-sisi yang tidak dapat dilakukan dalam TensorFlow (misalnya jika Anda bergantung pada perpustakaan eksternal untuk loading data atau preprocessing).

Menggunakan keras.utils.Sequence objek sebagai masukan

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

  • Ini bekerja dengan baik dengan multiprocessing.
  • Hal ini dapat mengocok (misalnya ketika melewati shuffle=True di fit() ).

Sebuah Sequence harus menerapkan dua metode:

  • __getitem__
  • __len__

Metode __getitem__ harus kembali batch lengkap. Jika Anda ingin memodifikasi dataset Anda antara zaman, Anda dapat menerapkan on_epoch_end .

Berikut ini 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 kumpulan data. Ada dua metode untuk menimbang 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 milik kelas ini.

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

Misalnya, jika kelas "0" adalah setengah direpresentasikan sebagai kelas "1" di data Anda, Anda bisa 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 3ms/step - loss: 0.3708 - sparse_categorical_accuracy: 0.9032
<keras.callbacks.History at 0x7ff80c7ddd10>

Berat sampel

Untuk kontrol berbutir halus, atau jika Anda tidak membuat pengklasifikasi, Anda dapat menggunakan "bobot sampel".

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

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

Ketika bobot yang digunakan adalah satu dan nol, array dapat digunakan sebagai masker untuk fungsi kerugian (seluruhnya membuang kontribusi sampel tertentu untuk total loss).

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 3ms/step - loss: 0.3806 - sparse_categorical_accuracy: 0.9000
<keras.callbacks.History at 0x7ff80c650350>

Berikut adalah pencocokan Dataset contoh:

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 [==============================] - 3s 3ms/step - loss: 0.3588 - sparse_categorical_accuracy: 0.9070
<keras.callbacks.History at 0x7ff80c51cb50>

Melewati data ke model multi-input, multi-output

Dalam contoh sebelumnya, kita sedang mempertimbangkan model dengan input tunggal (a tensor bentuk (764,) ) dan satu output (a tensor prediksi bentuk (10,) ). Tetapi bagaimana dengan model yang memiliki banyak input atau output?

Pertimbangkan model berikut, yang memiliki input gambar bentuk (32, 32, 3) (yang ini (height, width, channels) ) dan input time series dari bentuk (None, 10) (yang ini (timesteps, features) ). Model kami akan memiliki dua output dihitung dari kombinasi input ini: a "nilai" (bentuk (1,) ) dan distribusi probabilitas atas lima kelas (dari 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 dalam 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 melewatkan fungsi kerugian sebagai daftar:

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

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

Demikian 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 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 eksplisit dan dicts jika Anda memiliki lebih dari 2 output.

Ini mungkin untuk memberikan bobot yang berbeda kerugian output spesifik yang berbeda (misalnya, satu mungkin ingin hak istimewa "skor" loss dalam contoh kita, dengan memberikan 2x pentingnya kerugian kelas), menggunakan loss_weights argumen:

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 tidak 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()},
)

Melewati data ke multi-input atau model multi-output dalam fit() bekerja dengan cara yang sama seperti menentukan fungsi kerugian dalam kompilasi: Anda dapat melewati daftar array NumPy (dengan 1: 1 pemetaan untuk output yang menerima fungsi kerugian ) atau dicts pemetaan nama output 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 [==============================] - 2s 9ms/step - loss: 5.6917 - score_output_loss: 0.1031 - class_output_loss: 5.5886
4/4 [==============================] - 0s 6ms/step - loss: 4.4108 - score_output_loss: 0.0999 - class_output_loss: 4.3109
<keras.callbacks.History at 0x7ff80c3b4110>

Berikut Dataset kasus penggunaan: sama seperti apa yang kita lakukan untuk array NumPy, yang Dataset harus kembali tupel dari 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 21ms/step - loss: 4.2451 - score_output_loss: 0.0993 - class_output_loss: 4.1458
<keras.callbacks.History at 0x7ff80c3ed450>

Menggunakan panggilan balik

Callback di Keras adalah objek yang dipanggil pada titik yang berbeda selama pelatihan (di awal epoch, di akhir batch, di akhir epoch, dll.). Mereka dapat digunakan untuk menerapkan perilaku tertentu, seperti:

  • Melakukan validasi pada titik yang berbeda selama pelatihan (di luar validasi built-in per-Epoch)
  • Memeriksa model secara berkala atau ketika melebihi ambang akurasi tertentu
  • Mengubah tingkat pembelajaran model saat pelatihan tampaknya tidak stabil
  • Melakukan fine-tuning dari lapisan atas saat pelatihan tampaknya menjadi stabil
  • Mengirim email atau pemberitahuan pesan instan saat pelatihan berakhir atau ketika ambang batas kinerja tertentu terlampaui
  • Dll.

Callback dapat lulus sebagai daftar panggilan Anda untuk 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 [==============================] - 2s 3ms/step - loss: 0.3725 - sparse_categorical_accuracy: 0.8939 - val_loss: 0.2314 - val_sparse_categorical_accuracy: 0.9321
Epoch 2/20
625/625 [==============================] - 2s 3ms/step - loss: 0.1805 - sparse_categorical_accuracy: 0.9471 - val_loss: 0.2012 - val_sparse_categorical_accuracy: 0.9379
Epoch 3/20
625/625 [==============================] - 2s 3ms/step - loss: 0.1346 - sparse_categorical_accuracy: 0.9603 - val_loss: 0.1651 - val_sparse_categorical_accuracy: 0.9505
Epoch 4/20
625/625 [==============================] - 2s 3ms/step - loss: 0.1065 - sparse_categorical_accuracy: 0.9684 - val_loss: 0.1510 - val_sparse_categorical_accuracy: 0.9571
Epoch 5/20
625/625 [==============================] - 2s 3ms/step - loss: 0.0884 - sparse_categorical_accuracy: 0.9734 - val_loss: 0.1505 - val_sparse_categorical_accuracy: 0.9538
Epoch 6/20
625/625 [==============================] - 2s 3ms/step - loss: 0.0746 - sparse_categorical_accuracy: 0.9778 - val_loss: 0.1508 - val_sparse_categorical_accuracy: 0.9575
Epoch 00006: early stopping
<keras.callbacks.History at 0x7ff80c64cad0>

Banyak panggilan balik bawaan tersedia

Ada banyak callback bawaan yang sudah tersedia di Keras, seperti:

  • ModelCheckpoint : Secara berkala menyimpan model.
  • EarlyStopping : pelatihan Berhenti saat pelatihan tidak lagi meningkatkan metrik validasi.
  • TensorBoard : Model berkala menulis log yang dapat divisualisasikan dalam TensorBoard (lebih detail di bagian "Visualisasi").
  • CSVLogger : stream kerugian dan metrik data ke file CSV.
  • dll.

Lihat dokumentasi callback untuk daftar lengkap.

Menulis panggilan balik Anda sendiri

Anda dapat membuat panggilan balik kustom dengan memperluas kelas dasar keras.callbacks.Callback . Sebuah callback memiliki akses ke model yang terkait melalui properti kelas self.model .

Pastikan untuk membaca panduan lengkap untuk menulis callback kustom .

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 pemeriksaan

Saat Anda melatih model pada kumpulan data yang relatif besar, sangat penting untuk menyimpan pos pemeriksaan model Anda pada interval yang sering.

Cara termudah untuk mencapai ini adalah dengan ModelCheckpoint callback:

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
613/625 [============================>.] - ETA: 0s - loss: 0.3693 - sparse_categorical_accuracy: 0.8972
Epoch 00001: val_loss improved from inf to 0.23508, saving model to mymodel_1
2021-11-12 20:11:50.182298: W tensorflow/python/util/util.cc:368] Sets are not currently considered sequences, but this may change in the future, so consider avoiding using them.
INFO:tensorflow:Assets written to: mymodel_1/assets
625/625 [==============================] - 3s 4ms/step - loss: 0.3660 - sparse_categorical_accuracy: 0.8979 - val_loss: 0.2351 - val_sparse_categorical_accuracy: 0.9273
Epoch 2/2
620/625 [============================>.] - ETA: 0s - loss: 0.1659 - sparse_categorical_accuracy: 0.9507
Epoch 00002: val_loss improved from 0.23508 to 0.16898, saving model to mymodel_2
INFO:tensorflow:Assets written to: mymodel_2/assets
625/625 [==============================] - 2s 3ms/step - loss: 0.1657 - sparse_categorical_accuracy: 0.9507 - val_loss: 0.1690 - val_sparse_categorical_accuracy: 0.9482
<keras.callbacks.History at 0x7ff8b577cc90>

The ModelCheckpoint callback dapat digunakan untuk menerapkan toleransi kesalahan: kemampuan untuk pelatihan restart dari negara terakhir disimpan dari model dalam pelatihan kasus akan secara acak terganggu. Berikut ini 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
  88/1563 [>.............................] - ETA: 3s - loss: 1.1203 - sparse_categorical_accuracy: 0.6911INFO:tensorflow:Assets written to: ./ckpt/ckpt-loss=1.04/assets
 185/1563 [==>...........................] - ETA: 6s - loss: 0.7768 - sparse_categorical_accuracy: 0.7858INFO:tensorflow:Assets written to: ./ckpt/ckpt-loss=0.75/assets
 286/1563 [====>.........................] - ETA: 6s - loss: 0.6382 - sparse_categorical_accuracy: 0.8211INFO:tensorflow:Assets written to: ./ckpt/ckpt-loss=0.63/assets
 383/1563 [======>.......................] - ETA: 6s - loss: 0.5584 - sparse_categorical_accuracy: 0.8433INFO:tensorflow:Assets written to: ./ckpt/ckpt-loss=0.55/assets
 484/1563 [========>.....................] - ETA: 6s - loss: 0.5032 - sparse_categorical_accuracy: 0.8578INFO:tensorflow:Assets written to: ./ckpt/ckpt-loss=0.50/assets
 586/1563 [==========>...................] - ETA: 5s - loss: 0.4644 - sparse_categorical_accuracy: 0.8684INFO:tensorflow:Assets written to: ./ckpt/ckpt-loss=0.46/assets
 685/1563 [============>.................] - ETA: 5s - loss: 0.4356 - sparse_categorical_accuracy: 0.8762INFO:tensorflow:Assets written to: ./ckpt/ckpt-loss=0.43/assets
 783/1563 [==============>...............] - ETA: 5s - loss: 0.4127 - sparse_categorical_accuracy: 0.8825INFO:tensorflow:Assets written to: ./ckpt/ckpt-loss=0.41/assets
 883/1563 [===============>..............] - ETA: 4s - loss: 0.3958 - sparse_categorical_accuracy: 0.8868INFO:tensorflow:Assets written to: ./ckpt/ckpt-loss=0.39/assets
 985/1563 [=================>............] - ETA: 3s - loss: 0.3766 - sparse_categorical_accuracy: 0.8918INFO:tensorflow:Assets written to: ./ckpt/ckpt-loss=0.38/assets
1086/1563 [===================>..........] - ETA: 3s - loss: 0.3624 - sparse_categorical_accuracy: 0.8958INFO:tensorflow:Assets written to: ./ckpt/ckpt-loss=0.36/assets
1184/1563 [=====================>........] - ETA: 2s - loss: 0.3498 - sparse_categorical_accuracy: 0.8994INFO:tensorflow:Assets written to: ./ckpt/ckpt-loss=0.35/assets
1283/1563 [=======================>......] - ETA: 1s - loss: 0.3383 - sparse_categorical_accuracy: 0.9029INFO:tensorflow:Assets written to: ./ckpt/ckpt-loss=0.34/assets
1386/1563 [=========================>....] - ETA: 1s - loss: 0.3265 - sparse_categorical_accuracy: 0.9058INFO:tensorflow:Assets written to: ./ckpt/ckpt-loss=0.33/assets
1485/1563 [===========================>..] - ETA: 0s - loss: 0.3184 - sparse_categorical_accuracy: 0.9081INFO:tensorflow:Assets written to: ./ckpt/ckpt-loss=0.32/assets
1563/1563 [==============================] - 11s 7ms/step - loss: 0.3122 - sparse_categorical_accuracy: 0.9097
<keras.callbacks.History at 0x7ff8b53e1dd0>

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

Untuk panduan lengkap tentang serialisasi dan penghematan, lihat panduan untuk menyelamatkan dan serialisasi Model .

Menggunakan jadwal tingkat pembelajaran

Pola umum saat melatih model deep learning adalah mengurangi pembelajaran secara bertahap seiring dengan kemajuan pelatihan. Ini umumnya dikenal sebagai "peluruhan kecepatan belajar".

Jadwal peluruhan pembelajaran bisa statis (diperbaiki sebelumnya, sebagai fungsi dari zaman saat ini atau indeks batch saat ini), atau dinamis (menanggapi perilaku model saat ini, khususnya kehilangan validasi).

Melewati jadwal ke pengoptimal

Anda dapat dengan mudah menggunakan pembelajaran statis jadwal pembusukan tingkat dengan melewati sebuah objek jadwal sebagai learning_rate argumen dalam optimizer 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 built-in jadwal yang tersedia: ExponentialDecay , PiecewiseConstantDecay , PolynomialDecay , dan InverseTimeDecay .

Menggunakan panggilan balik untuk menerapkan jadwal kecepatan pembelajaran yang dinamis

Jadwal kecepatan pembelajaran dinamis (misalnya, penurunan kecepatan pembelajaran saat kehilangan validasi tidak lagi membaik) 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 panggilan balik yang mengubah kecepatan pembelajaran saat ini pada pengoptimal. Bahkan, ini bahkan built-in sebagai ReduceLROnPlateau callback.

Memvisualisasikan kerugian dan metrik selama pelatihan

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

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

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

tensorboard --logdir=/full_path_to_your_logs

Menggunakan panggilan balik TensorBoard

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

Dalam kasus 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)
<keras.callbacks.TensorBoard at 0x7ff88c8c04d0>

Untuk informasi lebih lanjut, lihat dokumentasi untuk TensorBoard callback .