転移学習をやってみた（Googleチュートリアル）


# 記事概要
通常、ディープラーニングを使って画像の分類モデルを作る場合はそれぞれのカテゴリで１０００枚くらいの画像が必要だと言われています。
それだけの画像を用意できない場合、考えられる方法としては以下の２つがあります

1. 画像を水増しする
1. 転移学習を使って既存のモデルをもとにして学習する。

本記事では、Googleの作ったMobileNetというモデルをベースに転移学習を行ってみたいと思います。
（ほぼGoogleのチュートリアルそのままです）

- 学習に使う学習ファイルは準備が大変なので、機械学習用にインターネット公開されている花の写真を使います。このデータセットは、デイジー、たんぽぽ、バラ、ひまわり、チューリップの５種類の花の写真が、それぞれ約６００枚ずつ用意されたものです。
この写真を使わなくてもカテゴリごとに５００枚程度の写真が準備できる方は自分で準備した写真を使えます。
- ソースコードは以下のリポジトリに公開されている物を使います。
- pythonを利用しますが、提供されたコードをそのまま使うので中は見ません。
- ここで利用するコードは、ローカル環境でもGoogleColabでも動きます。
Colab版のコードは以下のURLから参照できます。 (Google公開のコードをColab用に少し改変しました）




## 転移学習(Transfer learning)って？
転移学習とは、すでに作られた学習モデルをスターティングポイントとし、独自のデータを学習させることにより、カスタマイズを行って新たなモデルを作る手法です。
通常のモデル作成に比べ、少ないデータかつ短い時間で制度の高いモデルが作れるなどの特徴があります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/77722/17c668f3-bfde-3561-ccc6-57672f690f18.png)
引用元：https://machinelearningmastery.com/transfer-learning-for-deep-learning/


## どんなpre-trainedモデルがあるのか
例えば、代表的なpre-trainedモデルとして以下のモデルがります。例えばGoogle InceptionモデルはGoogle内でも最高精度を誇る画像認識モデルですが、その分処理予測時の処理不可が高い、モデルのサイズが大きいなどのデメリットもあります。
精度はInceptionには劣るものの、処理不可を減らし、サイズを小さくしてモバイル環境でも利用できるようにしたのがMobileNetです。
それぞれのモデルで得意分野があったり、上記のような特徴があるため、これらを把握した上でモデルを選択することも重要です。

- Google Inception Model
- Google Mobile Net
- Oxford VGG Model
- Microsoft ResNet Model


# 転移学習の実施
ここから実際の作業に入っていきます。

## 環境の準備
このチュートリアルを実行するためにはローカル環境を作成するか,Google Colabを利用するか

###ローカル環境の構築
まずは環境の準備を行います。
ローカル環境での実行には以下のツールが必要です。インストールがされていない場合はインストールを行ってください

- python3
- git

### Google Colabで実行
Google Colabでの実行は以下のURLを参照してください。

Google Colab
https://colab.research.google.com/drive/1-sgx4kute33-df1-uZs0y6SMn0byhXrx


## 転移学習実行コードの取得
まず、以下のコマンドを実行し、転移学習を行うためのソースコードをダウンロードしてきます。
（このコマンド実行にはgitが必要です。インストールされていない場合はインストールをしてください）



```bash
git clone https://github.com/googlecodelabs/tensorflow-for-poets-2
cd tensorflow-for-poets-2
```

##イメージの取得
次に、転移学習を行う画像データをダウンロードします。

#### 画像ファイルのダウンロード
```
wget http://download.tensorflow.org/example_images/flower_photos.tgz 
tar -xf ./flower_photos.tgz
```
 Windowsの環境で実行する場合、上記URLに直接アクセスし、解凍ソフトなどでファイルを解凍してください。MacやLinux環境であればそのまま実行可能です。

#### 画像の確認
次に、flower_photosフォルダを開き、その中フォルダの中を覗いてみます。以下のサンプルの通り、daisyフォルダの中には様々なデイジーの写真が、dandelionフォルダの中には様々なたんぽぽの写真が登録されていることがわかります。  
このデータは、Googleが機械学習用に公開しているデータですが、中を見て分かる通り、データそのものは普通のjpegファイルです。自分で用意した写真で転移学習を行う場合はこれと同じ形式で写真データを準備すればOKです。
その際、フォルダ名がその配下に含まれる写真のラベルとなることに注意してください。サイズはバラバラでも問題ありません。ただ、携帯やデジカメで撮影した写真そのままを使うと学習に時間がかかってしまうので、**縦横500〜200ピクセルくらいに収まるくらいのサイズに縮小しておく**ことをおすすめします。

