キカガク(KIKAGAKU)で「ファインチューニング」を学ぶ

Photo by Owen Beard on Unsplash

今回は「ファインチューニング - KIKAGAKU」を学ぶ。

学習内容

  1. 画像分類/データセットの準備
  2. CNN モデルの定義/目的関数と最適化手法の選択/モデルの学習/
  3. ファインチューニング/全結合層を追加/モデルの学習/予測精度の評価

学習させるのに5日間を要した。(PCを使用している間のみ、バックグラウンドで学習。)


ソースコード

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import cv2
import tensorflow as tf
# GPU が使用可能であることを確認
from tensorflow.python.client import device_lib
print(device_lib.list_local_devices())
# データセットの読み込み
train, test = tf.keras.datasets.cifar10.load_data()
# 画像の情報
print("画像情報:",train[0].shape, test[0].shape)
# ラベルの情報
print("ラベル情報:",train[1].shape, test[1].shape)
# 学習用データセットとテスト用データセットに対して正規化
x_train = train[0] / 255
x_test = test[0] / 255
# 目標値の切り分け
t_train = train[1]
t_test = test[1]
# 32bit にキャスト
x_train, x_test = x_train.astype('float32'), x_test.astype('float32')
t_train, t_test = t_train.astype('int32'), t_test.astype('int32')
# CNN モデルの定義
import os, random
def reset_seed(seed=0):
os.environ['PYTHONHASHSEED'] = '0'
random.seed(seed)
np.random.seed(seed)
tf.random.set_seed(seed)
from tensorflow.keras import models,layers
# シードの固定
reset_seed(0)
# モデルの構築
model = models.Sequential([
# 特徴量抽出
layers.Conv2D(filters=3, kernel_size=(3, 3), activation='relu', input_shape=(32, 32, 3)),
layers.MaxPool2D(pool_size=(2, 2)),
# ベクトル化
layers.Flatten(),
# 識別
layers.Dense(100, activation='relu'),
layers.Dense(10, activation='softmax')
])
# パラメータ確認
print("パラメータ確認:",model.summary())
# optimizerの設定
optimizer = tf.keras.optimizers.Adam(lr=0.01)
# モデルのコンパイル
model.compile(optimizer=optimizer,
loss='sparse_categorical_crossentropy',
metrics=['accuracy'])
# モデルの学習
batch_size = 4096
epochs = 30
# 学習の実行
history = model.fit(x_train, t_train,
batch_size=batch_size,
epochs=epochs,
validation_data=(x_test, t_test))
# ファインチューニング
from tensorflow.keras.applications import resnet, VGG16
# 学習済みモデルをインスタンス化
base_model = VGG16(input_shape=(224, 224, 3),
include_top=False, weights='imagenet')
# パラメータ確認
print("パラメータ確認:",base_model.summary())
# データセットの準備
# ランダムにデータを取得する
train_choice = np.random.randint(low=0, high=50000, size=10000)
test_choice = np.random.randint(low=0, high=10000, size=5000)
# データの準備
x_train = train[0][train_choice]
x_test = test[0][test_choice]
t_train = train[1][train_choice].astype('int32')
t_test = test[1][test_choice].astype('int32')
_train, _test = [], []
# 画像サイズを 224 × 224 にリサイズしてリストに格納
for img in x_train:
_train.append(cv2.resize(src=img, dsize=(224, 224)))
for img in x_test:
_test.append(cv2.resize(src=img, dsize=(224, 224)))
# リストから ndarray に変換し、正規化
x_train = np.array(_train, dtype='float32') / 255.0
x_test = np.array(_test, dtype='float32') / 255.0
print("サイズの確認:",x_train.shape, x_test.shape)
# 全結合層の追加
reset_seed(0)
# モデルの定義
finetuned_model = models.Sequential([
base_model,
layers.GlobalAveragePooling2D(),
layers.Dense(512, activation='relu'),
layers.Dense(10, activation='softmax')
])
# 目的関数と最適化手法の選択
optimizer = tf.keras.optimizers.SGD(lr=0.01)
# モデルのコンパイル
finetuned_model.compile(optimizer=optimizer,
loss='sparse_categorical_crossentropy',
metrics=['accuracy'])
# ファインチューニング モデルの確認
print("パラメータ確認:",finetuned_model.summary())
# モデルの学習
# 順伝播(比較のため)
loss, accuracy = finetuned_model.evaluate(x_test, t_test)
# 正解率
print(f'loss : {loss}, acuracy : {accuracy}')
# モデルの学習
history = finetuned_model.fit(x_train, t_train,
epochs=10,
batch_size=32,
validation_data=(x_test, t_test))
# 予測精度の評価
results = pd.DataFrame(history.history)
results.tail(3)
# 損失を可視化
results[['loss', 'val_loss']].plot(title='loss')
plt.xlabel('epochs')
plt.show()
# 正解率を可視化
results[['accuracy', 'val_accuracy']].plot(title='accuracy')
plt.xlabel('epochs')
plt.show()

