このページは Cloud Translation API によって翻訳されました。
Switch to English

組み込みメソッドを使用したトレーニングと評価

TensorFlow.orgで見る Google Colabで実行 GitHubでソースを表示するノートブックをダウンロード

セットアップ

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

前書き

このガイドでは、トレーニングと検証に組み込みAPI( model.fit()model.evaluate()model.predict() )を使用する場合のトレーニング、評価、および予測(推論)モデルについて説明します。

独自のトレーニングステップ関数を指定するときにfit()を活用することに関心がある場合は、 fit()で行われる処理のカスタマイズ」のガイドをご覧ください。

独自のトレーニングおよび評価ループを最初から作成することに関心がある場合は、 「トレーニングループを最初から作成する」ガイドを参照してください。

一般に、組み込みループを使用している場合でも、独自のループを作成している場合でも、モデルのトレーニングと評価は、すべての種類のKerasモデル(シーケンシャルモデル、Functional APIで構築されたモデル、最初から作成されたモデル)でほぼ同じように機能します。モデルのサブクラス化。

このガイドでは、分散トレーニングについては説明していません。分散トレーニングについては、マルチGPUと分散トレーニングのガイドをご覧ください。

APIの概要:最初のエンドツーエンドの例

モデルの組み込みトレーニングループにデータを渡すときは、 NumPy配列(データが小さく、メモリに収まる場合)またはtf.data Datasetオブジェクトを使用する必要があります。次のいくつかの段落では、オプティマイザー、損失、およびメトリックの使用方法を示すために、MNISTデータセットをNumPy配列として使用します。

次のモデルについて考えてみましょう(ここでは、Functional APIを組み込んでいますが、シーケンシャルモデルまたはサブクラス化されたモデルの場合もあります)。

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)

典型的なエンドツーエンドのワークフローは次のようになります。

  • トレーニング
  • 元のトレーニングデータから生成されたホールドアウトセットの検証
  • 試験データの評価

この例ではMNISTデータを使用します。

(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]
Downloading data from https://storage.googleapis.com/tensorflow/tf-keras-datasets/mnist.npz
11493376/11490434 [==============================] - 0s 0us/step

トレーニング構成(オプティマイザー、損失、メトリック)を指定します。

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

データを「batch_size」サイズの「バッチ」にスライスし、指定された数の「エポック」についてデータセット全体を繰り返し反復することにより、モデルをトレーニングするfit()を呼び出します。

print("Fit model on training data")
history = model.fit(
    x_train,
    y_train,
    batch_size=64,
    epochs=2,
    # We pass some validation for
    # monitoring validation loss and metrics
    # at the end of each epoch
    validation_data=(x_val, y_val),
)
Fit model on training data
Epoch 1/2
782/782 [==============================] - 2s 2ms/step - loss: 0.3380 - sparse_categorical_accuracy: 0.9044 - val_loss: 0.1873 - val_sparse_categorical_accuracy: 0.9452
Epoch 2/2
782/782 [==============================] - 2s 2ms/step - loss: 0.1606 - sparse_categorical_accuracy: 0.9525 - val_loss: 0.1767 - val_sparse_categorical_accuracy: 0.9471

返された「履歴」オブジェクトは、トレーニング中の損失値とメトリック値の記録を保持します。

history.history
{'loss': [0.3379512131214142, 0.16062788665294647],
 'sparse_categorical_accuracy': [0.9043999910354614, 0.9524800181388855],
 'val_loss': [0.18728218972682953, 0.17670848965644836],
 'val_sparse_categorical_accuracy': [0.9452000260353088, 0.9470999836921692]}

evaluate()介してテストデータでモデルを評価します。

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

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

では、このワークフローの各部分を詳しく見ていきましょう。

compile()メソッド:損失、メトリック、およびオプティマイザーの指定

fit()を使用してモデルをトレーニングするには、損失関数、オプティマイザー、およびオプションで監視するいくつかのメトリックを指定する必要があります。

これらをcompile()メソッドの引数としてモデルに渡します。

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

metrics引数はリストである必要があります。モデルには任意の数のメトリックを含めることができます。

モデルに複数の出力がある場合、出力ごとに異なる損失とメトリックを指定でき、モデルの総損失に対する各出力の寄与を変調できます。これについての詳細は、 「多入力、多出力モデルへのデータの受け渡し」のセクションにあります。

