KerasでCNNを構築しCIFAR-10の画像分類をしてみよう

みなさん,こんにちは。
シンノユウキ(shinno1993)です。

今回は機械学習やディープラーニングに用いられるライブラリ:Kerasを用いて,CNNを構築し,データ・セット:CIFAR-10の画像を認識・分類してみたいと思います.

以前の記事では,KerasとMNISTを用いて画像認識・分類しましたが,今回はそれの後継となるような記事です.以前の記事をご覧頂いた上で本記事をご覧いただくと良いかと思います.

【Python】Keras / MNISTを用いて画像認識に入門してみる【初学者向け】
今回は画像認識入門ということで,Pythonのニュートラルネットワークライブラリ:Kerasと手書き数字のデータ・セット:MNISTを用いて,画像認識に入門してみます.非エンジニアが機械学習の深い部分を理解せずとも,道具として機械学習を利用...

ではいきましょう!

まずは準備から

開発環境は「Google Colab」を利用

以前の記事と同様,開発環境にはGoogle Colabを用います.まだ環境を用意されていないという方は,以下の記事を参照してください.

機械学習を体験してみたいなら無料で使える「Google Colab」がオススメ
機械学習,ひいてはディープラーニングを体験してみたい!と思ったときの障壁の1つが環境構築です.これらには様々なライブラリを活用することになるでしょうし,また一般的なノートブック程度のスペックでは処理に何時間もかかってしまいます.といっても,...

 

データ・セット:CIFAR-10とは?

今回はデータ・セットとしてCIFAR-10を用います.このデータ・セットには60000個の画像が含まれており,50000個がトレーニング用,10000個がテスト用です.以下の10種類に分けられる画像が用意されています:

  • 飛行機
  • 自動車
  • 鹿
  • カエル
  • うま
  • トラック

この中に自動車とトラックがありますが,この2つに重なりはありません.つまり,トラックと分類された画像は自動車には含まれず,自動車と分類された画像はトラックに含まれません.この2つを完全に分類することも目指しています.

 

データをインポートしよう!

dltからデータ・セットをインポート

まずはデータ・セットをインポートしましょう.

import dlt
data = dlt.cifar.load_cifar10()

x_train = data.train_images 
y_train = data.train_labels
x_test = data.train_images
y_test =data.train_images

1行目でパッケージをインストールし,2行目でデータをロードしています.4行目以降は読み込んだデータをテストデータとトレーニング用データにそれぞれ代入しています.

dltはディープラーニングを学習する際に役立つパッケージのことです.「Deep Learning Tools」から名付けられています.これを使用することで,ディープラーニングの過程や結果を可視化させることができます.詳しくは以下の記事をご覧ください.

404 Not Found - Qiita - Qiita

 

インポートした画像を表示してみよう

これで,データ・セットをインポートすることができました.では,インポートした画像を表示してみましょう.以下のコードを実行してみてください.

plt.imshow(x_train[0])

これは,x_trainの最初の画像を表示するコードです.以下のような画像が表示されましたでしょうか.

画像が非常に粗い(32×32ピクセル)ですが,カエルでしょうか.とりあえず,無事に画像をインポートできていたことが確認できました!

 

データを準備しよう!

データを正規化しよう

次に行うのはデータの前処理です.その前に,この画像のデータ構造について確認しておきましょう.以下のコードを実行してみてください.

print(x_train[0])

すると,以下のような配列が返されたかと思います.

