ホーム » Keras » TensorFlow 2.4 : ガイド : Keras :- 組込みメソッドで訓練と評価

TensorFlow 2.4 : ガイド : Keras :- 組込みメソッドで訓練と評価

TensorFlow 2.0 : ガイド : Keras :- 組込みメソッドで訓練と評価 (翻訳/解説)

翻訳 : (株)クラスキャット セールスインフォメーション
作成日時 : 01/11/2021

* 本ページは、TensorFlow org サイトの Guide – Keras の以下のページを翻訳した上で
適宜、補足説明したものです:

* サンプルコードの動作確認はしておりますが、必要な場合には適宜、追加改変しています。
* ご自由にリンクを張って頂いてかまいませんが、sales-info@classcat.com までご一報いただけると嬉しいです。

 

無料セミナー実施中 クラスキャット主催 人工知能 & ビジネス Web セミナー

人工知能とビジネスをテーマにウェビナー (WEB セミナー) を定期的に開催しています。スケジュールは弊社 公式 Web サイト でご確認頂けます。
  • お住まいの地域に関係なく Web ブラウザからご参加頂けます。事前登録 が必要ですのでご注意ください。
  • Windows PC のブラウザからご参加が可能です。スマートデバイスもご利用可能です。
クラスキャットは人工知能・テレワークに関する各種サービスを提供しております :

人工知能研究開発支援 人工知能研修サービス テレワーク & オンライン授業を支援
PoC(概念実証)を失敗させないための支援 (本支援はセミナーに参加しアンケートに回答した方を対象としています。

お問合せ : 本件に関するお問い合わせ先は下記までお願いいたします。

株式会社クラスキャット セールス・マーケティング本部 セールス・インフォメーション
E-Mail:sales-info@classcat.com ; WebSite: https://www.classcat.com/
Facebook: https://www.facebook.com/ClassCatJP/

 

 

ガイド : Keras :- 組込みメソッドで訓練と評価

セットアップ

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

 

イントロダクション

このガイドは (model.fit(), model.evaluate(), model.predict() のような) 訓練 & 検証のための組込み API を使用するときの訓練、評価と予測 (推論) モデルをカバーします。

貴方自身の訓練ステップ関数を指定する間に fit() を活用することに関心がある場合には、”customizing what happens in fit()” を見てください。

貴方自身の訓練 & 評価ループをスクラッチから書くことに関心がある場合には、”スクラッチから訓練ループを書く” を見てください。

一般に、組み込みループを使用していようが貴方自身のものを書いていようが、モデル訓練 & 評価は総ての種類の Keras モデル — シーケンシャル・モデル、Functional API で構築されたモデル、そしてモデル・サブクラス化を通してスクラッチから書かれたモデル — に渡り厳密に同じように動作します。

このガイドは分散訓練はカバーしません。分散訓練については、マルチ-gpu & 分散訓練へのガイド を見てください。

 

API 概要: 最初の end-to-end サンプル

データをモデルの組み込み訓練ループに渡すとき、(もし貴方のデータが小さくてメモリに収まるのであれば) Numpy 配列tf.data Dataset オブジェクトを使用するべきです。次の幾つかのパラグラフでは、optimizer、損失そしてメトリクスをどのように使用するかを実演するために、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)

ここに典型的な end-to-end ワークフローがどのようなものかがあり、以下から成ります :

  • 訓練
  • 元の訓練データから生成された取り置いたセット上の検証
  • テストデータ上の評価

このサンプルのために 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]

訓練 configuration を指定します (optimizer、損失、メトリクス) :

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

fit() を呼び出します、これはデータをサイズ “batch_size” の “batches” にスライスし、そして与えられた数の “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.5805 - sparse_categorical_accuracy: 0.8396 - val_loss: 0.1783 - val_sparse_categorical_accuracy: 0.9477
Epoch 2/2
782/782 [==============================] - 2s 2ms/step - loss: 0.1698 - sparse_categorical_accuracy: 0.9495 - val_loss: 0.1314 - val_sparse_categorical_accuracy: 0.9606