デフォルト設定に満足している場合、多くの場合、オプティマイザ、損失、およびメトリックは、ショートカットとして文字列識別子を介して指定できます。

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

後で再利用するために、モデル定義とコンパイルステップを関数に入れましょう。このガイドでは、さまざまな例で数回呼び出します。

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

多くの組み込みオプティマイザー、損失、およびメトリックが利用可能です

一般に、必要なものがすでにKeras APIの一部である可能性が高いため、独自の損失、メトリック、またはオプティマイザをゼロから作成する必要はありません。

オプティマイザ:

  • SGD() (勢いの有無にかかわらず)
  • RMSprop()
  • Adam()

損失:

  • MeanSquaredError()
  • KLDivergence()
  • CosineSimilarity()

指標:

  • AUC()
  • Precision()
  • Recall()

カスタム損失

Kerasでカスタム損失を提供する方法は2つあります。最初の例では、入力y_trueおよびy_predを受け入れる関数を作成します。次の例は、実際のデータと予測の間の平均二乗誤差を計算する損失関数を示しています。

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


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

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

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

y_trueおよびy_pred横にあるパラメーターをy_true損失関数が必要な場合は、 tf.keras.losses.Lossクラスをサブクラス化して、次の2つのメソッドを実装できます。

  • __init__(self) :損失関数の呼び出し中に渡すパラメーターを受け入れる
  • call(self, y_true, y_pred) :ターゲット(y_true)とモデル予測(y_pred)を使用してモデルの損失を計算します

平均二乗誤差を使用したいとしますが、予測値を0.5から遠くインセンティブ解除する追加の用語を使用するとします(カテゴリターゲットはワンホットエンコードされ、0と1の間の値を取ると仮定します)。これにより、モデルが自信を持ちすぎないようにするインセンティブが生まれ、過剰適合を減らすのに役立つ場合があります(試してみるまで、機能するかどうかはわかりません)。

これがあなたがそれをする方法です:

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

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


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

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

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

カスタムメトリック

APIの一部ではないメトリックが必要な場合は、 tf.keras.metrics.Metricクラスをサブクラス化することにより、カスタムメトリックを簡単に作成できます。 4つのメソッドを実装する必要があります。

  • __init__(self) 。ここで、メトリックの状態変数を作成します。
  • update_state(self, y_true, y_pred, sample_weight=None) 、ターゲットy_trueとモデル予測y_predを使用して状態変数を更新します。
  • result(self)は、状態変数を使用して最終結果を計算します。
  • reset_states(self) 。これは、メトリックの状態を再初期化します。

場合によっては、結果の計算に非常に負荷がかかり、定期的にしか実行されないため、状態の更新と結果の計算は別々に保持されます(それぞれupdate_state()およびresult()で)。

これは、特定のクラスに属するものとして正しく分類されたサンプルの数をカウントするCategoricalTruePositivesメトリックを実装する方法を示す簡単な例です。

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

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

    def result(self):
        return self.true_positives

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


model = get_uncompiled_model()
model.compile(
    optimizer=keras.optimizers.RMSprop(learning_rate=1e-3),
    loss=keras.losses.SparseCategoricalCrossentropy(),
    metrics=[CategoricalTruePositives()],
)
model.fit(x_train, y_train, batch_size=64, epochs=3)
Epoch 1/3
782/782 [==============================] - 2s 2ms/step - loss: 0.3298 - categorical_true_positives: 45260.0000
Epoch 2/3
782/782 [==============================] - 2s 2ms/step - loss: 0.1524 - categorical_true_positives: 47734.0000
Epoch 3/3
782/782 [==============================] - 2s 2ms/step - loss: 0.1094 - categorical_true_positives: 48327.0000

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

標準の署名に適合しない損失と測定基準の処理

損失とメトリックの圧倒的多数は、 y_truey_predから計算できます。ここで、 y_predはモデルの出力です。しかし、すべてではありません。たとえば、正則化の損失は、レイヤーのアクティブ化のみを必要とする場合があり(この場合、ターゲットはありません)、このアクティブ化はモデル出力ではない場合があります。

