tensorflowでFineTuning

土 16 11月 2019

tensorflowでFineTuning

1.背景

  • tensorflowにまだまだ慣れていないが、FineTuningを行う必要が出てきました。
    • 本番で活用する前に、tensorflowでFineTuningを行う際の自己学習メモとして記録。
    • 先人のやり方を最大限/時短で吸収したい。
    • 実PJで使う際に必要になりそうな要素を勉強する。(どうやってデータを配置すべきか等)

2.FineTuningをとりあえず動かす。

  1. 画像セットの入手
    • 参考サイトより、本データベースの存在を知る。テストにちょうど良い規模感でしょうか。
    • 17 Category Flower Datasetのダウンロード
      • Downloads => Dataset imagesより、17flowers.tgzを入手。
  2. ソースコードの入手
    • 参考サイト1より、ソースコードを入手。
  3. Fine Tuning(学習)

    1. 画像データ準備
      • setup.pyにより、画像データをtrain_imagestest_imagesのフォルダに分けて保存。
    2. 学習:finetuning.pyを実施。

      • Fine Tuningのエッセンスはここにあると予想。
      • plotのimportでエラーが出て動作しない。

        • 該当箇所

          ```
          from keras.utils.visualize_util import plot

          from keras.utils.vis_utils import plot

          ```

        • keras.utils.visualize_utilが、leras.utils.vis_utilsに変更されたとの情報あり、変更するもplot見つからず。

        • コアな部分でないので、とりあえずコメントでつぶしてしまい、先に進む。
          • 飛ばすのは良くはありませんが・・本番で使いたいのはFront-end tensorflow, Back-end kerasで、本ソースコードとは逆だったりするので、後で落ち着いて対処すればいい。
            • GPUマシン(末記の検証環境)にて、50分ほどで学習完了。
        • 予測/推論の実行
          • predict.py実行。Tulip画像がTulip 1位で推論された。

      (py3.6_tf1.5.0) >python predict.py .\test_images\Tulip\image_0012.jpg ('Tulip', 0.9972982) ('Daffodil', 0.0010603186) ('Sunflower', 0.0004312605) ('Iris', 0.00036461666) ('Dandelion', 0.00031871776)

    3. evaluate.py実行。

      (py3.6_tf1.5.0) >python evaluate.py loss, acc = model.evaluate_generator(test_generator, val_samples=nb_test_samples) 0.266931531164304 0.8876451073989742

    4. とりあえず、上手く動かせたか。


