この記事を読者層について
DeepLearningの畳み込みニューラルネットワーク(以下CNN)の基礎知識があり、以下のような言葉の意味がわかる方
例)
- 畳み込み
- MaxPooling
- フィルター
VGG16とは
画像を解析するDeepLearningの手法の一つです。
2014年に発表されたモデルで、現在でも使われるほど、性能が高いモデルです。
学習済のモデルもKerasから呼び出して利用する事もできます。
オリジナルの記事はこちらです。
VGG16を作成するにあたり以下が重要になります。
- 畳み込みに使うフィルターのサイズは3×3
- 複数回の畳み込みを行った際にMaxPoolingを行う。
- MaxPoolingの後にフィルターのチャンネル数を倍にする。
動作環境
GoogleColaboratory
サンプルプログラム
# 必要なライブラリーのインストール
import tensorflow.keras as keras
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Conv2D
from tensorflow.keras.layers import MaxPooling2D
from tensorflow.keras.layers import Flatten
from tensorflow.keras.layers import Dense
from tensorflow.keras.datasets import cifar10
# CIFAR10のデータを取得して、ベクトルに変換するクラス
class CIFAR10Dataset():
def __init__(self):
self.image_shape = (32, 32, 3)
self.num_classes = 10
# 学習データとテストデータを取得する。
def get_batch(self):
(x_train, y_train), (x_test, y_test) = cifar10.load_data()
x_train, x_test = [self.change_vec(img_data) for img_data in [x_train, x_test]]
y_train, y_test = [self.change_vec(img_data, label_data=True) for img_data in [y_train, y_test]]
return x_train, y_train, x_test, y_test
# 目的変数の場合は、クラスベクトルに変更する。説明変数は標準化する。
def change_vec(self, img_data, label=False):
if label:
data = keras.utils.to_categorical(img_data, self.num_classes)
else:
img_data = img_data.astype("float32")
img_data /= 255
shape = (img_data.shape[0],) + self.image_shape
img_data = img_data.reshape(shape)
return img_data
# ディープラーニングのモデルを設定して返す関数
def network(input_shape, num_classes):
model = Sequential()
model.add(Conv2D(32, kernel_size=3, padding="same", input_shape=input_shape, activation="relu"))
model.add(Conv2D(32, kernel_size=3, padding="same", activation="relu"))
model.add(MaxPooling2D())
model.add(Conv2D(64, kernel_size=3, padding="same", activation="relu"))
model.add(Conv2D(64, kernel_size=3, padding="same", activation="relu"))
model.add(MaxPooling2D())
model.add(Conv2D(128, kernel_size=3, padding="same", activation="relu"))
model.add(Conv2D(128, kernel_size=3, padding="same", activation="relu"))
model.add(Conv2D(128, kernel_size=3, padding="same", activation="relu"))
model.add(MaxPooling2D())
model.add(Flatten())
model.add(Dense(1024, activation="relu"))
model.add(Dense(1024, activation="relu"))
model.add(Dense(num_classes, activation="softmax"))
print(model.summary())
return model
# モデルを学習させるクラス
class Trainer():
# モデルをコンパイルして、学習するための設定をプライベートプロパティに設定する。
def __init__(self, model, loss, optimizer):
self._model = model
self._model.compile(
loss=loss,
optimizer=optimizer,
metrics=["accuracy"]
)
self._verbose = 1
self._batch_size = 128
self._epochs = 30
# 実際の学習
def fit(self, x_train, y_train, x_test, y_test):
self._model.fit(
x_train,
y_train,
batch_size=self._batch_size,
epochs=self._epochs,
verbose=self._verbose,
validation_data=(x_test, y_test)
)
return self._model
dataset = CIFAR10Dataset() # データを取得するためのCIFAR10Datasetのインスタンス化
model = network(dataset.image_shape, dataset.num_classes) #モデルの取得
x_train, y_train, x_test, y_test = dataset.get_batch() # 学習データとテストデータの取得
trainer = Trainer(model, loss="categorical_crossentropy", optimizer="adam") # モデルとロス関数、最適化アルゴリズムを引数にして、Trainerのインスタンス化
model = trainer.fit(x_train, y_train, x_test, y_test) # モデルの学習
# モデルの評価
score = model.evaluate(x_test, y_test, verbose=0)
print('Test loss: ', score[0])
print('Test accuracy: ', score[1])