📝

[TensorFlowDeveloper]#2 C1W2_Implementing Callbacks

2022/08/12に公開

week2ではトレーニングの途中で精度が決められた閾値に到達した場合に学習をストップするようなCallback関数の実装について学びます。

ちなみに、アサインメントは下記でgitにて公開されてますので誰でも自由にチャレンジすることできます。
TensorFlow Developer Certification C1W2アサインメント

学習目標

1.トレーニング中のモデルの精度と損失をトラッキングするためのコールバック関数の利用
2.レイヤーサイズが学習精度と学習速度にいかに影響するかを予測する
3.トレーニングの速度向上のためのピクセル値の正規化実装
4.ファッション画像MNISTを分類するためのマルチレイヤーネットワークの構築

Callback関数(コールバック関数)

トレーニング処理の途中で評価を行い、指定した指標が閾値値に到達した場合にトレーニングをストップすることができる関数です。処理タイミングの違いによって下記のような関数が用意されていますが、今回のアサインではエポックの終了時に判定を行いたいので「on_epoch_end」を利用します。

関数 処理タイミング
on_epoch_begin 全てのエポックの開始時
on_epoch_end 全てのエポックの終了時
on_batch_begin 全てのバッチの終了時
on_batch_end 全てのバッチの終了時
on_train_begin 訓練の開始時
on_train_end 訓練の終了時

なお、on_epoch_end関数は、引数にlogsを持っており、関数の中でそれぞれ下記指標を判断することできます。

  • logs.get('accuracy'):精度
  • logs.get('loss'):損失

アサインメントの内容

Implementing Callbacks in TensorFlow using the MNIST Dataset(MNISTデータセットを利用したTensorFlowのコールバック関数の実装)

手書きの0〜9の数字の画像を識別するモデルを作成し、コールバック関数を用いて閾値以上の精度となった場合に学習をストップさせられるようにするトレーニング処理を実装することゴールです。
■条件
1.試行回数は9回以下とすること
2.精度が99%以上となった場合に"Reached 99% accuracy so cancelling training!" を出力して学習をストップさせること

1.Callback関数の定義

まずは、今回のメインであるコールバック関数を定義します。
keras.callbacks.Callbackを引数にmyCallbacクラスを定義し、クラスの中にエポックの終了時点で評価を行うon_epoch_end関数を定義します。
今回のアサインメントではaccuracyが99%以上になった場合、トレーニングをストップさせるのでlogs.get('accuracy')>0.99の条件に該当した場合に、self.model.stop_training = Trueでトレーニングを終了させます。

class myCallback(keras.callbacks.Callback):#Callbackクラスを継承してコールバッククラスを作成
        # Define the correct function signature for on_epoch_end
        def on_epoch_end(self, epoch, logs={}):#引数としてself,epoch,logsを定義
            if logs.get('accuracy') is not None and logs.get('accuracy') > 0.99:
                print("\nReached 99% accuracy so cancelling training!") 
                
                # Stop training once the above condition is met
                self.model.stop_training = True

2.モデル定義

ここからはweek1の内容を参考にモデル定義を行います。
今回は3層のレイヤーで学習させます。
1層目は今回分類する元データは28×28の画像なので、これをFlattenを用いて一次元データに変換します。
2層目は隠れ層で、アクティベーションにはreluを指定し、ユニット数は512で試してみます。
3層目は最終層なのでユニット数は分類するラベルの数と一致させる必要があるので10を指定し、アクティベーションはsoftmaxを利用します。

    # Define the model
    model = tf.keras.models.Sequential([ 
          tf.keras.layers.Flatten(input_shape=(28, 28)),#28×28の画像データを一次元で表現
          tf.keras.layers.Dense(512, activation=tf.nn.relu),#いったん512で試す
          tf.keras.layers.Dense(10, activation=tf.nn.softmax)#0〜9を識別するので最終レイヤーは10
    ]) 

これでモデル定義ができました。

コンパイル

最適化アルゴリズムにadam、損失関数にsparse_categorical_crossentropy、評価関数にaccuracyを指定してコンパイルします。

# Compile the model
model.compile(optimizer='adam', 
                  loss='sparse_categorical_crossentropy', 
                  metrics=['accuracy']) 

フィッティング(学習)

fit関数を使って、引数に説明変数、目的変数、試行回数(エポック)、コールバック関数を指定してトレーニングを実施します。

  history = model.fit(x_train, y_train, epochs=10, callbacks=[callbacks])

実行結果

フィッティングを実行した結果5回の試行で、accuracy: 0.9910となり0.99以上となったためトレーニングがストップすることを確認できました。

Epoch 1/10
1875/1875 [==============================] - 8s 4ms/step - loss: 0.1996 - accuracy: 0.9413
Epoch 2/10
1875/1875 [==============================] - 8s 4ms/step - loss: 0.0810 - accuracy: 0.9750
Epoch 3/10
1875/1875 [==============================] - 8s 4ms/step - loss: 0.0506 - accuracy: 0.9840
Epoch 4/10
1875/1875 [==============================] - 8s 4ms/step - loss: 0.0366 - accuracy: 0.9884
Epoch 5/10
1865/1875 [============================>.] - ETA: 0s - loss: 0.0274 - accuracy: 0.9910
Reached 99% accuracy so cancelling training!
1875/1875 [==============================] - 8s 4ms/step - loss: 0.0274 - accuracy: 0.9910
If you see the message Reached 99% accuracy so cancelling training! printed out after less than 9 epochs it means your callback worked as expected.

Discussion