【物体認識2020最前線】Windows10 に Pytorch をインストールして CornerNet-Lite を動かすまでのログ。


気が付けば１年以上ぶりの更新…(^^;;;

最近はJavaとか職業プログラミングばかりなので Python とか OpenCV とか触ってません。なので物体検出、物体認識の最新動向を追っかけてないけど、昨年より CornerNet-Lite が話題で、どうやらCornerNet-Squeeze は yolo v3 より速いらしいので環境構築してマックスくんを物体認識して実験してみる。動向の詳細は↓下記参照。

https://opencv.org/latest-trends-in-object-detection-from-cornernet-to-centernet-explained-part-ii-cornernet-lite/

CornerNet の仕組みについて日本語でわかりやすい記事は↓参照。
https://engineer.dena.jp/2019/07/cv-papers-19-keypoint-object-detection.html
CornerNet は一言でいえば、ヒートマップを作製して、矩形の角(Corner)を推定して物体を検出して認識する仕組みのようです。

で、以下にあるように、本当は、Anaconda 環境で構築されていたほうがいいのでしょうけど、pip3環境構築済だし、Anacondaとの競合（[condaとpip：混ぜるな危険](http://onoz000.hatenablog.com/entry/2018/02/11/142347)）とかめんどくさいので Anacondaは使わないで構築しましたので、そのログを残しておきます。

https://github.com/princeton-vl/CornerNet-Lite

## pytorchのインストール

下記URL にアクセスし自分の環境に合わせてクリックするとコマンドが表示されます。
https://pytorch.org/

QUICK START
LOCALLY
の部分ね！

私の環境はWindows で パッケージマネージャは pip 、Python 3.7.4、cuda10.1 でインストールしてみます。


~~~
C:\>pip3 install torch===1.4.0 torchvision===0.5.0 -f https://download.pytorch.org/whl/torch_stable.html
Looking in links: https://download.pytorch.org/whl/torch_stable.html
Collecting torch===1.4.0
  Downloading https://download.pytorch.org/whl/cu101/torch-1.4.0-cp37-cp37m-win_amd64.whl (796.8MB)
     |████████████████████████████████| 796.8MB 45kB/s
Collecting torchvision===0.5.0
  Using cached https://files.pythonhosted.org/packages/7d/3e/2b5ddf744226159dc90a52f0d044c0de7c5ca4f42d12a350a674ebb6fb2a/torchvision-0.5.0-cp37-cp37m-win_amd64.whl
Requirement already satisfied: six in c:\python\python37\lib\site-packages (from torchvision===0.5.0) (1.12.0)
Requirement already satisfied: pillow>=4.1.1 in c:\python\python37\lib\site-packages (from torchvision===0.5.0) (6.1.0)
Requirement already satisfied: numpy in c:\python\python37\lib\site-packages (from torchvision===0.5.0) (1.17.2)
Installing collected packages: torch, torchvision
  Found existing installation: torch 1.0.1
    Uninstalling torch-1.0.1:
      Successfully uninstalled torch-1.0.1
  Found existing installation: torchvision 0.4.0
    Uninstalling torchvision-0.4.0:
      Successfully uninstalled torchvision-0.4.0
Successfully installed torch-1.4.0 torchvision-0.5.0

C:\>
~~~

Successfully が表示されていれば完了です。

## pytorch 版 CornerNet-Lite の取得

CornerNet-Lite の pytorch版を下記より取得して動かしてみましょう。

https://github.com/princeton-vl/CornerNet-Lite.git

~~~
C:\>cd github
C:\github>git clone https://github.com/princeton-vl/CornerNet-Lite.git
Cloning into 'CornerNet-Lite'...
remote: Enumerating objects: 75, done.
remote: Total 75 (delta 0), reused 0 (delta 0), pack-reused 75
Unpacking objects: 100% (75/75), done.
~~~

make を実行しますが、前提として、mingw 環境が構築されていることとします。

~~~
C:\github\CornerNet-Lite\core\external>mingw32-make
python setup.py build_ext --inplace
Traceback (most recent call last):
  File "setup.py", line 4, in <module>
    from Cython.Build import cythonize
ModuleNotFoundError: No module named 'Cython'
Makefile:2: recipe for target 'all' failed
mingw32-make: *** [all] Error 1
~~~

No module named 'Cython' というエラーが出ているので、pip で Cython をインストールする。
構築済の環境によっては、その他のモジュールでも No module named というのが出るかもしれませんので、その場合は出てきたエラーメッセージを判断してモジュールをインストールしてください。

## Cythonとは？
Pythonを高速化するためのパッケージ。↓参照
https://qiita.com/pashango2/items/45cb85390193d97523ca

~~~
C:\>pip3 install cython
Collecting cython
  Downloading https://files.pythonhosted.org/packages/1f/be/b14be5c3ad1ff73096b518be1538282f053ec34faaca60a8753d975d7e93/Cython-0.29.14-cp37-cp37m-win_amd64.whl (1.7MB)
     |████████████████████████████████| 1.7MB 6.4MB/s
Installing collected packages: cython
Successfully installed cython-0.29.14

C:\>
~~~

気を取り直して…

~~~
C:\github\CornerNet-Lite\core\external>mingw32-make
python setup.py build_ext --inplace
Compiling bbox.pyx because it changed.
Compiling nms.pyx because it changed.
[1/2] Cythonizing bbox.pyx
C:\Python\Python37\lib\site-packages\Cython\Compiler\Main.py:369: FutureWarning: Cython directive 'language_level' not set, using 2 for now (Py2). This will change in a later release! File: C:\github\CornerNet-Lite\core\external\bbox.pyx
  tree = Parsing.p_module(s, pxd, full_module_name)
[2/2] Cythonizing nms.pyx
C:\Python\Python37\lib\site-packages\Cython\Compiler\Main.py:369: FutureWarning: Cython directive 'language_level' not set, using 2 for now (Py2). This will change in a later release! File: C:\github\CornerNet-Lite\core\external\nms.pyx
  tree = Parsing.p_module(s, pxd, full_module_name)
running build_ext
building 'bbox' extension
creating build
creating build\temp.win-amd64-3.7
creating build\temp.win-amd64-3.7\Release
C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.14.26428\bin\HostX86\x64\cl.exe /c /nologo /Ox /W3 /GL /DNDEBUG /MD -IC:\Python\Python37\lib\site-packages\numpy\core\include -IC:\Python\Python37\include -IC:\Python\Python37\include "-IC:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.14.26428\ATLMFC\include" "-IC:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.14.26428\include" "-IC:\Program Files (x86)\Windows Kits\NETFXSDK\4.6.1\include\um" "-IC:\Program Files (x86)\Windows Kits\10\include\10.0.17134.0\ucrt" "-IC:\Program Files (x86)\Windows Kits\10\include\10.0.17134.0\shared" "-IC:\Program Files (x86)\Windows Kits\10\include\10.0.17134.0\um" "-IC:\Program Files (x86)\Windows Kits\10\include\10.0.17134.0\winrt" "-IC:\Program Files (x86)\Windows Kits\10\include\10.0.17134.0\cppwinrt" "-IC:\Program Files (x86)\Windows Kits\10\Include\10.0.10240.0\ucrt" "-IC:\Program Files (x86)\Windows Kits\10\Include\10.0.10240.0\shared" -IC:\opencv3.4.0\sources\include\opencv2 -IC:\opencv3.4.0\sources\include -IC:\opencv3.4.0\build\include\opencv2 -IC:\opencv3.4.0\build\include -IC:\opencv\build\include /Tcbbox.c /Fobuild\temp.win-amd64-3.7\Release\bbox.obj -Wno-cpp -Wno-unused-function
cl : コマンド ライン error D8021 : 数値型引数 '/Wno-cpp' は無効です。
error: command 'C:\\Program Files (x86)\\Microsoft Visual Studio\\2017\\Community\\VC\\Tools\\MSVC\\14.14.26428\\bin\\HostX86\\x64\\cl.exe' failed with exit status 2
Makefile:2: recipe for target 'all' failed
mingw32-make: *** [all] Error 1

C:\github\CornerNet-Lite\core\external>
~~~

まだ、エラーが出る。数値型引数 '/Wno-cpp' は無効です。なんて言われるので、
とりあえず、C:\github\CornerNet-Lite\core\external\setup.py の

~~~
extra_compile_args=['-Wno-cpp', '-Wno-unused-function']
~~~

コンパイルオプションが無効なんだからいらないよね？ってことで

~~~
extra_compile_args=[]
~~~

として引数を無くしてしまい再実行する。

~~~
C:\github\CornerNet-Lite\core\external>mingw32-make

～～～～
途中省略
～～～～
md64.lib
   ライブラリ build\temp.win-amd64-3.7\Release\nms.cp37-win_amd64.lib とオブジェクト build\temp.win-amd64-3.7\Release\nms.cp37-win_amd64.exp を作成 中
コード生成しています。
コード生成が終了しました。
rm -rf build
~~~

で生成がうまくいく。

## モデルファイルの取得

トレーニングデータは、MS COCOです。
https://github.com/princeton-vl/CornerNet-Lite#training-and-evaluation

[ドキュメント](https://github.com/princeton-vl/CornerNet-Lite#downloading-models) にあるように作成済の３つのモデルファイルを取得して配置しています。

### CornerNet-Saccade
CornerNet-Saccade model CornerNet_Saccade_500000.pkl（447M）
https://drive.google.com/file/d/1MQDyPRI0HgDHxHToudHqQ-2m8TVBciaa/view?usp=sharing
をダウンロードして下記に配置する。

~~~
C:\github\CornerNet-Lite\cache\nnet\CornerNet_Saccade\
~~~

### CornerNet-Squeeze
CornerNet-Squeeze model CornerNet_Squeeze_500000.pkl（122M）
https://drive.google.com/file/d/1qM8BBYCLUBcZx_UmLT0qMXNTh-Yshp4X/view?usp=sharing
をダウンロードして下記に配置する。

~~~
C:\github\CornerNet-Lite\cache\nnet\CornerNet_Squeeze\
~~~

### CornerNet
CornerNet model CornerNet_500000.pkl（768M）
https://drive.google.com/file/d/1e8At_iZWyXQgLlMwHkB83kN-AN85Uff1/view?usp=sharing
をダウンロードして下記に配置する。

~~~
C:\github\CornerNet-Lite\cache\nnet\CornerNet\
~~~


## デモの実行

以下のコマンドを実行する。

~~~
C:\github\CornerNet-Lite>python demo.py
Traceback (most recent call last):
  File "demo.py", line 7, in <module>
    detector = CornerNet_Saccade()
  File "C:\github\CornerNet-Lite\core\detectors.py", line 38, in __init__
    from .test.cornernet_saccade import cornernet_saccade_inference
  File "C:\github\CornerNet-Lite\core\test\__init__.py", line 1, in <module>
    from .cornernet import cornernet
  File "C:\github\CornerNet-Lite\core\test\cornernet.py", line 7, in <module>
    from tqdm import tqdm
ModuleNotFoundError: No module named 'tqdm'

C:\github\CornerNet-Lite>
~~~

ModuleNotFoundError: No module named 'tqdm'　というエラーなので、pipでtqdmをインストールする。

~~~
C:\>pip3 install tqdm
Collecting tqdm
  Downloading https://files.pythonhosted.org/packages/72/c9/7fc20feac72e79032a7c8138fd0d395dc6d8812b5b9edf53c3afd0b31017/tqdm-4.41.1-py2.py3-none-any.whl (56kB)
     |████████████████████████████████| 61kB 4.1MB/s
Installing collected packages: tqdm
Successfully installed tqdm-4.41.1

C:\>
~~~

で、再実行してみる。

~~~
C:\github\CornerNet-Lite>python demo.py
total parameters: 116969339
loading from C:\github\CornerNet-Lite\core\..\cache\nnet\CornerNet_Saccade\CornerNet_Saccade_500000.pkl
C:\Python\Python37\lib\site-packages\torch\nn\functional.py:2506: UserWarning: Default upsampling behavior when mode=bilinear is changed to align_corners=False since 0.4.0. Please specify align_corners=True if the old behavior is desired. See the documentation of nn.Upsample for details.
  "See the documentation of nn.Upsample for details.".format(mode))
~~~

C:\github\CornerNet-Lite に以下のファイルが作成される。

demo_out.jpg 
![demo_out.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/255677/71ed0077-79cb-1b21-aae2-9b46a8c1de59.jpeg)
こんな感じでちゃんとボルゾイは犬と認識して、SUPはサーフボード、人(オイラ)も認識している。

ログを見ると

~~~
loading from C:\github\CornerNet-Lite\core\..\cache\nnet\CornerNet_Saccade\CornerNet_Saccade_500000.pkl
~~~

となっている。
CornerNet-Saccade を使っていて yolo v3 より速いという話題の CornerNet-Squeeze ではないので、demo.py を変更してみる。

~~~python:demo.py
#!/usr/bin/env python

import cv2
from core.detectors import CornerNet_Squeeze
from core.vis_utils import draw_bboxes

detector = CornerNet_Squeeze()

# image    = cv2.imread("demo.jpg")
image    = cv2.imread("max_kun.jpg")

bboxes = detector(image)
image  = draw_bboxes(image, bboxes)
cv2.imwrite("demo_out_max_kun.jpg", image)
~~~

で、実行する。

~~~
C:\github\CornerNet-Lite>python demo2.py
total parameters: 31771852
loading from C:\github\CornerNet-Lite\core\..\cache\nnet\CornerNet_Squeeze\CornerNet_Squeeze_500000.pkl

C:\github\CornerNet-Lite>
~~~

結果はこんな感じ。
![demo_out2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/255677/485f9d3d-3897-3372-f5f7-c64c60c11e2b.jpeg)
うむぅ。物体認識以前に物体検出ができていない。
しかも、キーラちゃんを鳥と認識している。精度はイマイチかも？？？

## AP (Average Precision、平均適合率)

[ドキュメント](https://opencv.org/latest-trends-in-object-detection-from-cornernet-to-centernet-explained-part-ii-cornernet-lite/) のCOCOデータのAPを見ると、yolo v3 より高いんだけどな？
![compare-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/255677/577189a5-abb8-80ff-e946-0881a7ff2c86.png)

YOLOv3 　39 msで33.0％　
CornerNet-Squeezeは、30 msで34.4％
CornerNet-Saccadeは、190 msで43.2％

って感じで精度が高くなっていってます。

![f4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/255677/d69c61b2-eec5-0f80-cc5e-3650277992ad.png)

yolo v3 で認識させたときの画像は↓こんな感じです。
![yolov3_max_kun.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/255677/c4201c7a-2d4a-b26e-f6ec-6222c7f9ea23.png)

yolo v3 を pytorch で動かしたときの記事はこちら↓参照。
https://qiita.com/goodboy_max/items/b75bb9eea52831fcdf15

CornerNet-Squeeze は COCOデータと異なる画像を物体認識させ応用するとイマイチなんだろうか？
画像が荒かったから？
それともコンパイルオプション取っちゃったから？？？

謎は深まるばかり・・・

## 参考情報
https://opencv.org/latest-trends-in-object-detection-from-cornernet-to-centernet-explained-part-ii-cornernet-lite/
https://engineer.dena.jp/2019/07/cv-papers-19-keypoint-object-detection.html
https://qiita.com/sounansu/items/9a6caf1ac5e78aefaeae
https://qiita.com/pashango2/items/45cb85390193d97523ca