このような場合、カスタムレイヤーの呼び出しメソッド内からself.add_loss(loss_value)呼び出すことができます。この方法で追加された損失は、トレーニング中に "main"損失( compile()渡されたものcompile()追加されます。アクティビティの正則化を追加する簡単な例を次に示します(アクティビティの正則化はすべてのKerasレイヤーに組み込まれていることに注意してください。このレイヤーは具体的な例を提供するためだけのものです)。

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


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

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

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

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

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

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

add_metric()を使用して、メトリック値のロギングに対して同じことを行うことができます。

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


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

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

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

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

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

Functional APIでは、 model.add_loss(loss_tensor)またはmodel.add_metric(metric_tensor, name, aggregation)呼び出すこともできます。

以下に簡単な例を示します。

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 2ms/step - loss: 2.4945 - std_of_activation: 0.0019

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

add_loss()を介してadd_loss()を渡す場合、モデルにはすでに最小化するロスがあるため、ロス関数なしでcompile()を呼び出すことが可能になることに注意してください。

次のLogisticEndpointレイヤーについて考えてみましょう。これは、ターゲットとロジットを入力として受け取り、 add_loss()によってadd_loss()エントロピー損失をadd_loss()ます。また、 add_metric()を介して分類の精度を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)

次のように、 loss引数なしでコンパイルされた2つの入力(入力データとターゲット)を持つモデルで使用できます。

import numpy as np

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

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

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

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

多入力モデルのトレーニングの詳細については、「多入力多出力モデルへのデータの受け渡し」を参照してください。

検証ホールドアウトセットを自動的に分離する

最初に見たエンドツーエンドの例では、 validation_data引数を使用して、NumPy配列(x_val, y_val)タプルをモデルに(x_val, y_val)各エポックの終わりに検証損失と検証メトリックを評価しました。

次に、別のオプションを示します。引数validation_split使用すると、検証用にトレーニングデータの一部を自動的に予約できます。引数値は、検証用に予約されるデータの割合を表すため、0より大きく1より小さい数値に設定する必要があります。たとえば、 validation_split=0.2は、「検証にデータの20%を使用する」ことを意味します。 validation_split=0.6は、「検証にデータの60%を使用する」ことを意味します。

検証が計算される方法は、シャッフルする前に、fit呼び出しによって受信された配列の最後のx%サンプルを取得することです。

NumPyデータでトレーニングする場合にのみvalidation_split使用できることに注意してください。

model = get_compiled_model()
model.fit(x_train, y_train, batch_size=64, validation_split=0.2, epochs=1)
625/625 [==============================] - 1s 2ms/step - loss: 0.3734 - sparse_categorical_accuracy: 0.8960 - val_loss: 0.2465 - val_sparse_categorical_accuracy: 0.9237

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

tf.dataデータセットからのトレーニングと評価

過去数段落で、データがNumPy配列として渡されたときに、損失、メトリック、およびオプティマイザを処理する方法をvalidation_dataし、 validation_dataおよびvalidation_split引数を適切に使用する方法をvalidation_dataしました。

次に、データがtf.data.Datasetオブジェクトの形式で送信される場合を見てみましょう。

tf.data APIは、高速でスケーラブルな方法でデータを読み込んで前処理するためのTensorFlow 2.0のユーティリティセットです。

Datasets作成に関する完全なガイドについては、 tf.dataのドキュメントを参照してください。

Datasetインスタンスをメソッドfit()evaluate() 、およびpredict()直接渡すことができます。

model = get_compiled_model()

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

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

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

# You can also evaluate or predict on a dataset.
print("Evaluate")
result = model.evaluate(test_dataset)
dict(zip(model.metrics_names, result))
Epoch 1/3
782/782 [==============================] - 2s 2ms/step - loss: 0.3404 - sparse_categorical_accuracy: 0.9047
Epoch 2/3
782/782 [==============================] - 2s 2ms/step - loss: 0.1614 - sparse_categorical_accuracy: 0.9518
Epoch 3/3
782/782 [==============================] - 2s 2ms/step - loss: 0.1171 - sparse_categorical_accuracy: 0.9653
Evaluate
157/157 [==============================] - 0s 2ms/step - loss: 0.1309 - sparse_categorical_accuracy: 0.9608

{'loss': 0.13087117671966553,
 'sparse_categorical_accuracy': 0.9607999920845032}

データセットは各エポックの終わりにリセットされるため、次のエポックで再利用できることに注意してください。

このデータセットから特定の数のバッチでのみトレーニングを実行する場合は、 steps_per_epoch引数を渡すことができます。これは、次のエポックに進む前に、このデータセットを使用してモデルが実行するトレーニングステップの数を指定します。

