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シャツ
プルオーバー
スニーカー
計算機環境
コーディングにおける注意点
- 層を追加するときは各レイヤーに名前が必要
- 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
クラスで入れてます。
結果 :
# (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
コードや画像はgithubで共有します。
終わりに
久しぶりに見返したら全く覚えていませんでした。 もっと勉強します。