0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

TensorFlowで転移学習 InceptionV3モデル & Kaggle Cats & Dogs 編

Last updated at Posted at 2022-04-17

学習済 InceptionV3におけるTensorFlowによる転移学習 「Kaggle Cats & Dogs」編

はじめに

前回投稿したコードを変更して、学習済モデルInceptionV3の転移学習を行ってみました。

  • 「CIFAR-10」での確認結果はこちらに投稿を載せております。

条件

  • オープンデータ:Kaggle Cats & Dogs ※別のプログラムで前処理しております。
  • データ形状:150x150x3 ※Kerasの条件に75×75ピクセル以上と記載あり

結果

結果から先に申しますと精度抜群でした。
前回投稿したサンプルコードのTensorFlowのモデルでは犬猫分類は70%位の汎化性能でしたが、本転移学習の結果は90%超えの結果となりました。
学習の推移もきれいなグラフとなりました。

  • 前回投稿時のモデルの学習推移
    output1.png
  • InceptionV3を使った転移学習の学習推移
    output.png

コード詳細

詳細はコードにコメントを記載してありますので確認して下さい。
リンクからファイルとフォルダをダウンロードして下さい。

  • ファイル名:transfer_learning_catdog.ipynb
  • フォルダ:cat_dog_data inception_v3

※「アクセス権が必要です」と表示された場合はgoogleからログアウトして再度アクセスをして下さい。
https://drive.google.com/drive/folders/1SfD1fQdnfmcduJPqnsd82Ufx1EfmNH_R?usp=sharing

transfer_learning_catdog.ipynb
# %%
import tensorflow as tf
from tensorflow import keras
import numpy as np
import matplotlib.pyplot as plt
import random

# %%
#学習時の定数設定
batch_size = 256    #バッチサイズ
epochs = 15         #エポック数

# %% [markdown]
# #### kaggle dogs vs cats https://www.kaggle.com/c/dogs-vs-cats

# %%
#kaggle 犬猫 Dataset
x_train = np.load('./cat_dog_data/cat_dog_train_data.npy')
y_train = np.load('./cat_dog_data/cat_dog_train_label.npy')
x_data = np.load('./cat_dog_data/cat_dog_test_data.npy')
y_data = np.load('./cat_dog_data/cat_dog_test_label.npy')
IMG_HEIGHT = 150    #画像データ高さ
IMG_WIDTH = 150     #画像データ幅
CATEGORY = 2        #カテゴリ数2

# %% [markdown]
# #### 検証データとテストデータに分割

# %%
#検証データとテストデータに分割
x_val, x_test = np.split(x_data, [int(len(x_data) * 0.5)])
y_val, y_test = np.split(y_data, [int(len(y_data) * 0.5)])
#正規化
X_train = x_train / 255
X_val = x_val / 255
X_test = x_test / 255

# %% [markdown]
# #### データ形状確認 画像データ:(画像枚数、高さ、幅、色数)

# %%
#データ形状確認 画像データ:(枚数, 高さ, 幅, 色数)
print(X_train.shape)
print(X_val.shape)
print(X_test.shape)
print(y_train.shape)
print(y_val.shape)
print(y_test.shape)

# %% [markdown]
# #### 訓練データ、検証データ、テストデータをランダムに10枚プレビュー

# %%
#訓練データの画像をランダム表示
fig, ax = plt.subplots(1, 10, figsize=(10, 1))
for i in range(10):
    rnd = random.randint(0, X_train.shape[0])
    ax[i].set_axis_off()
    ax[i].set_title(y_train[rnd])
    ax[i].imshow(np.squeeze(X_train[rnd]))

# %%
#検証用データの画像をランダム表示
fig, ax = plt.subplots(1, 10, figsize=(10, 1))
for i in range(10):
    rnd = random.randint(0, X_val.shape[0])
    ax[i].set_axis_off()
    ax[i].set_title(y_val[rnd])
    ax[i].imshow(np.squeeze(X_val[rnd]))

# %%
#テスト用データの画像をランダム表示
fig, ax = plt.subplots(1, 10, figsize=(10, 1))
for i in range(10):
    rnd = random.randint(0, X_test.shape[0])
    ax[i].set_axis_off()
    ax[i].set_title(y_test[rnd])
    ax[i].imshow(np.squeeze(X_test[rnd]))

# %%
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Flatten, Conv2D, MaxPooling2D, BatchNormalization, Dropout
from tensorflow.keras import layers
from tensorflow.keras import Model
from tensorflow.keras.applications.inception_v3 import InceptionV3
from tensorflow.keras.optimizers import RMSprop