[[[ 59  62  63]
  [ 43  46  45]
  [ 50  48  43]
  ...

この配列は32×32で構成されており,それぞれにRGB値が入力されています.このRGB値の特徴から,それぞれの画像を識別していきます.

まずは,このRGB値を正規化しましょう.データを0~1までの範囲に収まるように変換します.RGB値は0~255までの範囲を持ちますので,255で割ってやることで簡単に実装できます.

x_train = x_train.astype('float32') / 255
x_test = x_test.astype('float32') / 255

 

one-hotベクトルに変換しよう

次は正解用のラベルをone-hotベクトルと呼ばれる形に変換しましょう.今回の正解用ラベルは数字で入力されており,それぞれの数字に対応するラベルが予め定められています.たとえば,先ほど表示させたx_train[0]はカエルの画像で,y_train[0]は6と入力されていました.つまり,y_trainではfrogと入力する代わりに,機械でも扱いやすい数字として正解用のラベルを入力していたのですね.

しかし,まだこの形式では機械学習には適していません.処理をしやすくするために,たとえばfrog:6の場合は以下のようなone-hotベクトルに変換する必要があります.

 0,1,2,3,4,5,6,7,8,9
[0,0,0,0,0,0,1,0,0,0]

数字の6に該当する部分だけ1が入力された状態ですね.このような配列のことをone-hotベクトルといいます.

では実際に変換してみましょう.以下のコードを実行することで変換することができます.

from keras.utils.np_utils import to_categorical
y_train = to_categorical(y_train, 10)
y_test = to_categorical(y_test, 10)

kerasのto_categorical()を使用することで,one-hotベクトルに変換することができます.引数には変換するベクトルと,それに含まれる要素数を指定します.

 

モデルを構築しよう!

では,モデルを構築していきましょう.以下のコードを入力してください.

from keras.models import Sequential
from keras.layers import Dense, Dropout, Activation, Conv2D, MaxPooling2D, Flatten
from keras.optimizers import Adam

model = Sequential()

# 1層目
model.add(Conv2D(32, kernel_size=(3, 3), activation='relu' padding='same', input_shape=(32,32,3)))
model.add(Conv2D(32, kernel_size-(3, 3), activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))

# 2層目
model.add(Conv2D(64, kernel_size=(3, 3), activation='relu' padding='same'))
model.add(Conv2D(64, kernel_size=(3, 3), activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))

# 出力層
model.add(Flatten())
model.add(Dense(512))
model.add(Activation('relu'))
model.add(Dropout(0.5))
model.add(Dense(10))
model.add(Activation('softmax'))

 

では,コードを少し解説していきます.詳細な説明は割愛し,各所でどのようなことをしているのかを

1-3行目ではモデル構築に必要なライブラリなどをインポートしています.

5行目ではSequentialモデル(機械学習におけるシンプルで一般的なモデル)のインスタンスを作成しています.

8-11行目ではCNNにおける1層目のレイヤーを追加しています.Conv2D()では2次元の畳み込みレイヤーを追加し,MaxPooling2D() でプーリングを行うための層を追加しています.Dropoutでは過学習を防ぐための処理を行っています.

14-17行目では1層目のデータを処理するための層を追加しています.

20-25行目は出力層です.活性化関数にsoftmax関数を使用しているのがポイントです.これを使用することで10の出力それぞれの合計を1にすることができるので,一致度を確率的に表現することができます.

これでモデルが構築できました!

 

モデルに学習させよう!

では,今回作成したモデルに学習させましょう.以下のコードを実行してください.

model.compile(
loss='categorical_crossentropy', 
optimizer=Adam(lr=0.001), 
metrics=['accuracy'])
fit = model.fit(x_train, y_train,
              batch_size=128,
              epochs=10,
              verbose=1,
              validation_split=0.1
                )

この中で,batch_sizeは1度の学習で取り出して学習させる画像の数を表し,epochsでは学習の回数を表しています.恣意的に決めていますので増減しても構いません.ただし,epochsは少なすぎても精度が下がりますし,多すぎても時間がかかったり,過学習の問題があったりしますので注意してください.

これでモデルをコンパイルし,トレーニング用の画像と正解用のラベルを学習させることができました.

 

モデルを評価してみよう!

次に,学習させたモデルで,どの程度正確に判断できているか,テスト用の画像とラベルで評価しましょう.以下のコードを実行しましょう.

score = model.evaluate(x_test, y_test,verbose=0)
print('Test score:', score[0])
print('Test accuracy:', score[1])

以下のような結果が表示されたでしょうか.

Test score: 0.6903812148571015
Test accuracy: 0.7649

およそ76%の精度で,テストデータを正しい画像と識別する事ができています.

 

まとめ

今回はKerasを用いて簡単にですが,CNNを実装してみました.使ってみるということを優先しているため,ところどころ説明が不十分かもです.が,まず使ってみることで,理論的な知識も理解しやすくなるのではと考えています.

今度,私の勉強的な意味合いを込めて,CNNに関する基本的な知識を理解するための記事を公開してみる予定です.ご興味のある方は少しお待ち下さい.

タイトルとURLをコピーしました