tensorflowでFineTuning
1.背景
- tensorflowにまだまだ慣れていないが、FineTuningを行う必要が出てきました。
- 本番で活用する前に、tensorflowでFineTuningを行う際の自己学習メモとして記録。
- 先人のやり方を最大限/時短で吸収したい。
- 実PJで使う際に必要になりそうな要素を勉強する。(どうやってデータを配置すべきか等)
2.FineTuningをとりあえず動かす。
- 画像セットの入手
- 参考サイトより、本データベースの存在を知る。テストにちょうど良い規模感でしょうか。
- 17 Category Flower Datasetのダウンロード
Downloads => Dataset images
より、17flowers.tgz
を入手。
- ソースコードの入手
- 参考サイト1より、ソースコードを入手。
-
Fine Tuning(学習)
- 画像データ準備
setup.py
により、画像データをtrain_images
とtest_images
のフォルダに分けて保存。
-
学習:
finetuning.py
を実施。- Fine Tuningのエッセンスはここにあると予想。
-
plotのimportでエラーが出て動作しない。
-
該当箇所
```
from keras.utils.visualize_util import plotfrom keras.utils.vis_utils import plot
```
-
keras.utils.visualize_utilが、leras.utils.vis_utilsに変更されたとの情報あり、変更するもplot見つからず。
- コアな部分でないので、とりあえずコメントでつぶしてしまい、先に進む。
- 飛ばすのは良くはありませんが・・本番で使いたいのはFront-end tensorflow, Back-end kerasで、本ソースコードとは逆だったりするので、後で落ち着いて対処すればいい。
- GPUマシン(末記の検証環境)にて、50分ほどで学習完了。
- 飛ばすのは良くはありませんが・・本番で使いたいのはFront-end tensorflow, Back-end kerasで、本ソースコードとは逆だったりするので、後で落ち着いて対処すればいい。
- 予測/推論の実行
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)
-
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
-
とりあえず、上手く動かせたか。
- 画像データ準備
3.Fine Tuningに必要な要素(学習メモ)
-
Kerasのgenerator
- generatorに train/testのデータ(フォルダ)や、augmentation有無などを指定して学習スタート、といった使い方。
- 入力画像データは、train/testのフォルダ分けをしておくのが1つのやり方であることと理解。
- フォルダ分けをしなくても、例えばファイルパスのリストを与えるなど、あるのかどうかを調査。
- Keras Documentation ImageDataGenerator class
- 今回のサンプルコードでは、
flow_from_directory
を利用している。 flow_from_dataframe
が使える。pandasのdataframeで、公式に記載のフォーマットで記載されていればよい。
- 今回のサンプルコードでは、
- Keras Documentation ImageDataGenerator class
- generatorに train/testのデータ(フォルダ)や、augmentation有無などを指定して学習スタート、といった使い方。
-
Fine Tuningのやり方
- Networkの重みの固定の仕方で、セオリーでは以下と理解。
- 特徴抽出:学習済み畳み込みベース(CNN部分)を凍結し、学習済み分類器(全結合層部分)を新しい分類器で学習。
- ファインチューニング:新しく追加した分類器(全結合層部分)と、それに近い畳み込みブロック(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
```
-
-
- Networkの重みの固定の仕方で、セオリーでは以下と理解。
-
ソースコード別理解
- 他のソースコードの内容も確認し、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.参考サイト/書籍
- PythonとKerasによるディープラーニング(マイナビ出版)
- Fine Tuningの考え方が載っていて、参考になった。
- 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 |