実際に私が脂肪肝の超音波画像分類で使用したコードを公開いたします。
プログラミング初心者の方でも基本的には以下をコピペして順に実行すれば学習と検証が行えるようになってます。
環境はGoogle colab上を想定しています。
# ドライブのマウント
from google.colab import drive
drive.mount('/content/drive')
Google ドライブのファイルへのアクセス許可が求められるので接続してください。
# ライブラリのインストール
import tensorflow as tf
from tensorflow.keras.preprocessing import image_dataset_from_directory
from sklearn.model_selection import train_test_split
import matplotlib.pyplot as plt
import numpy as np
# 画像ディレクトリ
IMG_DIR = "/content/drive/My Drive/~"
# バッチサイズ
BATCH_SIZE = 16
# VGG16用にサイズ設定
IMAGE_SIZE = (224, 224)
IMAGE_SHAPE = IMAGE_SIZE + (3, )
# 訓練、検証、テストの比率
TRAIN_SIZE = 0.75
VALIDATION_SIZE = 0.25
# 学習率
LEARNING_RATE = 1e-5
# エポック数
INITIAL_EPOCHS =5
# ------------------------------------------------------------
# 1.画像読み込み、訓練・検証・テスト分割
# ------------------------------------------------------------
# (1) 画像読み込み
image_dataset = image_dataset_from_directory(IMG_DIR,
shuffle=False,
batch_size=BATCH_SIZE,
image_size=IMAGE_SIZE
)
# (2) 画像データセットをX:画像とY:クラス名で各々配列化
image_class_names = image_dataset.class_names
img_X = []
img_Y = []
for img_ds_batch in list(image_dataset.as_numpy_iterator()):
img_X.extend(img_ds_batch[0])
img_Y.extend(img_ds_batch[1])
img_X = np.asarray(img_X)
img_Y = np.asarray(img_Y)
# (3) 画像データの標準化
img_X = tf.keras.applications.vgg16.preprocess_input(img_X)
# (4) データセットを訓練・検証・テストに分割
# データセットを[train, (validation + test)]に分割
img_X_train, img_X_valid, img_Y_train, img_Y_valid = train_test_split(
img_X, img_Y,
train_size=TRAIN_SIZE,
random_state=RANDOM_STATE,
stratify=img_Y)
IMG_DIR = “/content/drive/My Drive/~”
上記は機械学習に使用したい画像を保存しているディレクトリを指定してください。
BATCH_SIZE = 16
バッチサイズです。適宜調節してください。
よくわからない場合で、このあとに行う学習でやたら時間がかかってしまう場合は数字を大きくしてください。32とか64とか。
# 訓練、検証、テストの比率
TRAIN_SIZE = 0.75 VALIDATION_SIZE = 0.25
画像を75%(学習用)と25%(検証用)に分割します。
割合変えたければ数字いじってください。
# ------------------------------------------------------------
# 2.モデル構築と学習
# ------------------------------------------------------------
# (1) 転移学習のベースモデルはVGG16
base_model = tf.keras.applications.vgg16.VGG16(include_top=False,
input_shape=IMAGE_SHAPE,
weights='imagenet')
# (2) 畳み込みベースの凍結
base_model.trainable = False
# (3) モデル構築
# Flatten(=平坦化層)追加
x = tf.keras.layers.Flatten()(base_model.output)
# FC1層追加
x = tf.keras.layers.Dense(4096, activation='relu')(x)
# FC2層追加
x = tf.keras.layers.Dense(4096, activation='relu')(x)
# 入力画像の形状
transfer_learning_inputs = base_model.inputs
# predictions層の追加
# 今回分類するクラス数を指定
image_class_num = len(image_class_names)
transfer_learning_prediction = tf.keras.layers.Dense(
image_class_num, activation='sigmoid')(x)
# 転移学習モデル構築
transfer_learning_model = tf.keras.Model(inputs=transfer_learning_inputs,
outputs=transfer_learning_prediction)
# (4) モデルのコンパイル
transfer_learning_model.compile(optimizer=
tf.keras.optimizers.Adam(learning_rate=LEARNING_RATE),
loss='sparse_categorical_crossentropy',
metrics=['accuracy'])
# (5) モデルの学習
history = transfer_learning_model.fit(img_X_train, img_Y_train,
epochs=INITIAL_EPOCHS,
batch_size=BATCH_SIZE,
validation_data=(img_X_valid, img_Y_valid))
------------------------------------------------------------
# 3.画像分類と精度
# ------------------------------------------------------------
print(transfer_learning_model.evaluate(img_X_valid, img_Y_valid, verbose=0))
# 訓練と検証
acc = history.history['accuracy']
val_acc = history.history['val_accuracy']
loss = history.history['loss']
val_loss = history.history['val_loss']
# 正解率
plt.figure(figsize=(8, 8))
plt.subplot(2, 1, 1)
plt.plot(acc, label='Training Accuracy')
plt.plot(val_acc, label='Validation Accuracy')
plt.legend(loc='lower right')
plt.ylabel('Accuracy')
plt.ylim([min(plt.ylim()),1])
plt.title('Training and Validation Accuracy')
# 損失関数
plt.subplot(2, 1, 2)
plt.plot(loss, label='Training Loss')
plt.plot(val_loss, label='Validation Loss')
plt.legend(loc='upper right')
plt.ylabel('Cross Entropy')
plt.ylim([0, 10.0])
plt.title('Training and Validation Loss')
plt.xlabel('epoch')
plt.show()