# %% [markdown]
# ## これより転移学習モデル生成
# ### 概要
# #### Inception V3 インスタンス作成
# * インスタンス作成
# * 学習済パラメーター読み込み
# * 学習済レイヤーのパラメータ更新のロック
# * Inception V3 モデルのどの層の後ろに独自の層を追加するか設定
# #### Inception V3 の指定の層の後ろに独自の層を追加
# * 独自の層を追加
# * モデルのハイパーパラメータ設定

# %% [markdown]
# 

# %% [markdown]
# #### InceptionV3のインスタンス作成  
# * 'include_top=False':InceptionV3モデルの出力部に独自の層を追加できる  
# * 'input_shape':入力のデータ形状を設定。'include_top=False'時に指定できる 
# * 'input_shape'は75×75以上でなければならない

# %%
# Inception_V3のインスタンスを作成し、学習済パラメータをセットする
weights_file = './inception_v3/inception_v3_weights_tf_dim_ordering_tf_kernels_notop.h5'
inception_v3_model = InceptionV3(input_shape = (150, 150, 3), include_top = False, weights = None) #Inception_V3に接続する層のinput_shapeは75x75ピクセル以上である事

# 学習済パラメーターを読み込む
inception_v3_model.load_weights(weights_file)

#Inceptio_V3の各層のパラメータは学習時更新させないようにロックする
for layer in inception_v3_model.layers:
  layer.trainable = False

# 本コードではInceptionV3の'mixed6'の後ろに独自の層を追加する事になる
end_layer = inception_v3_model.get_layer('mixed6').output

# %% [markdown]
# #### Inception V3 の指定の層の後ろに独自の層を追加

# %%
# 独自の層を追加
add_layer = layers.Flatten()(end_layer)
add_layer = layers.Dense(128, activation='relu')(add_layer)
add_layer = layers.Dense  (CATEGORY, activation='softmax')(add_layer)           
model = Model(inception_v3_model.input, add_layer) 

# ハイパーパラメータ設定
model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy']) 

# %% [markdown]
# #### 生成モデルインフォ

# %%
#生成モデルインフォ
model.summary()

# %% [markdown]
# #### コールバックの設定  https://keras.io/ja/callbacks/
# 内容:エポック毎に呼び出される。  
#    'checkpoint_best':'val_accuracy'を監視し一番精度の良かったエポック時の重みパラメーターを保存する  
#    'early_stopping':'val_accuracy'を監視し検証精度が停滞したら訓練を停止する

# %%
#コールバック
#checkpoint_best_path:バリデーション精度の最大時の重みデータを保存
#early_stoping:アーリーストッピング設定。バリデーション精度が停滞したら修了
from tensorflow.keras.callbacks import ModelCheckpoint, EarlyStopping
checkpoint_best_path = 'modelCNN_checkpoints_best/checkpoint'
checkpoint_best = ModelCheckpoint(filepath=checkpoint_best_path, save_weights_only=True, save_freq='epoch',
                                monitor='val_accuracy', save_best_only=True, verbose=1)
early_stopping = EarlyStopping(monitor='val_accuracy', patience=2)

# %%
# モデルフィット(学習)
callbacks = [checkpoint_best, early_stopping]
history = model.fit(X_train, y_train, epochs=epochs, validation_data=(X_val, y_val), batch_size=batch_size, callbacks=callbacks) 

# %%
#訓練ロス、訓練精度、検証ロス、検証精度の可視化
fig, ax = plt.subplots(1, 4, figsize=(20, 5))
ax[0].plot(history.history['loss'])
ax[0].set_title('loss vs. epochs')
ax[0].set_ylabel('loss')
ax[0].set_xlabel('Epoch')
ax[1].plot(history.history['accuracy'])
ax[1].set_title('accuracy vs. epochs')
ax[1].set_ylabel('accuracy')
ax[1].set_xlabel('Epoch')
ax[2].plot(history.history['val_loss'])
ax[2].set_title('val_loss vs. epochs')
ax[2].set_ylabel('val_loss')
ax[2].set_xlabel('Epoch')
ax[3].plot(history.history['val_accuracy'])
ax[3].set_title('val_accuracy vs. epochs')
ax[3].set_ylabel('val_accuracy')
ax[3].set_xlabel('Epoch')

# %% [markdown]
# #### コールバックで保存された検証精度(val_accuracy)最大時のパラメータを読み込む

# %%
model.load_weights('modelCNN_checkpoints_best/checkpoint')

# %% [markdown]
# #### テストデータで汎化性能確認

# %%
#テストデータでの精度確認
print("Evaluate on test data")
results = model.evaluate(X_test, y_test, verbose=0)#, batch_size=128)
print("test loss, test acc:", results)

0
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?