Darknet Install 備忘録

#概要
[YOLOモデル](https://pjreddie.com/darknet/yolo/)を評価したかったので、Darknetをインストールした。

- 実施時期：2019年12月
- OS: Ubuntu18.04LTS
- cmake: 3.10.2
- CUDA: 10.2　　　　←cuDNNともに前に[インストール済み](https://qiita.com/ShinichiroImoto/items/29fd068de6744b516c0d)
- cuDNN: 7.6.5
- CC (Compute capability GTX1070): 6.1
- OPENCV: 3.4.8　　 ←前に[インストール済み](https://qiita.com/ShinichiroImoto/items/4a220882d2e4446f740a)


##インストール
試行錯誤の結果、最終的に下記のDarknetに行き着き、これをインストールする。
https://github.com/AlexeyAB/darknet
Darknetは上記以外に次の２つも試したが、このAlexeyABの解説がとても丁寧でよかった。Q&Aも豊富。

- [YOLOオフィシャル](https://github.com/pjreddie/darknet)
- GPUを使わない[NNPACK](https://github.com/digitalbrain79/darknet-nnpack)

ちなみに、NNPACKはNinjaのインストールやコンパイルが必要で、[AWS](https://aws.amazon.com/jp/blogs/news/speeding-up-apache-mxnet-using-the-nnpack-library/)の手順も見ながらコンパイルできた。GPU+CUDAがインストールできればNNPACKは必要ない。
要は、cloneしたninjaフォルダ内のbuild.ninjaファイルへ次の2行の追加編集が必要。

```terminal
cflags = -std=gnu99 -g -pthread -fPIC
cxxflags = -std=gnu++11 -g -pthread -fPIC
```
おいらの場合、最終的にGPUがないエッジ端末に再教育したYOLOを置くときはOPEN VINOを使うつもりなので、やはりNNPACKは不要。

##コンパイル
まず、クローンする。

```terminal
$ git clone https://github.com/AlexeyAB/darknet.git
```

home直下にdarknetのフォルダができるので、そこで作業する。
実際cloneするとdarkentのフォルダに鍵マークが付いた。
rootとhomeのユーザに権限制限はないそうだがchmod 777してもマークが取れず、気持ちが悪かったのでこれは削除(rm -r)した。
クローンではなく"Download ZIP"ボタンをポチって、解凍してできたdarknetフォルダをhome直下にコピー(cp -r)した。

make条件が書かれているMakefileを編集する。

```terminal
$ cd darknet
$ sudo vim Makefile
```
Makefile中でEnable(=1)にするのは、GPU, CUDNN, OPENCV
GPU=1
CUDNN=1
CUDNN_HALF=0
OPENCV=1
AVX=0
OPENMP=0
LIBSO=0
ZED_CAMERA=0

また、いま生きている"ARCH="をコメントアウトして、環境に合わせてその下行にあるコメントアウトされている"#ARCH="を生かす。

\#GTX 1080, GTX 1070, GTX 1060, GTX 1050, GTX 1030, Titan Xp, Tesla P40, Tesla P4
ARCH= -gencode arch=compute_61,code=sm_61 -gencode arch=compute_61,code=compute_61

上書き保存(:wq!)してmakeする。
元々の"ARCH="でmakeしてもその後の動作に問題はなかったが、環境に合わせた"ARCH="に変更すると、make時間が短くなった気がする。

```terminal
$ sudo make
Makefile:171: recipe for target 'obj/convolutional_kernels.o' failed
make: *** [obj/convolutional_kernels.o] Error 127
```

会社の環境だとすんなりmakeできたが、家ではエラーが出た。pjreddieのdarknetでも同じエラーが出る。
試しに、GPU, CUDNNを0にすると問題なし。

GithubでCloseした[ケース](https://github.com/pjreddie/darknet/issues/200)があり、下記のようにMakefileを編集するとエラーは出なくなりmakeは成功した。

```terminal
#NVCC=nvcc
NVCC=/usr/local/cuda/bin/nvcc
```

CUDAのインストールが正しくなかったのだろうか。

##確認
ここではdarknet/dataフォルダに入っていた犬のjpgファイルで動作確認を行う。
Yolov3モデルで事前に教育済みのウェイトが必要だが、AlexeyABのdarknetには入っていなかったので、pjreddieのdarknetに入っていたyolov3.weightsをdarknetフォルダ直下にコピーしておく。
そして前段でmakeした実行ファイルで犬を検出させる。

```terminal
$./darknet detect cfg/yolov3.cfg yolov3.weights data/dog.jpg
 CUDA-version: 10020 (10020), cuDNN: 7.6.5, GPU count: 1  
 OpenCV version: 3.4.8
net.optimized_memory = 0 
batch = 1, time_steps = 1, train = 0 
   layer   filters  size/strd(dil)      input                output
   0 conv     32       3 x 3/ 1    416 x 416 x   3 ->  416 x 416 x  32 0.299 BF
   1 conv     64       3 x 3/ 2    416 x 416 x  32 ->  208 x 208 x  64 1.595 BF
   2 conv     32       1 x 1/ 1    208 x 208 x  64 ->  208 x 208 x  32 0.177 BF
   3 conv     64       3 x 3/ 1    208 x 208 x  32 ->  208 x 208 x  64 1.595 BF
   4 Shortcut Layer: 1,  wt = 0, wn = 0, outputs: 208 x 208 x  64 0.003 BF
/***  中略  ***/
 104 conv    256       3 x 3/ 1     52 x  52 x 128 ->   52 x  52 x 256 1.595 BF
 105 conv    255       1 x 1/ 1     52 x  52 x 256 ->   52 x  52 x 255 0.353 BF
 106 yolo
[yolo] params: iou loss: mse (2), iou_norm: 0.75, cls_norm: 1.00, scale_x_y: 1.00
Total BFLOPS 65.879 
avg_outputs = 532444 
 Allocate additional workspace_size = 52.43 MB 
Loading weights from yolov3.weights...
 seen 64, trained: 32013 K-images (500 Kilo-batches_64) 
Done! Loaded 107 layers from weights-file 
data/dog.jpg: Predicted in 25.815000 milli-seconds.
bicycle: 99%
dog: 100%
truck: 94%
```

結果のjpgが表示され、predictions.jpgとしてdarknetフォルダにできていれば成功

![predictions.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/205257/4a5c7dda-dea2-4f7c-6a20-0cc329d5aab5.jpg)

次回はいよいよモデル再教育とリアルタイムの検出に挑戦

以上