返された “history” オブジェクトは訓練の間の損失値とメトリック値の記録を保持しています :

history.history
{'loss': [0.34305039048194885, 0.15996208786964417],
 'sparse_categorical_accuracy': [0.9029399752616882, 0.9515600204467773],
 'val_loss': [0.17833450436592102, 0.1313990205526352],
 'val_sparse_categorical_accuracy': [0.947700023651123, 0.9606000185012817]}

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.1306 - sparse_categorical_accuracy: 0.9597
test loss, test acc: [0.13056731224060059, 0.9596999883651733]
Generate predictions for 3 samples
predictions shape: (3, 10)

今は、このワークフローの各ピースを詳細にレビューしましょう。

 

compile() メソッド: 損失、メトリクス、そして optimizer を指定する

fit でモデルを訓練するためには、損失関数、optimizer そしてオプションで監視するための幾つかのメトリクスを指定する必要があります。

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

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

metrics 引数はリストであるべきです — 貴方のモデルは任意の数のメトリクスを持つことができます。

貴方のモデルがマルチ出力を持つ場合、各出力に対して異なる損失とメトリクスを指定できて、そしてモデルのトータル損失への各出力の寄与を調節できます。これについての更なる詳細をセクション「データをマルチ入力、マルチ出力モデルに渡す」で見つけるでしょう。

デフォルト設定で満足できる場合には、多くの場合 optimizer、損失とメトリクスはショートカットとして文字列識別子で指定できることに注意してください :

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

後で再利用するために、モデル定義と compile ステップを関数内に配置しましょう ; それらをこのガイドの異なるサンプルに渡り幾度か呼び出します。

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

 
多くの組み込み optimizer、損失とメトリクスが利用可能です

一般に、貴方自身の損失、メトリクスや optimizer をスクラッチから作成しなくてもかまいません、何故ならば貴方が必要なものは既に Keras API の一部でありがちだからです :

Optimizers :

  • SGD() (with or without モメンタム)
  • 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 [==============================] - 2s 2ms/step - loss: 0.0281
<tensorflow.python.keras.callbacks.History at 0x7f01164a8978>

y_true と y_pred の他のパラメータを取る損失関数を必要とする場合、tf.keras.losses.Loss クラスをサブクラス化して次の 2 つのメソッドを実装することができます :

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

貴方は平均二乗誤差を使用することを望むとしましょう、但し 0.5 から遠い予測値に刺激を与えないような (= de-incentivize) 追加項とともに (categorical ターゲットは one-hot エンコードされて 0 と 1 の間の値を取るものと仮定します)。これはモデルが確信し過ぎないようにインセンティブを作成します、これは overfitting を減じるのに役立つかもしれません (それが動作するかは試すまで分かりません!)。

ここにそれをどのように行なうかがあります :

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.0489
<tensorflow.python.keras.callbacks.History at 0x7f0115bd5828>

 

カスタム・メトリクス

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() で) 別々にしておきます、何故ならばある場合には、結果計算は非常に高価であるかもしれないためで、それは定期的にだけ行われるでしょう。

ここに CatgoricalTruePositives メトリックをどのように実装するかを示す単純なサンプルがあります、それは与えられたクラスに属するものとして正しく分類されたサンプルが幾つかを数えます :

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.5990 - categorical_true_positives: 21949.4393
Epoch 2/3
782/782 [==============================] - 2s 2ms/step - loss: 0.1754 - categorical_true_positives: 23804.2822
Epoch 3/3
782/782 [==============================] - 2s 2ms/step - loss: 0.1215 - categorical_true_positives: 24171.2644
<tensorflow.python.keras.callbacks.History at 0x7fd152f26e80>

 

標準的なシグネチャに当てはまらない損失とメトリクスを扱う