出力結果



出力ログ

[name: "/device:CPU:0"
device_type: "CPU"
memory_limit: 268435456
locality {
}
incarnation: 5422697336045806387
]
2020-06-01 13:45:54.033667: I tensorflow/core/platform/cpu_feature_guard.cc:142] Your CPU supports instructions that this TensorFlow binary was not compiled to use: AVX2
画像情報: (50000, 32, 32, 3) (10000, 32, 32, 3)
ラベル情報: (50000, 1) (10000, 1)
Model: "sequential"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
conv2d (Conv2D) (None, 30, 30, 3) 84
_________________________________________________________________
max_pooling2d (MaxPooling2D) (None, 15, 15, 3) 0
_________________________________________________________________
flatten (Flatten) (None, 675) 0
_________________________________________________________________
dense (Dense) (None, 100) 67600
_________________________________________________________________
dense_1 (Dense) (None, 10) 1010
=================================================================
Total params: 68,694
Trainable params: 68,694
Non-trainable params: 0
_________________________________________________________________
パラメータ確認: None
Train on 50000 samples, validate on 10000 samples
Epoch 1/30
4096/50000 [=>............................] - ETA: 14s - loss: 2.3118 - accuracy: 0.1062
8192/50000 [===>..........................] - ETA: 10s - loss: 2.3346 - accuracy: 0.1068
12288/50000 [======>.......................] - ETA: 8s - loss: 2.2974 - accuracy: 0.1268
16384/50000 [========>.....................] - ETA: 6s - loss: 2.2829 - accuracy: 0.1295
20480/50000 [===========>..................] - ETA: 5s - loss: 2.2618 - accuracy: 0.1448
24576/50000 [=============>................] - ETA: 4s - loss: 2.2438 - accuracy: 0.1610
28672/50000 [================>.............] - ETA: 3s - loss: 2.2292 - accuracy: 0.1661
32768/50000 [==================>...........] - ETA: 3s - loss: 2.2130 - accuracy: 0.1773
36864/50000 [=====================>........] - ETA: 2s - loss: 2.1967 - accuracy: 0.1911
40960/50000 [=======================>......] - ETA: 1s - loss: 2.1832 - accuracy: 0.2026
45056/50000 [==========================>...] - ETA: 0s - loss: 2.1667 - accuracy: 0.2116
49152/50000 [============================>.] - ETA: 0s - loss: 2.1497 - accuracy: 0.2197
50000/50000 [==============================] - 9s 181us/sample - loss: 2.1462 - accuracy: 0.2209 - val_loss: 1.9381 - val_accuracy: 0.3203
<省略>
Epoch 30/30
4096/50000 [=>............................] - ETA: 8s - loss: 0.9545 - accuracy: 0.6646
8192/50000 [===>..........................] - ETA: 7s - loss: 0.9619 - accuracy: 0.6646
12288/50000 [======>.......................] - ETA: 6s - loss: 0.9575 - accuracy: 0.6654
16384/50000 [========>.....................] - ETA: 5s - loss: 0.9641 - accuracy: 0.6627
20480/50000 [===========>..................] - ETA: 4s - loss: 0.9698 - accuracy: 0.6602
24576/50000 [=============>................] - ETA: 4s - loss: 0.9693 - accuracy: 0.6608
28672/50000 [================>.............] - ETA: 3s - loss: 0.9739 - accuracy: 0.6591
32768/50000 [==================>...........] - ETA: 2s - loss: 0.9754 - accuracy: 0.6598
36864/50000 [=====================>........] - ETA: 2s - loss: 0.9765 - accuracy: 0.6598
40960/50000 [=======================>......] - ETA: 1s - loss: 0.9758 - accuracy: 0.6596
45056/50000 [==========================>...] - ETA: 0s - loss: 0.9786 - accuracy: 0.6584
49152/50000 [============================>.] - ETA: 0s - loss: 0.9805 - accuracy: 0.6568
50000/50000 [==============================] - 9s 171us/sample - loss: 0.9810 - accuracy: 0.6566 - val_loss: 1.4533 - val_accuracy: 0.5144
Model: "vgg16"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
input_1 (InputLayer) [(None, 224, 224, 3)] 0
_________________________________________________________________
block1_conv1 (Conv2D) (None, 224, 224, 64) 1792
_________________________________________________________________
block1_conv2 (Conv2D) (None, 224, 224, 64) 36928
_________________________________________________________________
block1_pool (MaxPooling2D) (None, 112, 112, 64) 0
_________________________________________________________________
block2_conv1 (Conv2D) (None, 112, 112, 128) 73856
_________________________________________________________________
block2_conv2 (Conv2D) (None, 112, 112, 128) 147584
_________________________________________________________________
block2_pool (MaxPooling2D) (None, 56, 56, 128) 0
_________________________________________________________________
block3_conv1 (Conv2D) (None, 56, 56, 256) 295168
_________________________________________________________________
block3_conv2 (Conv2D) (None, 56, 56, 256) 590080
_________________________________________________________________
block3_conv3 (Conv2D) (None, 56, 56, 256) 590080
_________________________________________________________________
block3_pool (MaxPooling2D) (None, 28, 28, 256) 0
_________________________________________________________________
block4_conv1 (Conv2D) (None, 28, 28, 512) 1180160
_________________________________________________________________
block4_conv2 (Conv2D) (None, 28, 28, 512) 2359808
_________________________________________________________________
block4_conv3 (Conv2D) (None, 28, 28, 512) 2359808
_________________________________________________________________
block4_pool (MaxPooling2D) (None, 14, 14, 512) 0
_________________________________________________________________
block5_conv1 (Conv2D) (None, 14, 14, 512) 2359808
_________________________________________________________________
block5_conv2 (Conv2D) (None, 14, 14, 512) 2359808
_________________________________________________________________
block5_conv3 (Conv2D) (None, 14, 14, 512) 2359808
_________________________________________________________________
block5_pool (MaxPooling2D) (None, 7, 7, 512) 0
=================================================================
Total params: 14,714,688
Trainable params: 14,714,688
Non-trainable params: 0
_________________________________________________________________
パラメータ確認: None
サイズの確認: (10000, 224, 224, 3) (5000, 224, 224, 3)
Model: "sequential_1"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
vgg16 (Model) (None, 7, 7, 512) 14714688
_________________________________________________________________
global_average_pooling2d (Gl (None, 512) 0
_________________________________________________________________
dense_2 (Dense) (None, 512) 262656
_________________________________________________________________
dense_3 (Dense) (None, 10) 5130
=================================================================
Total params: 14,982,474
Trainable params: 14,982,474
Non-trainable params: 0
_________________________________________________________________
パラメータ確認: None
<省略>
loss : 2.444868545150757, acuracy : 0.09120000153779984
Train on 10000 samples, validate on 5000 samples
Epoch 1/10
<省略>
9920/10000 [============================>.] - ETA: 1:10 - loss: 0.2278 - accuracy: 0.9276
9952/10000 [============================>.] - ETA: 42s - loss: 0.2279 - accuracy: 0.9276
9984/10000 [============================>.] - ETA: 14s - loss: 0.2281 - accuracy: 0.9274
10000/10000 [==============================] - 10428s 1s/sample - loss: 0.2278 - accuracy: 0.9275 - val_loss: 0.4037 - val_accuracy: 0.8640

Posted in  on 6/02/2020 by rteak |