3.Fine Tuningに必要な要素(学習メモ)

  1. Kerasのgenerator

    • generatorに train/testのデータ(フォルダ)や、augmentation有無などを指定して学習スタート、といった使い方。
      • 入力画像データは、train/testのフォルダ分けをしておくのが1つのやり方であることと理解。
      • フォルダ分けをしなくても、例えばファイルパスのリストを与えるなど、あるのかどうかを調査。
        • Keras Documentation ImageDataGenerator class
          • 今回のサンプルコードでは、flow_from_directoryを利用している。
          • flow_from_dataframeが使える。pandasのdataframeで、公式に記載のフォーマットで記載されていればよい。
  2. Fine Tuningのやり方

    • Networkの重みの固定の仕方で、セオリーでは以下と理解。
      1. 特徴抽出:学習済み畳み込みベース(CNN部分)を凍結し、学習済み分類器(全結合層部分)を新しい分類器で学習。
      2. ファインチューニング:新しく追加した分類器(全結合層部分)と、それに近い畳み込みブロック(VGG16で言えばブロック5)の重みを再学習。
    • 今回使ったサンプルコードでは、上記の1を飛ばして、直接2を実行している。
      • その根拠としては、以下の block5_conv1 (Conv2D) 以降の重みを再学習している。

        • 確認1:プログラム中でfreezeしている層を確認。

          ```

          最後のconv層の直前までの層をfreeze

          for layer in model.layers[:15]: layer.trainable = False ```

        • 確認2:VGG16と全結合層を結合した学習用のモデルを出力。

          ```


          Layer (type) Output Shape Param #

          input_1 (InputLayer) (None, 150, 150, 3) 0


          block1_conv1 (Conv2D) (None, 150, 150, 64) 1792


          block1_conv2 (Conv2D) (None, 150, 150, 64) 36928


          block1_pool (MaxPooling2D) (None, 75, 75, 64) 0


          block2_conv1 (Conv2D) (None, 75, 75, 128) 73856


          block2_conv2 (Conv2D) (None, 75, 75, 128) 147584


          block2_pool (MaxPooling2D) (None, 37, 37, 128) 0


          block3_conv1 (Conv2D) (None, 37, 37, 256) 295168


          block3_conv2 (Conv2D) (None, 37, 37, 256) 590080


          block3_conv3 (Conv2D) (None, 37, 37, 256) 590080


          block3_pool (MaxPooling2D) (None, 18, 18, 256) 0


          block4_conv1 (Conv2D) (None, 18, 18, 512) 1180160


          block4_conv2 (Conv2D) (None, 18, 18, 512) 2359808


          block4_conv3 (Conv2D) (None, 18, 18, 512) 2359808


          block4_pool (MaxPooling2D) (None, 9, 9, 512) 0


          block5_conv1 (Conv2D) (None, 9, 9, 512) 2359808


          block5_conv2 (Conv2D) (None, 9, 9, 512) 2359808


          block5_conv3 (Conv2D) (None, 9, 9, 512) 2359808


          block5_pool (MaxPooling2D) (None, 4, 4, 512) 0


          sequential_1 (Sequential) (None, 17) 2101777

          Total params: 16,816,465 Trainable params: 9,181,201 Non-trainable params: 7,635,264


          ```

  3. ソースコード別理解

    • 他のソースコードの内容も確認し、Fine Tuningで勉強すべきトピックを確認する。
    • ソースコードと役割の確認

      • データの準備
        • setup.py
      • 学習メイン
        • finetuning.py
        • vgg_scratch.py : VGG16の重みをランダム化した場合。学習が上手くいかない例のはず。
        • finetuning_with_preprocess.py : 前処理を使っている。別途調査したい。
      • 推論

        • predict.py : 画像1枚のみの推論
        • evaluate.py : テストデータ全体の推論
        • predict_with_preprocess.py : 画像1枚のみの推論。前処理を使っている。
      • 可視化

        • extractor.py : ボトルネック特徴量(FC層の直前の出力)をファイルに保存。モデルの検証方法として使えるかを調査したい。
        • plot_results.py : matplotlibで学習ログを可視化
      • helperと単純な?cnn

        • smallcnn.py

4.参考サイト/書籍

  1. PythonとKerasによるディープラーニング(マイナビ出版)
    • Fine Tuningの考え方が載っていて、参考になった。
  2. VGG16のFine-tuningによる17種類の花の分類
    • こちらからソースコードを入手して試行させて頂いた。

5.検証環境

No 名称 状況
1 CPU AMD Phenom(tm) II X6 1090T 3.20GHz
これがAVX(Advanced Vector Extensions)を搭載しておらず、
Tensorflowはver=1.5.0止まりとなってしまう。
2 GPU GeForce GTX 1060 6GB
Jupyter notebookに多少メモリ開放バグあるみたい?
たまに6GB上限を気にするレベルで、とりあえずまだ大丈夫。
3 Memory 16GB
機械学習のため秋葉原で中古メモリ増設。4->16で色々快適に。
4 Python Windows, Anaconda3-5.3.1 でver3.6の仮想環境(Tensorflow対応から3.6とした)
5 Tensorflow Version 1.5.0
Visual Studio 2015 Version 14.0.25431.01 Update 3
CUDA V9.0.176
cuDNN v7.0.5[Dec 5, 2017], for CUDA 9.0

social