損失とメトリクスの圧倒的な大部分は y_true と y_pred から計算できます、ここで y_pred はモデルの出力です。しかし総てではありません。例えば、正則化損失は層の活性を必要とするだけかもしれません (この場合ターゲットはありません)、そしてこの活性はモデル出力ではないかもしれません。

そのような場合、カスタム層の call メソッドの内側から self.add_loss(loss_value) を呼び出すことができます。このように追加された損失は訓練の間は “main” 損失に追加されます (compile() に渡された 1 つ)。ここに activity 正則化を追加する単純なサンプルがあります (activity 正則化は総ての 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 [==============================] - 2s 2ms/step - loss: 3.6940
<tensorflow.python.keras.callbacks.History at 0x7fd152623780>

add_metric() を使用して、logging メトリック値に対しても同じことを行うことができます :

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.5606 - std_of_activation: 0.9663
<tensorflow.python.keras.callbacks.History at 0x7fd15149e6d8>

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: 3.7107 - std_of_activation: 0.0021
<tensorflow.python.keras.callbacks.History at 0x7fd150b28668>

add_loss() を通して損失を渡すとき損失関数なしで compile() を呼び出すことが可能になることに注意してください、何故ならばモデルは既に最小化するための損失を持っているからです。

次の LogisticEndpoint 層を考えます : それは入力として targets & logits を取り、そしてそれは add_loss() を通して交差エントロピー損失を追跡します。それはまた 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)

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

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 355ms/step - loss: 0.8829 - binary_accuracy: 0.0000e+00

マルチ入力モデルの訓練についてより多くの情報のためには、セクション Passing data to multi-input, multi-output models を見てください。

 

検証取り置き (= holdout) セットを自動的に分離する

貴方が見た最初の end-to-end サンプルでは、各エポックの終わりに検証損失と検証メトリクスを評価するために Numpy 配列のタプル (x_val, y_val) をモデルに渡すために validation_data 引数を使用しました。

ここにもう一つのオプションがあります : 引数 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 [==============================] - 2s 3ms/step - loss: 0.6469 - sparse_categorical_accuracy: 0.8200 - val_loss: 0.2360 - val_sparse_categorical_accuracy: 0.9282
<tensorflow.python.keras.callbacks.History at 0x7fd14d1d42e8>

 

tf.data Datasets からの訓練 & 評価

前の 2, 3 のパラグラフでは、損失、メトリクスと optimizer をどのように扱うかを見ました、そしてデータが Numpy 配列として渡されるとき、fit で 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 3ms/step - loss: 0.5574 - sparse_categorical_accuracy: 0.8441
Epoch 2/3
782/782 [==============================] - 2s 3ms/step - loss: 0.1744 - sparse_categorical_accuracy: 0.9499
Epoch 3/3
782/782 [==============================] - 2s 3ms/step - loss: 0.1216 - sparse_categorical_accuracy: 0.9639
Evaluate
157/157 [==============================] - 0s 1ms/step - loss: 0.1193 - sparse_categorical_accuracy: 0.9641
{'loss': 0.11928322911262512,
 'sparse_categorical_accuracy': 0.9641000032424927}

Dataset は各エポックの最後にリセットされますので、それは次のエポックで再利用できることに注意してください。

このデータセットから特定の数のバッチ上でだけ訓練を実行することを望む場合、steps_per_epoch 引数を渡すことができます、これは次のエポックに移る前にこの Dataset を使用してモデルが幾つの訓練ステップを実行するべきかを指定します。

これを行なう場合、dataset は各エポックの最後にリセットされません、代わりに次のバッチを単にドローし続けます。dataset はやがてデータを使い果たします (それが無限ループな 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)

# 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: 1.2767 - sparse_categorical_accuracy: 0.6370
Epoch 2/3
100/100 [==============================] - 0s 3ms/step - loss: 0.4023 - sparse_categorical_accuracy: 0.8871
Epoch 3/3
100/100 [==============================] - 0s 3ms/step - loss: 0.3542 - sparse_categorical_accuracy: 0.8964
<tensorflow.python.keras.callbacks.History at 0x7fd14d6df4e0>

 

