Tensorflow Keras を利用した深層学習(Deep Learning)2値分類モデルの単純な実装例について,常に参照できるように備忘録として示す。モデル構築の実装例を可能な限りシンプルに示すため,入力データの前処理やハイパーパラメータ調整については特別扱わない。
開発環境
- keras: 2.10.0
- matplotlib: 3.5.3
- python: 3.10.4
- tensorflow-gpu: 2.4.0
ソースコード
import numpy as np
from tensorflow.keras import Sequential
from tensorflow.keras.layers import Dense, Input
from tensorflow.keras.datasets import boston_housing
from sklearn.preprocessing import MinMaxScaler
from sklearn.metrics import confusion_matrix, classification_report
from matplotlib import pyplot as plt
# データセット作成
# データの読み込み
boston = boston_housing
(X_train, y_train), (X_test, y_test) = boston.load_data()
# 平均値より小さいターゲットを0に,平均値以上のターゲットを1に変更して2クラス分類課題にする
threshold = y_train.mean()
y_train, y_test = np.where(y_train < threshold, 0, 1), np.where(y_test < threshold, 0, 1)
# 特徴量を正規化する
scaler = MinMaxScaler().fit(X_train)
X_train, X_test = scaler.transform(X_train), scaler.transform(X_test)
# モデル作成
# 入力層/中間層/出力層 各1層
model = Sequential()
# 入力層
model.add(Input(shape=(X_train.shape[1],)))
# 中間層
model.add(Dense(64, activation='relu'))
# 出力層
model.add(Dense(1))
# モデルコンパイル
model.compile(loss='binary_crossentropy', optimizer='adam', metrics='accuracy')
# モデル内容の確認
model.summary()
# 学習
history = model.fit(X_train, y_train, epochs=50, validation_split=0.2)
# 学習過程の可視化
fig, ax = plt.subplots(1, 2)
# Loss変動の可視化
ax[0].plot(history.history['loss'], label='Train')
ax[0].plot(history.history['val_loss'], label='Test')
ax[0].set_title('Model loss')
ax[0].set_ylabel('Loss')
ax[0].set_xlabel('Epoch')
ax[0].legend()
# Accuracy変動の可視化
ax[1].plot(history.history['accuracy'], label='Train')
ax[1].plot(history.history['val_accuracy'], label='Test')
ax[1].set_title('Model accuracy')
ax[1].set_ylabel('Accuracy')
ax[1].set_xlabel('Epoch')
ax[1].legend()
plt.tight_layout()
plt.show()
# 予測値を計算
pred = (model.predict(X_test) > 0.5).astype('int32')
# 予測値精度
print('混合行列\n', confusion_matrix(y_test, pred))
print('各種制度指標\n', classification_report(y_test, pred))
パッケージのインポート
「matplotlib」は学習・予測結果の可視化に,「scikit-learn」は前処理及ぼ予測精度の評価に用いる。
import numpy as np
from tensorflow.keras import Sequential
from tensorflow.keras.layers import Dense, Input
from tensorflow.keras.datasets import boston_housing
from sklearn.preprocessing import MinMaxScaler
from sklearn.metrics import confusion_matrix, classification_report
from matplotlib import pyplot as plt
データセット作成
keras で用意されているboston_housingデータセットを用いる。学習データ(X_train)は404行13列,テストデータ(X_test)は102行13列のデータ。
boston_housingデータセットのターゲットは連続値なので,平均値を以上の値はクラス1,平均値より小さい値はクラス0に置き換えることで,2値分類データセットに変換している。
# データの読み込み
boston = boston_housing
(X_train, y_train), (X_test, y_test) = boston.load_data()
# 平均値より小さいターゲットを0に,平均値以上のターゲットを1に変更して2クラス分類課題にする
threshold = y_train.mean()
y_train, y_test = np.where(y_train < threshold, 0, 1), np.where(y_test < threshold, 0, 1)
# 特徴量を正規化する
scaler = MinMaxScaler().fit(X_train)
X_train, X_test = scaler.transform(X_train), scaler.transform(X_test)
モデル作成
シンプルな実装例として,各1層の入力層/中間層/出力層で構成される回帰モデルを定義する。下記の例において中間層は64個のユニットを持つ。出力は値が平均値以上か否か [0 or 1] に対応するn行1列の形状になるので,ユニット数は1を指定する。2値分類が目的なので,損失は’binary_crossentropy’を指定。
# 入力層/中間層/出力層 各1層
model = Sequential()
# 入力層
model.add(Input(shape=(X_train.shape[1],)))
# 中間層
model.add(Dense(64, activation='relu'))
# 出力層
model.add(Dense(1))
# モデルコンパイル
model.compile(loss='binary_crossentropy', optimizer='adam', metrics='accuracy')
# モデル内容の確認
model.summary()
# コード実行時の出力
Model: "sequential_1"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
dense (Dense) (None, 64) 896
_________________________________________________________________
dense_1 (Dense) (None, 1) 65
=================================================================
Total params: 961
Trainable params: 961
Non-trainable params: 0
_________________________________________________________________
学習
定義した回帰モデルについて,事前に用意しておいた学習データ(X_train)と正答データ(y_test)を与え,fitメソッドを利用して学習を行う。下記の例では訓練回数は50回(epochs=50),バリデーションデータ割合は20%(validation_split=0.2)に指定している。
history = model.fit(X_train, y_train, epochs=50, validation_split=0.2)
# コード実行時の出力
Epoch 1/50
11/11 [==============================] - 2s 113ms/step - loss: 4.7995 - accuracy: 0.5715 - val_loss: 1.3066 - val_accuracy: 0.5062
Epoch 2/50
11/11 [==============================] - 0s 12ms/step - loss: 0.9818 - accuracy: 0.5124 - val_loss: 0.8908 - val_accuracy: 0.3951
.
.
.
Epoch 49/50
11/11 [==============================] - 0s 11ms/step - loss: 0.3037 - accuracy: 0.9043 - val_loss: 0.6630 - val_accuracy: 0.8395
Epoch 50/50
11/11 [==============================] - 0s 11ms/step - loss: 0.2590 - accuracy: 0.9342 - val_loss: 0.6693 - val_accuracy: 0.8395
学習過程の可視化
history変数内に保存されている学習過程の情報を用いて,学習データ/バリデーションデータに対する損失(loss)および正答率(accuracy)の変動を可視化する。
# 学習過程の可視化
fig, ax = plt.subplots(1, 2)
# Loss変動の可視化
ax[0].plot(history.history['loss'], label='Train')
ax[0].plot(history.history['val_loss'], label='Test')
ax[0].set_title('Model loss')
ax[0].set_ylabel('Loss')
ax[0].set_xlabel('Epoch')
ax[0].legend()
# Accuracy変動の可視化
ax[1].plot(history.history['accuracy'], label='Train')
ax[1].plot(history.history['val_accuracy'], label='Test')
ax[1].set_title('Model accuracy')
ax[1].set_ylabel('Accuracy')
ax[1].set_xlabel('Epoch')
ax[1].legend()
plt.tight_layout()
plt.show()
予測値を計算
学習済みモデルの predictメソッドを用いてテストデータ(X_test)について予測値を求める。一応,predict_classesメソッドを利用することもできるが,UserWarningが表示されるので,警告内容の記載に従って以下の書き方をしている。
pred = (model.predict(X_test) > 0.5).astype('int32')
予測精度
テストデータ(X_test)についての予測の正しさを可視化するため,混合行列および各種評価指標を出力する。
print('混合行列\n', confusion_matrix(y_test, pred))
print('各種制度指標\n', classification_report(y_test, pred))
# コード実行時の出力
混合行列
[[44 10]
[11 37]]
各種制度指標
precision recall f1-score support
0 0.80 0.81 0.81 54
1 0.79 0.77 0.78 48
accuracy 0.79 102
macro avg 0.79 0.79 0.79 102
weighted avg 0.79 0.79 0.79 102
コメント