これを行うと、データセットは各エポックの終了時にリセットされず、代わりに次のバッチを描画し続けます。データセットは、最終的にデータが不足します(無限ループデータセットでない限り)。

model = get_compiled_model()

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

# Only use the 100 batches per epoch (that's 64 * 100 samples)
model.fit(train_dataset, epochs=3, steps_per_epoch=100)
Epoch 1/3
100/100 [==============================] - 0s 2ms/step - loss: 0.8017 - sparse_categorical_accuracy: 0.7894
Epoch 2/3
100/100 [==============================] - 0s 2ms/step - loss: 0.3743 - sparse_categorical_accuracy: 0.8925
Epoch 3/3
100/100 [==============================] - 0s 2ms/step - loss: 0.3227 - sparse_categorical_accuracy: 0.9027

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

検証データセットの使用

fit() validation_data引数としてDatasetインスタンスを渡すことができます。

model = get_compiled_model()

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

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

model.fit(train_dataset, epochs=1, validation_data=val_dataset)
782/782 [==============================] - 2s 3ms/step - loss: 0.3416 - sparse_categorical_accuracy: 0.9018 - val_loss: 0.2260 - val_sparse_categorical_accuracy: 0.9339

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

各エポックの終わりに、モデルは検証データセットを反復処理し、検証損失と検証メトリックを計算します。

このデータセットから特定の数のバッチでのみ検証を実行する場合は、 validation_steps引数を渡すことができます。これは、検証を中断して次のエポックに進む前に、モデルが検証データセットで実行する必要がある検証ステップの数を指定します。

model = get_compiled_model()

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

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

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

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

使用ごとに検証データセットがリセットされることに注意してください(常に同じサンプルをエポックからエポックに評価するため)。

引数validation_split (トレーニングデータからホールドアウトセットを生成する)は、 Datasetオブジェクトからトレーニングする場合はサポートされていません。この機能には、データセットのサンプルにインデックスをDataset機能が必要です。これは、 Dataset APIでは一般的に不可能です。

サポートされる他の入力フォーマット

NumPy配列、熱心なテンソル、TensorFlow Datasetsに加えて、Pandasデータフレームを使用して、またはデータとラベルのバッチを生成するPythonジェネレーターからKerasモデルをトレーニングできます。

特に、 keras.utils.Sequenceクラスは、マルチプロセッシング対応であり、シャッフルできるPythonデータジェネレーターを構築するためのシンプルなインターフェースを提供します。

一般的に、以下を使用することをお勧めします。

  • データが小さく、メモリに収まる場合は、NumPy入力データ
  • 大規模なデータセットがあり、分散トレーニングを行う必要がある場合は、 Datasetオブジェクト
  • 大規模なデータセットがあり、TensorFlowでは実行できない多くのカスタムPython側処理を実行する必要がある場合(データの読み込みや前処理を外部ライブラリに依存している場合など)、オブジェクトをSequenceます。

keras.utils.Sequenceオブジェクトを入力として使用する

keras.utils.Sequenceは、2つの重要なプロパティを持つPythonジェネレーターを取得するためにサブクラス化できるユーティリティです。

  • マルチプロセッシングでうまく機能します。
  • シャッフルすることができます(たとえば、 fit()shuffle=Trueを渡す場合)。

Sequenceは2つのメソッドを実装する必要があります。

  • __getitem__
  • __len__

__getitem__メソッドは完全なバッチを返す必要があります。エポック間でデータセットを変更する場合は、 on_epoch_end実装on_epoch_endます。

簡単な例を次に示します。

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)

サンプルの重み付けとクラスの重み付けの使用

デフォルト設定では、サンプルの重みはデータセット内の頻度によって決定されます。サンプルの頻度に関係なく、データに重みを付けるには2つの方法があります。

  • クラスの重み
  • サンプルの重み

クラスの重み

これは、辞書をModel.fit() class_weight引数に渡すことで設定されます。このディクショナリは、クラスインデックスを、このクラスに属するサンプルに使用する必要がある重みにマップします。

これを使用して、リサンプリングせずにクラスのバランスを調整したり、特定のクラスをより重視するモデルをトレーニングしたりできます。

たとえば、データでクラス「0」がクラス「1」として表される半分である場合、 Model.fit(..., class_weight={0: 1., 1: 0.5})使用できます。

