PythonライブラリKerasによる深層学習(ディープラーニング)。手書き文字画像分類とモデル評価

python活用 python

深層学習(ディープラーニング)手法を用いて画像認識してみたいです。

このような要望にお応えします。

今回は画像認識タスクの一つである画像分類を深層学習手法を用いて行います。
また、PythonライブラリKerasを利用します。
Kerasは、ニューラルネットワークモデルの構築をサポートしてくれます。このライブラリを使用して、画像分類のモデル構築と評価を行います。

画像分類に使用するデータは、画像認識のサンプルデータとして頻繁に使用されるMNIST手書き文字画像データセットを使用します。

画像分類のモデルは、NN(Neural Network)、CNN(Convolutional Neural Network)を使用します。

実行環境は、Pythonの開発環境のひとつAnacondaをベースとしてjupyter notebookを利用しました。
Anacondaの環境構築については、下記の記事にまとめています。

今回使用するライブラリのバージョンは以下になります。

  • python 3.7
  • tensorflow 1.7.0
  • Keras 2.2.2

画像認識をはじめていきます。手順は、大きく以下のようになります。

  • 画像データの準備
  • モデルの定義
  • モデルの学習/評価
  • 画像分類結果出力

画像データの準備

各手書き数字画像は、28*28ピクセル(=784ピクセル)で構成されています。
学習データには60000個の画像が用意され、検証用データには10000個の画像を使用することができます。 そして、0~9までの10クラスがあり、これらのクラスに正しく分類できるようにモデルの学習を行います。

画像データの各ピクセル値は0~255のグレースケールです。そのため、入力値が0~1の範囲となるように正規化を実施します。各値の最大値が255ですので、255で除算することにより正規化します。

今回の問題は、画像が0~9の整数のうち、どれに相当するのかを学習するマルチクラス分類の問題になりますので、学習時に必要となる0~9のクラスを示すベクトルを用意することになります。

それでは、データの準備をしてみます。まず、学習用データと検証用データに分けて、画像データをx_train, y_train, x_test, y_testに読み出します。

MNISTの手書き数字画像以外の自前の画像データを使用したい場合は、Image, cv2等のライブラリを用いて、各画像を読み込んでベクトル化するといいと思います。

これでデータの準備は完了です。

モデルの定義

次は学習モデルを定義していきます。
NN, CNNのモデルを定義します。

まずは、NNを定義します。
入力層を784(画像ベクトル表現の次元数)、中間層ユニット数64、活性化関数としてrelu、出力層のユニット数を10としてsoftmax関数を使用します。

次にCNNを定義します。
CNNでは、畳み込み層と多層ニューラルネットワークを組み合わせたモデルを構築します。

ざっくりとCNNのモデル構築について整理します。
畳み込み層を用いて、分類に役立つ特徴的な箇所を抽出し、分類に役立たない箇所を除去するような特徴量を獲得したうえで、これを多層ニューラルネットワークの入力として使用します。

畳み込み層は、Conv2D, MaxPooling2Dを用いて構築します。

Conv2D(32, (3, 3), activation=’relu’, input_shape=(28, 28, 1))では、入力画像のサイズを指定し、フィルタ数32、フィルタサイズ3*3を指定しています。この処理により、サイズ26(=28-2)*26(=28-2)の特徴マップが32個作成されます。
MaxPooling2D((2, 2))では、ダウンサンプリングを行い、サイズ13*13の特徴マップが32個作成されます。

Conv2D(64, (3, 3), activation=’relu’)では、サイズ11(=13-2)*11(=13-2)の特徴マップが64個作成されます。 MaxPooling2D((2, 2))では、ダウンサンプリングを行い、サイズ5*5の特徴マップが64個作成されます。

Conv2D(64, (3, 3), activation=’relu’)では、サイズ3(=5-2)*3(=5-2)の特徴マップが64個作成されます。
このように、ネットワークが深くなるに従い、データのサイズが縮小する傾向にあります。

畳み込み層の構造は、summary()を用いることで確認することができます。

このような畳み込み層から得られた特徴ベクトルを多層ニューラルネットワークに入力します。ニューラルネットワークの入力はベクトルですので、画像をベクトルデータになるように変換します。
そのために、Conv2D(64, (3, 3), activation=’relu’)で獲得した特徴量は(3, 3, 64)の3次元ですので、
これをFlatten()を用いて入力できるようにベクトルに変換します。
次にshape(3, 3, 64)を一つ以上のDenseレイヤーを用意して分類を実行します。

MNISTは10クラスですので、Denseレイヤーの出力を10にし、softmax関数を指定します。

これでCNNのモデル定義は完了です。

モデルの学習/評価

モデルを学習し、検証用データでモデルを評価してみます。

NNの学習/モデル評価

CNNの学習/モデル評価

画像分類結果

画像分類の結果は、以下のようになりました。
NN, CNNでの分類結果を載せます。

画像下に出力したラベルの色が青の場合、正解データと予測値が一致し、赤色の場合は、一致しないように出力しています。

[NNモデルによる画像分類結果]

[CNNモデルによる画像分類結果]

30枚の画像を取り出して表示してみました。4行1列目の画像の分類を誤っているみたいです。正解は3ですが、8と予測したみたいです。8にも見えるような気がします。。。

ソースコード全体を載せます。

NNモデルのソースコード

CNNモデルのソースコード

いかがでしょうか。
このように、Kerasを使用すれば比較的簡単にディープラーニングモデルを構築できます。また、モデルの学習/評価も簡単にできます。
今回は、MNISTの手書き画像分類を行いましたが、自前画像を用意して試すこともできますので活用してみてはいかがでしょうか。

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