検証 dataset を使用する

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 [==============================] - 3s 3ms/step - loss: 0.5455 - sparse_categorical_accuracy: 0.8495 - val_loss: 0.2034 - val_sparse_categorical_accuracy: 0.9388
<tensorflow.python.keras.callbacks.History at 0x7fd15710acf8>

各エポックの最後に、モデルは検証 Dataset に渡り反復して検証損失と検証メトリクスを計算します。

この Dataset から特定の数のバッチ上でだけ検証を実行することを望む場合、validation_steps 引数を渡すことができます、これはモデルが検証を中断して次のエポックに進む前に検証 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,
    # 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.5584 - sparse_categorical_accuracy: 0.8487 - val_loss: 0.3266 - val_sparse_categorical_accuracy: 0.9187
<tensorflow.python.keras.callbacks.History at 0x7fd15702b780>

検証 Dataset は各使用の後にリセットされることに注意してください (その結果エポックからエポックへ同じサンプル上で常に評価しています)。

Dataset オブジェクトから訓練するときには (訓練データから取り置いたセットを生成する) 引数 validation_split はサポートされません、何故ならばこの機能は (Dataset API では一般に可能ではない) dataset のサンプルをインデックスする機能を必要とするからです。

 

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

Numpy 配列、eager tensor と TensorFlow Dataset の他にも、Pandas データフレームを使用したりバッチを yield する Python ジェネレータから Keras モデルを訓練することが可能です。

特に、keras.utils.Sequence クラスは (マルチプロセッシング-aware でシャッフル可能な) Python データ・ジェネレータを構築するための単純なインターフェイスを提供します。

一般に、以下を利用することを勧めます :

  • 貴方のデータが小さくてメモリに収まるのであれば NumPy 入力データ
  • 大規模なデータセットを持ち分散訓練を行なうことを必要とするのであれば Dataset オブジェクト
  • 大規模なデータセットを持ち TensorFlow では成せない多くのカスタム Python-側処理を行なう必要があれば Sequence オブジェクト (e.g. データロードや前処理のために外部ライブラリに依拠する場合)。

 

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

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

  • それはマルチプロセッシングと上手く動作します。
  • それはシャッフルできます (e.g. fit() で shuffle=True を渡すとき)。

シークエンスは 2 つのメソッドを実装しなければなりません :

  • __getitem__
  • __len__

メソッド __getitem__ は完全なバッチを返すべきです。エポック間でデータセットを変更することを望む場合、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 [==============================] - 2s 2ms/step - loss: 0.6064 - sparse_categorical_accuracy: 0.8448

 

サンプル重み

極め細かい制御のため、あるいは分類器を構築していない場合、”sample weights” を利用できます。

  • NumPy データから訓練するとき: Model.fit() に sample_weight 引数を渡す。
  • tf.data か任意の他の種類の iterator から訓練するとき: (input_batch, label_batch, sample_weight_batch) タプルを yield します。

“sample weights” 配列は、トータル損失を計算するときにバッチの各サンプルがどのくらいの重みを持つべきであるかを指定する数字の配列です。それは一般に不均衡な分類問題で使用されます (滅多に見られないクラスにより大きい重みを与えるアイデアです)。

使用される重みが ones か zeros であるとき、配列は損失関数のためのマスクとして使用できます (特定のサンプルのトータル損失への寄与を完全に捨てます)。

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.6247 - sparse_categorical_accuracy: 0.8420
<tensorflow.python.keras.callbacks.History at 0x7f316a017c88>

ここに適合している 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.6229 - sparse_categorical_accuracy: 0.8383
<tensorflow.python.keras.callbacks.History at 0x7f3169f36208>

 

データをマルチ入力、マルチ出力モデルに渡す

前のサンプルでは、単一の入力 (shape (764,) の tensor) と単一の出力 (shape (10,) の予測 tensor) を持つモデルを考えていました。しかしマルチ入力や出力を持つモデルについてはどうでしょう?

