今回は「ファインチューニング -
KIKAGAKU」を学ぶ。
学習内容
- 画像分類/データセットの準備
- CNN モデルの定義/目的関数と最適化手法の選択/モデルの学習/
- ファインチューニング/全結合層を追加/モデルの学習/予測精度の評価
学習させるのに5日間を要した。(PCを使用している間のみ、バックグラウンドで学習。)
ソースコード
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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() |
出力結果
出力ログ
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[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 | |