ここまでコードを実行すると上記のようなグラフが出てきます。
上のグラフが学習エポックごとのAccuracyです。
グラフの意味が分かる方は、適宜ハイパーパラメータの再設定や画像の見直しなどで精度を上げてみてください。
------------------------------------------------------------
# 3.コンフュージョンマトリクスの表示
# ------------------------------------------------------------
from sklearn.metrics import confusion_matrix
import itertools
def plot_confusion_matrix(cm, classes,
normalize=False,
title='Confusion matrix',
cmap=plt.cm.Blues):
"""
This function prints and plots the confusion matrix.
Normalization can be applied by setting `normalize=True`.
"""
if normalize:
cm = cm.astype('float') / cm.sum(axis=1)[:, np.newaxis]
print("Normalized confusion matrix")
else:
print('Confusion matrix, without normalization')
print(cm)
plt.imshow(cm, interpolation='nearest', cmap=cmap)
plt.title(title)
plt.colorbar()
tick_marks = np.arange(len(classes))
plt.xticks(tick_marks, classes, rotation=45)
plt.yticks(tick_marks, classes)
fmt = '.2f' if normalize else 'd'
thresh = cm.max() / 2.
for i, j in itertools.product(range(cm.shape[0]), range(cm.shape[1])):
plt.text(j, i, format(cm[i, j], fmt),
horizontalalignment="center",
color="white" if cm[i, j] > thresh else "black")
plt.tight_layout()
plt.ylabel('True label')
plt.xlabel('Predicted label')
pred_y = transfer_learning_model.predict(img_X_valid)
pred_y_classes = np.argmax(pred_y,axis = 1)
confusion_mtx = confusion_matrix(img_Y_valid,pred_y_classes)
plot_confusion_matrix(confusion_mtx, classes = range(2))

ここまで実行で上記のような混合行列が生成されます。
True labelは実際のラベルでPredict labelがAIが予測した結果です。
上記だと、実際のラベルが0のもの203件中170件を正確に予測できたという感じです。
from sklearn.metrics import classification_report
print(classification_report(img_tY, pred_y_classes))

上記コードの実行で各種スコアの表示ができます。
今回は学習用のデータとヴァリデーション用へのデータ分割しかしてません。
どこかに発表する際はテストデータも用意するとよいと思います。
また、コードの詳細に関してはのちに解説しようと思います。
コメント