次のモデルを考えます、これは shape (32, 32, 3) (それは (高さ、幅、チャネル)) の画像入力と shape (None, 10) (それは (時間ステップ, 特徴)) の時系列入力を持ちます。私達のモデルはこれらの入力の組み合わせから計算された 2 つの出力を持ちます : (shape (1,) の) 「スコア」と (shape (5,) の) 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]
)

このモデルをプロットしましょう、そうすれば私達がここで何をしているかを明瞭に見ることができます (プロットで示される shape はサンプル毎 shape ではなくバッチ shape であることに注意してください)。

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

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

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

出力層に名前を与えましたので、辞書を通して出力毎の損失とメトリクスを指定することもできるでしょう :

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

2 出力以上を持つ場合、明示的な名前と辞書の使用を勧めます。

loss_weights 引数を使用して、異なる出力固有の損失に異なる重みを与えることも可能です (例えば、私達の例の「スコア」損失にクラス損失の 2 倍の重要性を与えることにより、特権を与えることを望むかもしれません) :

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

マルチ入力やマルチ出力モデルに fit でデータを渡すことは compile で損失関数を指定するのと同様な方法で動作します : (損失関数を受け取った出力への 1:1 マッピングを持つ) Numpy 配列のリスト出力名を 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 [==============================] - 1s 9ms/step - loss: 13.5903 - score_output_loss: 0.7376 - class_output_loss: 12.8527
4/4 [==============================] - 0s 9ms/step - loss: 11.6027 - score_output_loss: 0.5326 - class_output_loss: 11.0702
<tensorflow.python.keras.callbacks.History at 0x7f31532ea0f0>

ここに Dataset のユースケースがあります : Numpy 配列のために行なったことと同様です、Dataset は辞書のタプルを返すべきです。

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 15ms/step - loss: 11.3703 - score_output_loss: 0.4201 - class_output_loss: 10.9502
<tensorflow.python.keras.callbacks.History at 0x7f315ad6ac18>

 

コールバックを使用する

Keras の Callbacks は訓練の間に異なるポイント (エポックの最初、バッチの最後、エポックの最後, etc.) で呼び出されるオブジェクトでそれは次のような動作を実装するために使用できます :

  • 訓練の間に異なるポイントで検証を行なう (組込みのエポック毎検証を越えて)
  • 定期の間隔であるいはそれが特定の精度しきい値を超えたときにモデルをチェックポイントする
  • 訓練が頭打ちになったように見えるときにモデルの学習率を変更する
  • 訓練が頭打ちになったように見えるときに top 層の再調整を行なう
  • 訓練が終わるときあるいは特定のパフォーマンスしきい値を超えたところで電子メールかインスタントメッセージ通知を送る
  • 等々。

Callback は 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 2ms/step - loss: 0.6304 - sparse_categorical_accuracy: 0.8218 - val_loss: 0.2454 - val_sparse_categorical_accuracy: 0.9256
Epoch 2/20
625/625 [==============================] - 1s 2ms/step - loss: 0.1954 - sparse_categorical_accuracy: 0.9425 - val_loss: 0.1763 - val_sparse_categorical_accuracy: 0.9456
Epoch 3/20
625/625 [==============================] - 1s 2ms/step - loss: 0.1329 - sparse_categorical_accuracy: 0.9613 - val_loss: 0.1528 - val_sparse_categorical_accuracy: 0.9534
Epoch 4/20
625/625 [==============================] - 1s 2ms/step - loss: 0.1053 - sparse_categorical_accuracy: 0.9676 - val_loss: 0.1541 - val_sparse_categorical_accuracy: 0.9553
Epoch 5/20
625/625 [==============================] - 1s 2ms/step - loss: 0.0799 - sparse_categorical_accuracy: 0.9752 - val_loss: 0.1464 - val_sparse_categorical_accuracy: 0.9562
Epoch 00005: early stopping
<tensorflow.python.keras.callbacks.History at 0x7fe1e08bb518>

 

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

  • ModelCheckpoint: 定期的にモデルをセーブする。
  • EarlyStopping: 訓練がもはや検証メトリクスを改善しないときに訓練を停止する。
  • TensorBoard: TensorBoard で可視化できるモデルログを定期的に書く (セクション「可視化」で更なる詳細)。
  • CSVLogger: 損失とメトリクス・データを CSV ファイルにストリームする。
  • etc.