とりあえず転移学習を体験したいという場合は、このデータをそのまま使ってください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/77722/d5fa0b1e-548f-2c44-1649-48b6b76556a5.png)


## tensorboardの起動（オプション）

学習の実行前に以下のコマンドを実行し、Tensorboardを起動しておくと、学習の状況をブラウザ上から確認できるようになります。

```shell:ローカル実行時
tensorboard --logdir tf_files/training_summaries &
```

きれいなグラフが表示されるので、トレーニングが進んでいる感があります。
それぞれのグラフの示す意味についてはTensorboardのドキュメントを参照してください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/77722/501f54de-7d67-3bd1-07cd-cde70ea80305.png)

Google Colab上でも同じ様にTensorboardを表示することはできますが、2.0以降でないとだめな様です。このサンプルでは1.x系を使っているので、一旦飛ばします。


## モデルの作成
###モデルの選択
認識したいものやモデルを使う環境に応じてもととなるモデルを選択します。
ここでは、MobineNetを利用していきます。
MobileNetとは、２０１７年にGoogleによってつくられたモバイル環境向けの画像認識モデルです。
他のモデルに比べてサイズが小さく、処理負荷も低いという特徴があります。

さっそく以下のコマンドを実行し、転移学習を開始します。

```shell:ローカル実行用
python3 -m scripts.retrain \
  --bottleneck_dir=tf_files/bottlenecks \
  --how_many_training_steps=500 \
  --model_dir=tf_files/models/ \
  --summaries_dir=tf_files/training_summaries/mobilenet_0.50_224 \
  --output_graph=tf_files/retrained_graph.pb \
  --output_labels=tf_files/retrained_labels.txt \
  --architecture=mobilenet_0.50_224 \
  --image_dir=flower_photos
```

```shell:GoogleColab用
python scripts/retrain.py \  
  --bottleneck_dir=/content/bottlenecks \
  --how_many_training_steps=1000 \
  --model_dir=/content/models/ \
  --summaries_dir=/content/training_summaries/mobilenet_0.50_224 \
  --output_graph=/content/retrained_graph.pb \
  --output_labels=/content/retrained_labels.txt \
  --architecture=mobilenet_0.50_224 \
  --image_dir=/content/flower_photos
```


上記のコマンドでうまく動かない場合は、scriptを直接指定に変えてみる

```shell
python3 scripts/retrain.py \ 
#---以降同じ---
```

実行するPCのスペックによりますが、トレーニングには５分〜１０分程度かかります。
完了後、tf_filesの下にretrained_labels.txtとretrained_graph.pbファイルが作成されていることを確認します。


## 予測の実行
ここでは、前の手順で作成したモデル(.pbファイル）を使って新たに与えられたデータを分類してみます。

### 画像の取得
適当にインターネットで拾ってきたデイジーの画像をダウンロードして、my-daisy-pic.jpgに名前を変更して保存します。
（以下の画像を使っても良いですが、自分で適当に拾ってきたデイジーの画像でもOKです）

![18d02333-1530-4f2c-9d04-86b428765dc0.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/77722/fd9a8cb2-efd3-a50a-61de-5b83a0c31260.jpeg)

###予測の実行
下記のコマンドを実行して、先程インターネットから取ってきたデイジーの画像を読み込ませてみます。

```
python3 -m scripts.label_image --graph=tf_files/retrained_graph.pb --image=mypic/daisy7.jpg
```

すると以下の値が返って来ました。

```
Evaluation time (1-image): 0.382s
daisy (score=0.74989)        <-- これ
dandelion (score=0.12876)
tulips (score=0.07300)
roses (score=0.04504)
sunflowers (score=0.00332)
```


なんと！　ちゃんとこの写真がデイジーであることが認識されました。

他にもチューリップ、ひまわりの写真でも試してみてください。

# まとめ
ここまで実施した方は転移学習がいかに簡単に行えるかが体験できたかと思います。
データさえ集めれば、独自の分類モデルを作ることも簡単です。ただし、それなりの質と量のデータが必要になります。
データは同じようなデータよりも、バラエティに富んだデータの方が良いそうです。
どのような写真を集めれば良いかは、今回利用した花のデータセットを参照することでイメージが付きやすいかと思いますので、是非参考にしてみてください。


## 次回予告

次回は、同じデータを使って１からモデルを作ってみたいと思います。どれぐらいの精度の違いが出るのか…楽しみです。


## 参考記事
Google 転移学習チュートリアル
https://codelabs.developers.google.com/codelabs/tensorflow-for-poets/#0