VGG16で画像分類(2クラス)


はじめに

 今回の記事は今までとはちょっと違ってプログラミングにある程度慣れた方たちを対象に書いてみました。
 今回のテーマは2クラスの画像分類です。僕はもちろんのこと、おそらく興味を持っている人はかなり多い分野だと思います。それではやっていきましょう!

筆者の開発環境

  • macOS Mojave バージョン10.14.3
  • MacBook Air(11-inch, Early 2015)
  • プロセッサ 1.6 GHz Intel Core i5
  • Python 3.7.1
  • Keras 2.2.4

これで問題なくできました!

VGG16について

この記事のタグにもあるVGG16が何か皆さんご存知でしょうか?
VGG16とは2014年のILSVRC(ImageNet Large Scale Visual Recognition Challenge)で提案された畳み込み13層とフル結合3層の計16層から成る畳み込みニューラルネットワークのことであり、膨大な量の画像で学習がなされている学習済みモデルのことであり、分類の精度がとてつもなく高いんです!
自作のKeras modelを使うのも勉強になって良いことなのですが、どうしても精度には限界があります。なので今回はVGG16でファインチューニングをして、自前のデータセットでも高精度の分類ができるような仕上がりになっています。

まず準備すること

GPUが入っているパソコンを使われている方は大丈夫なのですが、入っていない方はGoogle Colaboratoryを使いましょう!今回の作業はとてつもく思い作業なのでとてもじゃないけどCPUじゃ耐えられません。。。
Googleアカウントをお持ちの方はGoogle Driveにログインしたら以下のような画面になります。

この画面で左上の新規というボタンをクリックして その他→アプリの追加という順に進みます。

この画面に移動したら右上の検索バーに「Colab」と打ち込むとGoogle Colaboratoryが表示されるので、追加ボタンをクリック!
これであなたのGoogle DriveでもColaboratoryが使えるようになりました。

今回必要なファイル

さて、Google Colaboratoryを追加した後は、Google Driveに必要なファイルをアップロードしていきます。
今回必要なのは分類したい画像ファイルです。僕の場合はライオンとヒョウを使って分類したので、ファイル構造はこんな感じです。

Animal
├─train
│ ├─lion 240 files
│ └─leopard 240 files
└─test
├─lion 60 files
└─leopard 60 files

今回は学習用画像と評価用画像を4:1にしています。
この辺りは自分で使いたい画像を好きに選んでください。画像のサイズは後で調整できるので、なんでも大丈夫ですよ!

このような内容の画像ファイルをGoogle Driveにアップロードしたら、Google Colaboratoryに移動していよいよ実行に移りましょう。

それでは実践

Google Colaboratoryを開いた皆さんのパソコン画面はこんな状態になっていると思います。
左端に再生ボタンのようなものが書いてあるバーはコードセルといって、これからみなさんがコードを打ち込んでいくバーになります。

まずランタイム→ランタイムのタイプを変更の順でクリックすると

こんな画面が出てくるので、ハードウェアアクセラレータをGPUに変更して保存をクリック!これで無料で処理速度の速いGPU環境が使えます。プログラミングをやるとなれば何回も使うものなのでこの機会に覚えておきましょう。

これが済んだらGoogle Driveのマウントを行います。先ほども述べたコードセルに次のようなコードを打ち込みます。


from google.colab import drive
drive.mount("/content/gdrive") 

これをshift + enter(もしくは左端の再生ボタン的なもの)で実行すると下にurlが表示されるので、それをクリックして自分のグーグルアカウントを選び表示されるサクセスコードを「Enter your authorization code」の部分にコピペしたらOKです。

続いて、次のコードセルに


import os
os.chdir("/content/gdrive/My Drive")

と入力して実行します。これでGoogle Drive上のフォルダを使って作業ができるようになりました。

そして次は


import numpy as np

from keras.preprocessing.image import load_img, img_to_array
from keras.applications.vgg16 import VGG16
from keras.models import Sequential, Model
from keras.layers import Input, Dense, Dropout, Activation, Flatten
from keras.optimizers import SGD
from keras.utils import np_utils
from keras.preprocessing.image import ImageDataGenerator


# 分類クラス
classes = ['lion', 'leopard']
nb_classes = len(classes)
batch_size = 32
nb_epoch = 1

# 画像のサイズ
img_rows, img_cols = 224, 224

# モデルの構築
def build_model() :
    input_tensor = Input(shape=(img_rows, img_cols, 3))
    vgg16 = VGG16(include_top=False, weights='imagenet', input_tensor=input_tensor)

    _model = Sequential()

    _model.add(Flatten(input_shape=vgg16.output_shape[1:]))
    _model.add(Dense(256, activation='relu'))
    _model.add(Dropout(0.5))
    _model.add(Dense(nb_classes, activation='softmax'))

    model = Model(inputs=vgg16.input, outputs=_model(vgg16.output))
    for layer in model.layers[:15]:
        layer.trainable = False

    # 損失関数と評価関数を指定
    model.compile(loss='categorical_crossentropy',
                  optimizer=SGD(lr=1e-4, momentum=0.9), metrics=['accuracy'])
    return model

if __name__ == "__main__":

    train_datagen = ImageDataGenerator(
        rescale=None,
        rotation_range=15


    train_generator = train_datagen.flow_from_directory(
        directory= 'Animal/train',
        target_size=(img_rows, img_cols),
        color_mode='rgb',
        classes=classes,
        class_mode='categorical',
        batch_size=batch_size,
        shuffle=True)

    # 評価用画像の用意
    test_datagen = ImageDataGenerator(rescale=None)

    test_generator = test_datagen.flow_from_directory(
        directory= 'Animal/test',
        target_size=(img_rows, img_cols),
        color_mode='rgb',
        classes=classes,
        class_mode='categorical',
        batch_size=batch_size,
        shuffle=True)

    # インスタンスの呼び出し
    model = build_model()
    # model.fit() でモデルを学習
    model.fit_generator(
        train_generator,
        steps_per_epoch=3000, 
        epochs=nb_epoch, 
        validation_data=test_generator, 
        validation_steps=600 
    )

といったコードを打ち込んで実行します。
このような画面が出てきたら成功です!

accというのは正答率のことで、これが次第に大きくなっていけば学習が進んでいるということです。
このまま安心して終わるのを待ちましょう。

参考にさせてもらったサイト

終わりに

いかがだったでしょうか?
今回はライオンとヒョウの分類をしてみましたが、使う画像やファイルの名前を皆さんのお好みで変えて分類することは十分可能なので色々試してみてください!
画像さえ集めれば2クラス分類にとどまらず、3、4、5、、、と色んなクラスの分類ができますので面白いと思います。

次はこの記事の発展的な内容でXcodeを使ったiOSの画像分類アプリ作成について書こうと思うので、出来上がり次第皆さんに読んでいただけたら嬉しいです。
では、また次の記事で!