これは、クラスの重みまたはサンプルの重みを使用して、クラス#5(MNISTデータセットの数字「5」)の正しい分類をより重要視するNumPyの例です。

import numpy as np

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

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

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

サンプルの重み

きめの細かい制御の場合、または分類子を作成していない場合は、「サンプルの重み」を使用できます。

  • NumPyデータからトレーニングする場合: sample_weight引数をModel.fit() sample_weightます。
  • tf.dataまたはその他の種類のイテレーターからトレーニングする場合:Yield (input_batch, label_batch, sample_weight_batch)タプル。

「サンプルの重み」配列は、バッチ内の各サンプルが総損失を計算するときにどれだけの重みを持つべきかを指定する数値の配列です。これは通常、不均衡な分類の問題で使用されます(めったに見られないクラスに、より大きな重みを与えるという考えです)。

使用される重みが1と0の場合、配列は損失関数のマスクとして使用できます(総損失に対する特定のサンプルの寄与を完全に破棄します)。

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

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

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

以下は、一致するDataset例です。

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

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

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

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

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

多入力多出力モデルへのデータの受け渡し

前の例では、単一の入力(形状のテンソル(764,) )と単一の出力(形状の予測テンソル(10,) )を持つモデルを検討していました。しかし、複数の入力または出力を持つモデルはどうでしょうか?

形状(32, 32, 3) 32、32、3 (32, 32, 3) (それは(height, width, channels) )の画像入力と形状(None, 10) (それは(timesteps, features) )の時系列入力を持つ次のモデルを考えます。私たちのモデルには、これらの入力の組み合わせから計算された2つの出力があります:(スコア(shape (1,) )と5つのクラスの確率分布(shape (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]
)

このモデルをプロットしてみましょう。ここで何をしているのかがはっきりとわかります(プロットに表示される形状は、サンプルごとの形状ではなく、バッチ形状であることに注意してください)。

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

png

コンパイル時に、損失関数をリストとして渡すことにより、異なる出力に異なる損失を指定できます。

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

モデルに単一の損失関数のみを渡した場合、同じ損失関数がすべての出力に適用されます(ここでは適切ではありません)。

メトリックについても同様です。

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

出力レイヤーに名前を付けたので、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()],
    },
)

3つ以上の出力がある場合は、明示的な名前とdictを使用することをお勧めします。

loss_weights引数を使用して、さまざまな出力固有の損失に異なる重みを与えることができます(たとえば、クラスの損失の2倍の重要性を与えることにより、この例では「スコア」の損失に特権を与えることがloss_weightsます)。

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

これらの出力が予測ではなくトレーニングではない場合、特定の出力の損失を計算しないことを選択することもできます。

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

フィットで多入力または多出力モデルにデータを渡すことは、コンパイルで損失関数を指定するのと同じように機能します。NumPy配列のリストを渡すことができます(損失関数を受け取った出力に1:1のマッピングで)または出力名をNumPy配列にマッピングする辞書

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

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

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

# Alternatively, fit on dicts
model.fit(
    {"img_input": img_data, "ts_input": ts_data},
    {"score_output": score_targets, "class_output": class_targets},
    batch_size=32,
    epochs=1,
)
4/4 [==============================] - 0s 7ms/step - loss: 25.4748 - score_output_loss: 0.3410 - class_output_loss: 25.1338
4/4 [==============================] - 0s 4ms/step - loss: 20.0559 - score_output_loss: 0.2357 - class_output_loss: 19.8202

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

これがDataset使用例です。NumPy配列に対して行ったのと同様に、 Datasetはdictのタプルを返す必要があります。

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 9ms/step - loss: 18.7921 - score_output_loss: 0.2095 - class_output_loss: 18.5825

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

コールバックの使用

Kerasのコールバックは、トレーニング中の異なる時点(エポックの開始時、バッチの終了時、エポックの終了時など)に呼び出されるオブジェクトであり、次のような動作を実装するために使用できます。

  • トレーニング中のさまざまな時点で検証を行う(組み込みのエポックごとの検証以外)
  • 定期的に、または特定の精度のしきい値を超えたときにモデルにチェックポイントを設定する
  • トレーニングが頭打ちになっているように思われる場合のモデルの学習率の変更
  • トレーニングが頭打ちになっているように見えるときに、トップレイヤーを微調整する
  • トレーニングが終了したとき、または特定のパフォーマンスしきい値を超えたときにメールまたはインスタントメッセージ通知を送信する
  • 等。

