このページは 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.3476 - sparse_categorical_accuracy: 0.9005 - val_loss: 0.1868 - val_sparse_categorical_accuracy: 0.9452
Epoch 2/2
782/782 [==============================] - 2s 2ms/step - loss: 0.1622 - sparse_categorical_accuracy: 0.9517 - val_loss: 0.1334 - val_sparse_categorical_accuracy: 0.9616

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

history.history
{'loss': [0.34755897521972656, 0.16218683123588562],
 'sparse_categorical_accuracy': [0.9004799723625183, 0.9516800045967102],
 'val_loss': [0.18684418499469757, 0.13335685431957245],
 'val_sparse_categorical_accuracy': [0.9452000260353088, 0.9616000056266785]}

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.1379 - sparse_categorical_accuracy: 0.9594
test loss, test acc: [0.13789668679237366, 0.9593999981880188]
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.0156

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

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 1ms/step - loss: 0.0386

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

カスタムメトリック

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 [==============================] - 1s 2ms/step - loss: 0.3406 - categorical_true_positives: 45130.0000
Epoch 2/3
782/782 [==============================] - 1s 2ms/step - loss: 0.1591 - categorical_true_positives: 47607.0000
Epoch 3/3
782/782 [==============================] - 2s 2ms/step - loss: 0.1140 - categorical_true_positives: 48302.0000

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

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

圧倒的多数の損失とメトリクスは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.5240

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

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.3414 - std_of_activation: 1.0120

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

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 [==============================] - 1s 2ms/step - loss: 2.5604 - std_of_activation: 0.0023

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

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.9677 - binary_accuracy: 0.0000e+00

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

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

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

最初に見たエンドツーエンドの例では、 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.3745 - sparse_categorical_accuracy: 0.8950 - val_loss: 0.2279 - val_sparse_categorical_accuracy: 0.9333

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

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

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

ここで、データが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.3373 - sparse_categorical_accuracy: 0.9045
Epoch 2/3
782/782 [==============================] - 2s 2ms/step - loss: 0.1582 - sparse_categorical_accuracy: 0.9528
Epoch 3/3
782/782 [==============================] - 2s 2ms/step - loss: 0.1146 - sparse_categorical_accuracy: 0.9658
Evaluate
157/157 [==============================] - 0s 1ms/step - loss: 0.1300 - sparse_categorical_accuracy: 0.9601

{'loss': 0.12998636066913605, 'sparse_categorical_accuracy': 0.960099995136261}

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

このデータセットから特定の数のバッチでのみトレーニングを実行する場合は、 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.7669 - sparse_categorical_accuracy: 0.8027
Epoch 2/3
100/100 [==============================] - 0s 2ms/step - loss: 0.3694 - sparse_categorical_accuracy: 0.8947
Epoch 3/3
100/100 [==============================] - 0s 2ms/step - loss: 0.3178 - sparse_categorical_accuracy: 0.9080

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

検証データセットの使用

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

model = get_compiled_model()

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

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

model.fit(train_dataset, epochs=1, validation_data=val_dataset)
782/782 [==============================] - 2s 2ms/step - loss: 0.3401 - sparse_categorical_accuracy: 0.9047 - val_loss: 0.1726 - val_sparse_categorical_accuracy: 0.9521

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

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

このデータセットから特定の数のバッチでのみ検証を実行する場合は、 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.3402 - sparse_categorical_accuracy: 0.9024 - val_loss: 0.3108 - val_sparse_categorical_accuracy: 0.9250

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

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

引数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})使用できます。

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

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 [==============================] - 1s 2ms/step - loss: 0.3811 - sparse_categorical_accuracy: 0.8999

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

サンプルの重み

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

  • 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 [==============================] - 1s 2ms/step - loss: 0.3763 - sparse_categorical_accuracy: 0.9000

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

以下は、一致する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.3776 - sparse_categorical_accuracy: 0.9005

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

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

