snovaのブログ

主にプログラミングやデジタルコンテンツについて書きます。最近はPython, Flutter, VRに興味があります。

kerasのfashion_mnistで転移学習

イントロダクション

ずっと前に下書きしてたものが出てきたので、共有します。

画像認識では学習量を小さくするために、転移学習やfine tuningが使われているので、実践してみました。 ただのMNISTだとおもしろくないけど、カラーにすると学習量が大きくなるので、間を取ってfashion_mnistのデータセットを使いました。

目次

転移学習

転移学習とはあるデータセットで訓練された学習モデルを別のデータセットのモデルとして使うことです。 fine tuningは別のデータセットの学習モデルとして使うときに、少し学習させることです。

fashion MNIST

手書き数字の代わりに、Tシャツやズボンなどのファッションアイテムを集めたデータセットです。 サイズが28x28の白黒画像なので、カラーのCIFAR10と比較するとデータ量が小さいです。 訓練データ数は60000枚、テストデータは10000枚。 以下の表は、データセットの中身を示しています。

ラベル 内容
0 Tシャツ/トップス
1 ズボン
2 プルオーバー
3 ドレス
4 コート
5 サンダル
6 シャツ
7 スニーカー
8 バッグ
9 アンクルブーツ

実際の画像をいくつか紹介します。

Tシャツ

プルオーバー

スニーカー

計算機環境

  • OS : Ubuntu 16.04
  • Python : 3.5.5
  • Keras : 2.2.0
  • TensorFlow : 1.9.0

コーディングにおける注意点

  • 層を追加するときは各レイヤーに名前が必要
  • softmax関数が最後に入っていたら、fine-tuningが難しいので、 model.pop() で最後のlayerを削除
  • 訓練させたくない、または、学習が重いので訓練させる層を限定したいなら、 freeze 機能を使用

  • 各レイヤーには名前が必要 層の名前はそれぞれ固有である必要があります。 名前の設定は以下のようにします。

model_b = Sequential()
model_b.add(Dense(128, activation='relu', name='model_b_dense1'))

層の名前を確認したいなら、以下のようなスクリプトを書くと良いです。

print(model.summary())

for model_layer in model.layers:
    print(model_layer.get_config())
  • softmax関数が最後に入っていたら、fine-tuningが難しいので、 model.pop() で最後のlayerを削除 そのモデルの最後の層を削除するコマンドはmodel.pop()
model = load_model(model_filename, compile=False)
model.pop() # delete softmax
  • 訓練させたくない、または、学習が重いので訓練させる層を限定したいなら、 freeze 機能を使用 trainable=False はその層を訓練させないという意味です。 デフォルトはtrainable=True
print(model.summary())

for i, model_layer in enumerate(model.layers):
    print('layer : ' + str(i))
    print(model_layer.get_config())
    model_layer.trainable = False # 
    print(model_layer.get_config())

モデルの保存は save(filepath) 、モデルの読み込みは keras.models.load_model(filepath)で行います。

作成したコード

Fashion MNISTのデータの一部を抽出し、学習、モデルを保存します。 次に、別のデータでfine-tuningします。 なお、追加の層はseqentialではなく、modelクラスで入れてます。

keras_fmnist.py - Gist

結果 :

# (1st)
Layer (type)                 Output Shape              Param #   
=================================================================
conv2d_1 (Conv2D)            (None, 26, 26, 32)        320       
_________________________________________________________________
conv2d_2 (Conv2D)            (None, 24, 24, 64)        18496     
_________________________________________________________________
max_pooling2d_1 (MaxPooling2 (None, 12, 12, 64)        0         
_________________________________________________________________
dropout_1 (Dropout)          (None, 12, 12, 64)        0         
_________________________________________________________________
flatten_1 (Flatten)          (None, 9216)              0         
_________________________________________________________________
dense_1 (Dense)              (None, 128)               1179776   
_________________________________________________________________
dropout_2 (Dropout)          (None, 128)               0         
_________________________________________________________________
dense_2 (Dense)              (None, 10)                1290      
=================================================================

train accuracy : 0.968
test accuracy : 0.819


# (2nd)
Layer (type)                 Output Shape              Param #   
=================================================================
conv2d_1_input (InputLayer)  (None, 28, 28, 1)         0         
_________________________________________________________________
conv2d_1 (Conv2D)            (None, 26, 26, 32)        320       
_________________________________________________________________
conv2d_2 (Conv2D)            (None, 24, 24, 64)        18496     
_________________________________________________________________
max_pooling2d_1 (MaxPooling2 (None, 12, 12, 64)        0         
_________________________________________________________________
dropout_1 (Dropout)          (None, 12, 12, 64)        0         
_________________________________________________________________
flatten_1 (Flatten)          (None, 9216)              0         
_________________________________________________________________
dense_1 (Dense)              (None, 128)               1179776   
_________________________________________________________________
dropout_2 (Dropout)          (None, 128)               0         
_________________________________________________________________
model_a_dense1 (Dense)       (None, 128)               16512     
_________________________________________________________________
model_a_dense2 (Dense)       (None, 10)                1290      
=================================================================

train accuracy : 0.954
test accuracy : 0.833

1回目の学習の精度

2回目の学習の精度

コードや画像はgithubで共有します。

github.com

終わりに

久しぶりに見返したら全く覚えていませんでした。 もっと勉強します。

参考文献

Google Play and the Google Play logo are trademarks of Google LLC.