コールバックは、リストとして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.3737 - sparse_categorical_accuracy: 0.8942 - val_loss: 0.2353 - val_sparse_categorical_accuracy: 0.9309
Epoch 2/20
625/625 [==============================] - 2s 2ms/step - loss: 0.1768 - sparse_categorical_accuracy: 0.9474 - val_loss: 0.1777 - val_sparse_categorical_accuracy: 0.9458
Epoch 3/20
625/625 [==============================] - 2s 2ms/step - loss: 0.1306 - sparse_categorical_accuracy: 0.9615 - val_loss: 0.1543 - val_sparse_categorical_accuracy: 0.9535
Epoch 4/20
625/625 [==============================] - 2s 2ms/step - loss: 0.1021 - sparse_categorical_accuracy: 0.9693 - val_loss: 0.1404 - val_sparse_categorical_accuracy: 0.9578
Epoch 5/20
625/625 [==============================] - 2s 2ms/step - loss: 0.0837 - sparse_categorical_accuracy: 0.9742 - val_loss: 0.1510 - val_sparse_categorical_accuracy: 0.9546
Epoch 6/20
625/625 [==============================] - 1s 2ms/step - loss: 0.0711 - sparse_categorical_accuracy: 0.9783 - val_loss: 0.1367 - val_sparse_categorical_accuracy: 0.9622
Epoch 00006: early stopping

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

多くの組み込みコールバックが利用可能です

  • ModelCheckpoint :モデルを定期的に保存します。
  • EarlyStopping :トレーニングによって検証メトリックが改善されなくなっEarlyStopping 、トレーニングを停止します。
  • TensorBoardTensorBoardで視覚化できるモデルログを定期的に書き込みます(詳細は「視覚化」セクションを参照)。
  • CSVLogger :損失とメトリックのデータをCSVファイルにストリーミングします。

完全なリストについては、コールバックのドキュメントを参照してください。

独自のコールバックを書く

基本クラスkeras.callbacks.Callback拡張することにより、カスタムコールバックを作成できます。コールバックは、クラスプロパティself.model介して関連するモデルにアクセスできます。

カスタムコールバックを作成するための完全なガイドを必ずお読みください。

トレーニング中にバッチごとの損失値のリストを保存する簡単な例を次に示します。

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

チェックポイントモデル

比較的大きなデータセットでモデルをトレーニングする場合、モデルのチェックポイントを頻繁に保存することが重要です。

これを実現する最も簡単な方法は、 ModelCheckpointコールバックを使用することです。

model = get_compiled_model()

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

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

ModelCheckpointコールバックを使用して、フォールトトレランスを実装できます。トレーニングがランダムに中断された場合に、モデルの最後に保存された状態からトレーニングを再開する機能です。基本的な例は次のとおりです。

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
  80/1563 [>.............................] - ETA: 2s - loss: 1.0591 - sparse_categorical_accuracy: 0.7113INFO:tensorflow:Assets written to: ./ckpt/ckpt-loss=0.96/assets
 177/1563 [==>...........................] - ETA: 6s - loss: 0.7432 - sparse_categorical_accuracy: 0.7925INFO:tensorflow:Assets written to: ./ckpt/ckpt-loss=0.70/assets
 281/1563 [====>.........................] - ETA: 6s - loss: 0.6034 - sparse_categorical_accuracy: 0.8307INFO:tensorflow:Assets written to: ./ckpt/ckpt-loss=0.59/assets
 379/1563 [======>.......................] - ETA: 5s - loss: 0.5403 - sparse_categorical_accuracy: 0.8472INFO:tensorflow:Assets written to: ./ckpt/ckpt-loss=0.53/assets
 477/1563 [========>.....................] - ETA: 5s - loss: 0.4893 - sparse_categorical_accuracy: 0.8608INFO:tensorflow:Assets written to: ./ckpt/ckpt-loss=0.48/assets
 581/1563 [==========>...................] - ETA: 4s - loss: 0.4535 - sparse_categorical_accuracy: 0.8704INFO:tensorflow:Assets written to: ./ckpt/ckpt-loss=0.45/assets
 680/1563 [============>.................] - ETA: 4s - loss: 0.4276 - sparse_categorical_accuracy: 0.8775INFO:tensorflow:Assets written to: ./ckpt/ckpt-loss=0.42/assets
 781/1563 [=============>................] - ETA: 4s - loss: 0.4049 - sparse_categorical_accuracy: 0.8836INFO:tensorflow:Assets written to: ./ckpt/ckpt-loss=0.40/assets
 877/1563 [===============>..............] - ETA: 3s - loss: 0.3852 - sparse_categorical_accuracy: 0.8894INFO:tensorflow:Assets written to: ./ckpt/ckpt-loss=0.38/assets
 979/1563 [=================>............] - ETA: 3s - loss: 0.3690 - sparse_categorical_accuracy: 0.8935INFO:tensorflow:Assets written to: ./ckpt/ckpt-loss=0.37/assets