完全なリストについては callbacks ドキュメント を見てください。

 

貴方自身のコールバックを書く

基底クラス keras.callbacks.Callback を拡張することでカスタム callback を作成できます。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
)
poch 1/2
625/625 [==============================] - 2s 3ms/step - loss: 0.6299 - sparse_categorical_accuracy: 0.8272 - val_loss: 0.2785 - val_sparse_categorical_accuracy: 0.9163

Epoch 00001: val_loss improved from inf to 0.27849, saving model to mymodel_1
INFO:tensorflow:Assets written to: mymodel_1/assets
Epoch 2/2
625/625 [==============================] - 1s 2ms/step - loss: 0.1858 - sparse_categorical_accuracy: 0.9474 - val_loss: 0.1806 - val_sparse_categorical_accuracy: 0.9468

Epoch 00002: val_loss improved from 0.27849 to 0.18056, saving model to mymodel_2
INFO:tensorflow:Assets written to: mymodel_2/assets
<tensorflow.python.keras.callbacks.History at 0x7fe1e06de208>

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
  69/1563 [>.............................] - ETA: 2s - loss: 1.6135 - sparse_categorical_accuracy: 0.5407INFO:tensorflow:Assets written to: ./ckpt/ckpt-loss=0.98/assets
 168/1563 [==>...........................] - ETA: 7s - loss: 1.2051 - sparse_categorical_accuracy: 0.6650INFO:tensorflow:Assets written to: ./ckpt/ckpt-loss=0.71/assets
 267/1563 [====>.........................] - ETA: 7s - loss: 1.0127 - sparse_categorical_accuracy: 0.7184INFO:tensorflow:Assets written to: ./ckpt/ckpt-loss=0.59/assets
 365/1563 [======>.......................] - ETA: 6s - loss: 0.8969 - sparse_categorical_accuracy: 0.7499INFO:tensorflow:Assets written to: ./ckpt/ckpt-loss=0.53/assets
 499/1563 [========>.....................] - ETA: 5s - loss: 0.7950 - sparse_categorical_accuracy: 0.7773INFO:tensorflow:Assets written to: ./ckpt/ckpt-loss=0.49/assets
 568/1563 [=========>....................] - ETA: 5s - loss: 0.7562 - sparse_categorical_accuracy: 0.7876INFO:tensorflow:Assets written to: ./ckpt/ckpt-loss=0.45/assets
 694/1563 [============>.................] - ETA: 4s - loss: 0.6999 - sparse_categorical_accuracy: 0.8026INFO:tensorflow:Assets written to: ./ckpt/ckpt-loss=0.43/assets
 768/1563 [=============>................] - ETA: 4s - loss: 0.6730 - sparse_categorical_accuracy: 0.8099INFO:tensorflow:Assets written to: ./ckpt/ckpt-loss=0.41/assets
 868/1563 [===============>..............] - ETA: 3s - loss: 0.6418 - sparse_categorical_accuracy: 0.8183INFO:tensorflow:Assets written to: ./ckpt/ckpt-loss=0.39/assets
