はじめに
Kerasで学習する際に便利そうなコールバックがあったので使ってみました。
今回は下記のコールバックを使用してみます。
- EarlyStopping
- TensorBoard
- CSVLogger
下記にKeras公式サイトのコールバックの説明があります。
https://keras.io/ja/callbacks/
EarlyStopping
監視対象の値が変化しなくなったときに学習を終了します。エポック数を多めに指定しても途中で終了してくれるので安心です。
ここでは、エポック数10回の間に損失値の変化が0.0001より小さければ、改善がみられないと判断して学習を終了するようにします。
es_cb = keras.callbacks.EarlyStopping(
monitor='loss', min_delta=0.0001, patience=10, mode='auto')
TensorBoard
TensorBoardによる可視化を行います。
オプションがいろいろあるのですが、今回はログ出力先だけ指定して残りはデフォルト値のままとします。
tb_cb = keras.callbacks.TensorBoard(log_dir='./logs')
CSVLogger
エポックの結果をCSVファイルに出力してくれます。
csv_logger = keras.callbacks.CSVLogger('training.csv')
Pythonプログラム
前回と同様、一次関数を学習させます。
model.fit()
で学習時にコールバックの指定を追加しています。
また、validation_data
を指定して、エポックごとにテストデータの検証も行うようにしています。
model.fit(
x_train, y_train,
epochs=500,
callbacks=[es_cb, tb_cb, csv_logger],
validation_data=(x_test, y_test))
プログラムの全体です。
import matplotlib.pyplot as plt
import numpy as np
from tensorflow import keras
from sklearn.model_selection import train_test_split
# Y = 2X + 3を求める関数とする。
x = np.linspace(0, 10, num=50)
y = 2 * x + 3
# トレーニングデータと検証データに分割
x_train, x_test, y_train, y_test = train_test_split(x, y, shuffle=False)
# ネットワークを作成
model = keras.models.Sequential([
keras.layers.Dense(1, input_shape=(1,), activation="linear"),
])
# コールバックの作成
es_cb = keras.callbacks.EarlyStopping(
monitor='loss', min_delta=0.0001, patience=10, mode='auto')
tb_cb = keras.callbacks.TensorBoard(log_dir='./logs')
csv_logger = keras.callbacks.CSVLogger('./training.csv')
# オプティマイザはSGD、損失関数はMSEを使用
model.compile(optimizer='sgd', loss='mse')
model.fit(
x_train, y_train,
epochs=500,
callbacks=[es_cb, tb_cb, csv_logger],
validation_data=(x_test, y_test))
print(model.get_weights())
plt.scatter(x, y, label='data', color='gray')
plt.plot(x_train, model.predict(x_train), label='train', color='blue')
plt.plot(x_test, model.predict(x_test), label='test', color='red')
plt.legend()
plt.show()
結果
エポック数に500を指定していますが、405エポックで学習が終了しました。
TensorBoardの表示
TensorBoardを起動します。
$ tensorboard --logdir=./logs
Serving TensorBoard on localhost; to expose to the network, use a proxy or pass --bind_all
TensorBoard 2.4.1 at http://localhost:6006/ (Press CTRL+C to quit)
ブラウザで http://localhost:6006/ にアクセスするとTensorBoardを見ることができます。
グラフのオレンジの線がトレーニングデータ、青の線がテストデータです。
学習とともに損失値が小さくなっているのがわかります。
CSVLoggerの結果
CSVLoggerで指定したCSVファイルもできています。
epoch,loss,val_loss
0,254.1975860595703,116.32344818115234
1,35.86260986328125,6.254454612731934
2,5.318000793457031,0.04576351121068001
3,1.8426451683044434,1.2428233623504639
4,1.295862078666687,2.55403733253479
5,1.1909117698669434,2.0331602096557617
6,1.181778073310852,2.214395761489868
7,1.1415034532546997,3.4069273471832275
8,1.1195648908615112,3.5103976726531982
9,1.0969243049621582,2.3636646270751953
10,1.0725418329238892,3.2535252571105957
11,1.0593643188476562,2.874397039413452
(以下略)
PandasとMatplotlibでグラフ化してみます。
最初の損失値が大きいので、4番目以降のエポックのデータを使ってグラフにします。
import pandas as pd
import matplotlib.pyplot as plt
df = pd.read_csv('training.csv', index_col='epoch')
df.iloc[3:].plot()
plt.legend()
plt.show()
TensorBoardと同じようなグラフを作成することができました。
おわりに
これでモデルを作成して、学習状況を確認する準備ができました。
次回はもっと複雑なデータを使った学習を行う予定です。