1077/1563 [===================>..........] - ETA: 2s - loss: 0.3527 - sparse_categorical_accuracy: 0.8977INFO:tensorflow:Assets written to: ./ckpt/ckpt-loss=0.35/assets
1181/1563 [=====================>........] - ETA: 1s - loss: 0.3391 - sparse_categorical_accuracy: 0.9016INFO:tensorflow:Assets written to: ./ckpt/ckpt-loss=0.34/assets
1281/1563 [=======================>......] - ETA: 1s - loss: 0.3273 - sparse_categorical_accuracy: 0.9052INFO:tensorflow:Assets written to: ./ckpt/ckpt-loss=0.32/assets
1378/1563 [=========================>....] - ETA: 0s - loss: 0.3169 - sparse_categorical_accuracy: 0.9078INFO:tensorflow:Assets written to: ./ckpt/ckpt-loss=0.32/assets
1477/1563 [===========================>..] - ETA: 0s - loss: 0.3086 - sparse_categorical_accuracy: 0.9102INFO:tensorflow:Assets written to: ./ckpt/ckpt-loss=0.31/assets
1563/1563 [==============================] - 8s 5ms/step - loss: 0.3000 - sparse_categorical_accuracy: 0.9128

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

また、モデルを保存および復元するための独自のコールバックを呼び出します。

シリアル化と保存の完全なガイドについては、モデルの保存とシリアル化ガイドを参照してください

学習率スケジュールの使用

深層学習モデルをトレーニングするときの一般的なパターンは、トレーニングの進行に伴って徐々に学習を減らすことです。これは一般に「学習率の減衰」として知られています。

学習減衰スケジュールは、静的(現在のエポックまたは現在のバッチインデックスの関数として事前に修正)または動的(モデルの現在の動作、特に検証損失に対応)にすることができます。

オプティマイザにスケジュールを渡す

オプティマイザーのlearning_rate引数としてスケジュールオブジェクトを渡すことで、静的学習率の減衰スケジュールを簡単に使用できます。

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)

ExponentialDecayPiecewiseConstantDecayPolynomialDecay 、およびInverseTimeDecayいくつかの組み込みのスケジュールが利用可能です。

コールバックを使用して動的学習率スケジュールを実装する

これらのスケジュールオブジェクトでは、オプティマイザが検証メトリックにアクセスできないため、動的学習率スケジュール(たとえば、検証の損失が改善されなくなったときに学習率を下げる)を達成できません。

ただし、コールバックは検証メトリックを含むすべてのメトリックにアクセスできます!したがって、オプティマイザの現在の学習率を変更するコールバックを使用して、このパターンを実現できます。実際、これはReduceLROnPlateauコールバックとして組み込まれています。

トレーニング中の損失と測定基準の視覚化

トレーニング中にモデルを監視する最善の方法は、 TensorBoardを使用することです。TensorBoardは、ローカルで実行できるブラウザーベースのアプリケーションであり、以下を提供します。

  • トレーニングと評価のための損失とメトリックのライブプロット
  • (オプション)レイヤーアクティベーションのヒストグラムの視覚化
  • (オプション) Embeddingレイヤーによって学習された埋め込みスペースの3D視覚化

TensorFlowをpipでインストールしている場合は、コマンドラインからTensorBoardを起動できるはずです。

tensorboard --logdir=/full_path_to_your_logs

TensorBoardコールバックの使用

KerasモデルとfitメソッドでTensorBoardを使用する最も簡単な方法は、 TensorBoardコールバックです。

最も単純なケースでは、コールバックでログを書き込む場所を指定するだけでよいのです。

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

詳細については、 TensorBoardコールバックのドキュメントをご覧ください。