前の例では、単一の入力(形状のテンソル(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つ以上の出力がある場合は、明示的な名前と辞書を使用することをお勧めします。

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 6ms/step - loss: 11.1192 - score_output_loss: 0.5547 - class_output_loss: 10.5645
4/4 [==============================] - 0s 4ms/step - loss: 9.9594 - score_output_loss: 0.4204 - class_output_loss: 9.5390

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

これが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 8ms/step - loss: 9.7058 - score_output_loss: 0.3508 - class_output_loss: 9.3550

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

コールバックの使用

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 [==============================] - 1s 2ms/step - loss: 0.3744 - sparse_categorical_accuracy: 0.8949 - val_loss: 0.2301 - val_sparse_categorical_accuracy: 0.9336
Epoch 2/20
625/625 [==============================] - 1s 2ms/step - loss: 0.1762 - sparse_categorical_accuracy: 0.9485 - val_loss: 0.1818 - val_sparse_categorical_accuracy: 0.9463
Epoch 3/20
625/625 [==============================] - 1s 2ms/step - loss: 0.1292 - sparse_categorical_accuracy: 0.9616 - val_loss: 0.1620 - val_sparse_categorical_accuracy: 0.9524
Epoch 4/20
625/625 [==============================] - 1s 2ms/step - loss: 0.1014 - sparse_categorical_accuracy: 0.9699 - val_loss: 0.1486 - val_sparse_categorical_accuracy: 0.9566
Epoch 5/20
625/625 [==============================] - 1s 2ms/step - loss: 0.0847 - sparse_categorical_accuracy: 0.9751 - val_loss: 0.1612 - val_sparse_categorical_accuracy: 0.9533
Epoch 6/20
625/625 [==============================] - 1s 2ms/step - loss: 0.0699 - sparse_categorical_accuracy: 0.9788 - val_loss: 0.1447 - val_sparse_categorical_accuracy: 0.9600
Epoch 00006: early stopping

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

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

  • ModelCheckpoint :定期的にモデルを保存します。
  • 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
617/625 [============================>.] - ETA: 0s - loss: 0.3784 - sparse_categorical_accuracy: 0.8940
Epoch 00001: val_loss improved from inf to 0.22038, 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.3766 - sparse_categorical_accuracy: 0.8946 - val_loss: 0.2204 - val_sparse_categorical_accuracy: 0.9363
Epoch 2/2
595/625 [===========================>..] - ETA: 0s - loss: 0.1721 - sparse_categorical_accuracy: 0.9498
Epoch 00002: val_loss improved from 0.22038 to 0.18707, saving model to mymodel_2
INFO:tensorflow:Assets written to: mymodel_2/assets
625/625 [==============================] - 2s 3ms/step - loss: 0.1708 - sparse_categorical_accuracy: 0.9501 - val_loss: 0.1871 - val_sparse_categorical_accuracy: 0.9453

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

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
  83/1563 [>.............................] - ETA: 2s - loss: 1.0490 - sparse_categorical_accuracy: 0.7165INFO:tensorflow:Assets written to: ./ckpt/ckpt-loss=0.97/assets
 185/1563 [==>...........................] - ETA: 5s - loss: 0.7407 - sparse_categorical_accuracy: 0.7959INFO:tensorflow:Assets written to: ./ckpt/ckpt-loss=0.72/assets
 286/1563 [====>.........................] - ETA: 5s - loss: 0.6176 - sparse_categorical_accuracy: 0.8253INFO:tensorflow:Assets written to: ./ckpt/ckpt-loss=0.60/assets
 385/1563 [======>.......................] - ETA: 5s - loss: 0.5432 - sparse_categorical_accuracy: 0.8475INFO:tensorflow:Assets written to: ./ckpt/ckpt-loss=0.53/assets
 485/1563 [========>.....................] - ETA: 5s - loss: 0.4909 - sparse_categorical_accuracy: 0.8607INFO:tensorflow:Assets written to: ./ckpt/ckpt-loss=0.48/assets
 585/1563 [==========>...................] - ETA: 4s - loss: 0.4531 - sparse_categorical_accuracy: 0.8713INFO:tensorflow:Assets written to: ./ckpt/ckpt-loss=0.45/assets
 684/1563 [============>.................] - ETA: 4s - loss: 0.4262 - sparse_categorical_accuracy: 0.8788INFO:tensorflow:Assets written to: ./ckpt/ckpt-loss=0.42/assets
 784/1563 [==============>...............] - ETA: 3s - loss: 0.4066 - sparse_categorical_accuracy: 0.8845INFO:tensorflow:Assets written to: ./ckpt/ckpt-loss=0.40/assets
 882/1563 [===============>..............] - ETA: 3s - loss: 0.3863 - sparse_categorical_accuracy: 0.8902INFO:tensorflow:Assets written to: ./ckpt/ckpt-loss=0.38/assets
 985/1563 [=================>............] - ETA: 2s - loss: 0.3682 - sparse_categorical_accuracy: 0.8954INFO:tensorflow:Assets written to: ./ckpt/ckpt-loss=0.37/assets
1084/1563 [===================>..........] - ETA: 2s - loss: 0.3532 - sparse_categorical_accuracy: 0.8993INFO:tensorflow:Assets written to: ./ckpt/ckpt-loss=0.35/assets
1185/1563 [=====================>........] - ETA: 1s - loss: 0.3407 - sparse_categorical_accuracy: 0.9028INFO:tensorflow:Assets written to: ./ckpt/ckpt-loss=0.34/assets
1284/1563 [=======================>......] - ETA: 1s - loss: 0.3287 - sparse_categorical_accuracy: 0.9063INFO:tensorflow:Assets written to: ./ckpt/ckpt-loss=0.33/assets
1385/1563 [=========================>....] - ETA: 0s - loss: 0.3171 - sparse_categorical_accuracy: 0.9095INFO:tensorflow:Assets written to: ./ckpt/ckpt-loss=0.32/assets
1485/1563 [===========================>..] - ETA: 0s - loss: 0.3090 - sparse_categorical_accuracy: 0.9116INFO:tensorflow:Assets written to: ./ckpt/ckpt-loss=0.31/assets
1563/1563 [==============================] - 8s 5ms/step - loss: 0.3018 - sparse_categorical_accuracy: 0.9136

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

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

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

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

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

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

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

オプティマイザーの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 0x7fda1f3062e8>

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