1000/1563 [==================>...........] - ETA: 3s - loss: 0.6074 - sparse_categorical_accuracy: 0.8276INFO:tensorflow:Assets written to: ./ckpt/ckpt-loss=0.37/assets
1100/1563 [====================>.........] - ETA: 2s - loss: 0.5852 - sparse_categorical_accuracy: 0.8336INFO:tensorflow:Assets written to: ./ckpt/ckpt-loss=0.36/assets
1169/1563 [=====================>........] - ETA: 2s - loss: 0.5715 - sparse_categorical_accuracy: 0.8374INFO:tensorflow:Assets written to: ./ckpt/ckpt-loss=0.35/assets
1268/1563 [=======================>......] - ETA: 1s - loss: 0.5537 - sparse_categorical_accuracy: 0.8423INFO:tensorflow:Assets written to: ./ckpt/ckpt-loss=0.33/assets
1369/1563 [=========================>....] - ETA: 1s - loss: 0.5374 - sparse_categorical_accuracy: 0.8468INFO:tensorflow:Assets written to: ./ckpt/ckpt-loss=0.33/assets
1496/1563 [===========================>..] - ETA: 0s - loss: 0.5191 - sparse_categorical_accuracy: 0.8518INFO:tensorflow:Assets written to: ./ckpt/ckpt-loss=0.32/assets
1563/1563 [==============================] - 9s 6ms/step - loss: 0.5102 - sparse_categorical_accuracy: 0.8543
<tensorflow.python.keras.callbacks.History at 0x7fe1e035b358>

モデルをセーブしてリストアするための貴方自身のコールバックを書くこともできます。

シリアライゼーションとセービングについての完全なガイドは、Saving and Serializing Models へのガイドを見てください。

 

学習率スケジュールを使用する

深層学習モデルを訓練するときの共通のパターンは訓練が進むにつれて学習率を徐々に減じることです。これは一般に「学習率減衰 (= decay)」として知られています。

学習率減衰は静的 (現在のエポックか現在のバッチインデックスの関数として、前もって固定) でも動的 (モデルの現在の動作に呼応、特に検証損失) でもあり得るでしょう。

 

スケジュールを optimizer に渡す

スケジュール・オブジェクトを optimizer の 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)

幾つかの組込みスケジュールが利用可能です : ExponentialDecay, PiecewiseConstantDecay, PolynomialDecay そして InverseTimeDecay.

 

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

動的学習率スケジュール (例えば、検証損失がもはや改善しないときに学習率を減じます) はこれらのスケジュール・オブジェクトでは達成できません、何故ならば optimizer は検証メトリクスへのアクセスを持たないからです。

けれども、コールバックは検証メトリクスを含む、総てのメトリクスへのアクセスを持ちます!こうして optimizer の現在の学習率を変更するコールバックを使用してこのパターンを達成できます。実際に、これは ReduceLROnPlateau コールバックとして組込みでさえあります。

 

訓練の間に損失とメトリクスを可視化する

訓練の間に貴方のモデルを監視する最善の方法は 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)

TensorBoard callback は、embeddings, histograms をロギングするか否か、そしてどのくらいの頻度でログを書くかを含む、多くの有用なオプションを持ちます :

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 0x7fe1e0781ef0>
 

以上



AI導入支援 #2 ウェビナー

スモールスタートを可能としたAI導入支援   Vol.2
[無料 WEB セミナー] [詳細]
「画像認識 AI PoC スターターパック」の紹介
既に AI 技術を実ビジネスで活用し、成果を上げている日本企業も多く存在しており、競争優位なビジネスを展開しております。
しかしながら AI を導入したくとも PoC (概念実証) だけでも高額な費用がかかり取組めていない企業も少なくないようです。A I導入時には欠かせない PoC を手軽にしかも短期間で認知度を確認可能とするサービの紹介と共に、AI 技術の特性と具体的な導入プロセスに加え運用時のポイントについても解説いたします。
日時:2021年10月13日(水)
会場:WEBセミナー
共催:クラスキャット、日本FLOW(株)
後援:働き方改革推進コンソーシアム
参加費: 無料 (事前登録制)
人工知能開発支援
◆ クラスキャットは 人工知能研究開発支援 サービスを提供しています :
  • テクニカルコンサルティングサービス
  • 実証実験 (プロトタイプ構築)
  • アプリケーションへの実装
  • 人工知能研修サービス
◆ お問合せ先 ◆
(株)クラスキャット
セールス・インフォメーション
E-Mail:sales-info@classcat.com