Keras : 画像分類 : LeNet で MNIST, CIFAR-10, CIFAR-100

Keras: 画像分類 : LeNet
作成 : (株)クラスキャット セールスインフォメーション
日時 : 04/30/2017

 

LeNet in Keras

TensorFlow を backend として Keras を利用されている方も多いかと思いますが、復習の意味で、Keras による LeNet で基本的なデータセット – MNIST, CIFAR-10, CIFAR-100 – で試しておきます。再調整と転移学習も使用します。

LeNet の原論文は以下 :

以下の Theano, Caffe のチュートリアルと protobuf 定義は直接的に実装の参考になります :

以下が実装です。特に迷うところはありませんが、(オリジナルの LeNet-5 は sigmoid だと思いますが) activation は relu を選択しています :

model = Sequential()
model.add(Conv2D(20, kernel_size=5, strides=1, activation='relu', input_shape=input_shape))
model.add(MaxPooling2D(2, strides=2))

model.add(Conv2D(50, kernel_size=5, strides=1, activation='relu'))
model.add(MaxPooling2D(2, strides=2))

model.add(Flatten())
model.add(Dense(500, activation='relu'))
model.add(Dense(num_classes, activation='softmax'))

TensorBoard のグラフ表示を確認しておきます :

 

MNIST using LeNet

手始めに MNIST。以下は TensorBoard の出力で、上が訓練損失で、下がテスト精度です :

精度はおよそ 99.3 % です。

Dropout

念のために dropout 層を追加してみます :

model = Sequential()
model.add(Conv2D(20, kernel_size=5, strides=1, activation='relu', input_shape=input_shape))
model.add(MaxPooling2D(2, strides=2))

model.add(Conv2D(50, kernel_size=5, strides=1, activation='relu'))
model.add(MaxPooling2D(2, strides=2))
model.add(Dropout(0.25))

model.add(Flatten())
model.add(Dense(500, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(num_classes, activation='softmax'))

99.5 % まで上昇。

 

LeNet の改良による CIFAR-10

まずはシンプルな LeNet (LeNet-5) を CIFAR-10 に適用してみます。
以下の TensorBoard のグラフは、上から訓練損失・訓練精度・テスト精度です :

Dropout・データ拡張

汎化性能が上がらないので dropout 層を追加した上で、データ拡張も使用して 500 epochs 訓練してみます :

84 % 程度でしょうか。もう少し訓練すれば多少は上がるかもしれませんが、このモデルのほぼ上限でしょう。

 

CIFAR-100

CIFAR-10 で訓練したモデルを流用して CIFAR-100 への転移学習を実行してみました :

精度は 56 % 程度です。それほど悪い数字でもありませんが、LeNet ベースでは難しいようです。

 

以上