![]() | ![]() | ![]() | ![]() |
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
difit()
).
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 untukModel.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)
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 .