LoginSignup
1
2

More than 3 years have passed since last update.

学習済モデルを利用しないで作るKerasを用いたVGG16の実装

Last updated at Posted at 2020-05-06

この記事を読者層について

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])

参考文献

直感DeepLearning

1
2
1

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
1
2