Google ColabとYOLO v3を用いて浮世絵で顔検出を行った件

# Google ColabとYOLO v3で自前の画像で物体検出を行いたい
**浮世絵**の顔検出を行いたいと唐突に思い立ち、実施することにした。
参考にしたサイトやつまづいた点、今後行いたいことをこちらに残しておこうと思う。
※windows 64bitのノートPCで検証を行った。

## 手順
以下の順番で取り組んだ。

1. 画像準備
2. アノテーション
3. 学習
4. 推論

## 1.画像手順
浮世絵の画像は、こちらの記事[【貴重】北斎や広重に歌麿まで、2600枚の浮世絵と錦絵が無料DL放題](https://buzzap.jp/news/20170618-ukiyoe-nishikie-dl/)を参考に、
アメリカ議会図書館（Library of Congress）の[サイト](https://www.loc.gov/)からダウンロード。
![ukiyo-e_images.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/684711/b7253158-6abf-cb8b-99dc-23be7f5067c0.png)

画像をダウンロードしているだけでも楽しい。画像は約100枚ダウンロードした。
今回は学習時に画像のアスペクト比は同程度が良いと思い、縦長の画像のみをダウンロード。
（今思うと、統一しなくても良いかも）

### 画像処理
アノテーションを行う前に、学習時に同じ画像サイズの方が良いと考えて300x500の画像サイズにリサイズした。
画像サイズが同一でなくても学習ができるか、今後試してみたい。

## 2.アノテーション
アノテーションはmicrosoftの[VOTT](https://github.com/Microsoft/VoTT/)も試しましたが、画像取り込みの部分で失敗し、labelImgを試しました。
[Annotationツール比較：labelImgとVoTT（YOLO・SSD両対応のデータセット）](https://www.nakasha.co.jp/future/ai/annotation_tool.html)の記事の「windowsで簡単インストールしたい方はこちらから：」を参考に、exeをダウンロードして使用した。

他のサイトでも紹介されている通り、マニュアルなしで利用できた。
また、アノテーション結果をPascal VocかYoloか選択できることも嬉しい。

出力されるアノテーション結果は
>[object-class] [x_center] [y_center] [width] [height]

の形式でテキストファイルが画像毎に出力された。

## 3.学習

Google Colaboratoryの使い方については、[こちら](https://wakuphas.hatenablog.com/entry/2018/09/19/025941)、Yolo v3による学習では[こちら](https://blog2.cct-inc.co.jp/blog/machine-learning/yolov3/)
のサイトを参考にGoogle Colaboratory上で学習を実施した(本当にありがとうございます)。

上記記事にも書かれているが、Google ColaboratoryはGPUが利用できる一方、**接続してから12時間をすぎると、アップロードしていたデータや出力したファイル、構築した環境まで全て消える点**が注意点。
こまめにファイルのダウンロードを行うことが大事。

学習手順は上記記事を参照頂くとして、以下を実行した。
記事によれば、適当な重みを初期値として読み込むと収束するとのことで以下の重みを用いた。

* yolo v3 の初期値ファイル :[darknet53.conv.74](https://pjreddie.com/media/files/darknet53.conv.74)

~~~
$ ./darknet detector train cfg/obj.data cfg/yolo-obj.cfg darknet53.conv.74 > train_log.txt
~~~

なお、以下のyolo-obj.cfgでは、batch=16、subdivisions=6に値を変更して学習を行った。
学習が実行すると、/backupフォルダに重み（*.weightsのファイル）が保存される。

### ひっかかったところ

#### ① make エラー 

~~~~
$make
~~~~
を実行してエラーが出てしまった。
Google Colaboratoryを開いた時の左上の「編集」→「ノートブックの設定」→「GPU」
を設定するのを忘れていた。


#### ② 学習時（cfgファイル）エラー

[こちら](https://blog2.cct-inc.co.jp/blog/machine-learning/yolov3/)の記事のcfg/yolov3-voc.cfgをコピーして修正を行い、実行した結果、

>./src/utils.c:256: error: Assertion `0' failed

と表示されてエラーが出た。
[Google ColabでYOLOの学習をする上でつまずいたエラー](https://qiita.com/hiro_gabaxtu/items/ae1f564fe35dfa0306a8)を参考に、ファイル内の改行コードが
CRLFとなっていたことが原因でした。
[サクラエディタ](https://sakura-editor.github.io/)をダウンロードし、CRLFからLFに置換したことで解決した。



## 4.推論

学習によってできた重みを用いて推論を実行する。
（以下のyolo-obj.cfg は推論用にbatch=1,subdivisions=1に値を変更すること）

~~~
./darknet detector test cfg/obj.data cfg/yolo-obj.cfg backup/yolov**final.weights  **.jpg -thresh 0.10
~~~
-threshは検出の閾値。
こんな感じの結果が出力されました。

![predictions.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/684711/1d69ed47-5394-0515-6f06-7de2f8d3da01.jpeg)

後ろ姿をアノテーションした画像は少なかったのにも関わらず、後ろ姿の頭部が検出出来ていて驚いた。

## 5.今後行いたいこと
* 学習の収束状態をplotする
* yolo v4,5ではどのような結果になるか試す(参考になる記事など教えて頂けると嬉しいです！)

##　参考にしたサイト（ありがとうございました！）
より有益な記事を書いていこうと思っています。

* https://blog2.cct-inc.co.jp/blog/machine-learning/yolov3/
* https://wakuphas.hatenablog.com/entry/2018/09/19/025941
* https://qiita.com/emi-cd/items/60e8fe877dbedb2cfae7
* https://qiita.com/hiro_gabaxtu/items/ae1f564fe35dfa0306a8