Mac OS上でdarknet YOLOv4をビルドして使ってみたのですが、Mac OS向けの情報がネット上にあまりに少なかったので、記事にすることにしました。
なぜ情報があまりなかったか?、というと、WindowsやLinux環境で構築するのが一般的になっていて、Mac OS環境を好んで使う変人があまりいないから、なのですが。😝
なぜMac環境でやる人は変人扱いされるのかというと、
- darknet YOLOv4は並列処理アーキテクチャとしてCUDAのみサポートしている
- CUDAはNVIDIAのGPU以外はサポートしていない
- そして最近のMacマシンのグラフィックスカードはRadeonである
- よってMacではGPUを使った平行処理ができない
つまり学習も物体検出も、Macだとめちゃめちゃ遅い、というデメリットがあるからなんですね。
そんななか、うちにMacマシンしかなかったので、まぁMacでもいいかって感じでやってみました。
べつにビルドできないとか動作しないという訳ではないので、僕のようなMac党人間の方はためらわずMacにインストールしてみるといいですよ。(みちづれ狙い😋)
試行錯誤の末ようやくできたわけですが、いきなり手順だけ読まされても「なんでその工程が必要なんだー!」ってなっちゃうと思います。
なので理由や概念的な説明もかるく交えながら書きました。
shellの基本的な扱いができる方であればそこそこストレスなく読み進めることができると思います。
インストール手順
さっそくMac OSにインストールしていきましょう。
参考になる情報は、How to compile on Linux/macOS (using CMake
)にある短い説明です。
あと、Requirementsも何となく参考になりました。
その他は手探りで実施です。
前提環境
インストール作業ではMacのパッケージ管理システムHomebrewを使います。インストールしていない人は、先にインストールしましょう。
(%はシェル待機文字を表しているのでコピペするなら/bin/bashからです😊)
% /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
Homebrewについて詳しく知りたい人は公式サイトをどうぞ。
最新ソースコードを取得
まずはGitHubから最新ソースコードを取得します。
Gitをインストールしていない人は先にインストールしましょう。
続いてGitHubからソースコードを取得します。
% git clone https://github.com/AlexeyAB/darknet.git
作成されたディレクトリに移動しておきましょう。
% cd darknet
% ld -l
total 352
drwxr-xr-x 4 dimaru staff 128 4 3 13:22 3rdparty
-rw-r--r-- 1 dimaru staff 21433 4 3 13:22 CMakeLists.txt
-rw-r--r-- 1 dimaru staff 1373 4 3 13:22 DarknetConfig.cmake.in
-rw-r--r-- 1 dimaru staff 515 4 3 13:22 LICENSE
-rw-r--r-- 1 dimaru staff 5938 4 3 13:22 Makefile
-rw-r--r-- 1 dimaru staff 59454 4 3 13:22 README.md
drwxr-xr-x 3 dimaru staff 96 4 3 13:22 build
-rwxr-xr-x 1 dimaru staff 7878 4 3 13:22 build.ps1
-rwxr-xr-x 1 dimaru staff 1960 4 3 13:22 build.sh
drwxr-xr-x 92 dimaru staff 2944 4 3 13:22 cfg
drwxr-xr-x 3 dimaru staff 96 4 3 13:22 cmake
-rw-r--r-- 1 dimaru staff 10334 4 3 13:22 darknet.py
-rw-r--r-- 1 dimaru staff 9467 4 3 13:22 darknet_images.py
-rw-r--r-- 1 dimaru staff 5227 4 3 13:22 darknet_video.py
drwxr-xr-x 17 dimaru staff 544 4 3 13:22 data
-rwxr-xr-x 1 dimaru staff 110 4 3 13:22 image_yolov3.sh
-rwxr-xr-x 1 dimaru staff 110 4 3 13:22 image_yolov4.sh
drwxr-xr-x 4 dimaru staff 128 4 3 13:22 include
-rwxr-xr-x 1 dimaru staff 345 4 3 13:22 json_mjpeg_streams.sh
-rwxr-xr-x 1 dimaru staff 159 4 3 13:22 net_cam_v3.sh
-rwxr-xr-x 1 dimaru staff 159 4 3 13:22 net_cam_v4.sh
drwxr-xr-x 3 dimaru staff 96 4 3 13:22 results
drwxr-xr-x 25 dimaru staff 800 4 3 13:22 scripts
drwxr-xr-x 143 dimaru staff 4576 4 3 13:22 src
-rw-r--r-- 1 dimaru staff 366 4 3 13:22 vcpkg.json
-rwxr-xr-x 1 dimaru staff 108 4 3 13:22 video_yolov3.sh
-rwxr-xr-x 1 dimaru staff 108 4 3 13:22 video_yolov4.sh
CMakeLists.txtを編集する
Mac OSでは、build.shを実行することでビルドが実行されます。build.shが実行されるとcmakeを使ってビルドされるわけですが、その前にビルドオプションをMac OS用に変更しておく必要があります。
というわけでcmakeの設定ファイルであるCMakeLists.txtに修正を加えます。
% brew install nano
% nano CMakeLists.txt
変更するのはoption()形式の部分だけで、着色してある部分が今回の変更箇所です。
CMakeLists.txt抜粋
option(CMAKE_VERBOSE_MAKEFILE "Create verbose makefile" ON)
option(CUDA_VERBOSE_BUILD "Create verbose CUDA build" OFF)
option(BUILD_SHARED_LIBS "Create dark as a shared library" ON)
option(BUILD_AS_CPP "Build Darknet using C++ compiler also for C files" OFF)
option(BUILD_USELIB_TRACK "Build uselib_track" ON)
option(MANUALLY_EXPORT_TRACK_OPTFLOW "Manually export the TRACK_OPTFLOW=1 define" OFF)
option(ENABLE_OPENCV "Enable OpenCV integration" ON)
option(ENABLE_CUDA "Enable CUDA support" OFF)
option(ENABLE_CUDNN "Enable CUDNN" OFF)
option(ENABLE_CUDNN_HALF "Enable CUDNN Half precision" OFF)
option(ENABLE_ZED_CAMERA "Enable ZED Camera support" OFF)
option(ENABLE_VCPKG_INTEGRATION "Enable VCPKG integration" OFF)
Mac OS環境ではCUDAが使えないため、CUDA関連を利用するオプションはことごとくOFFにしてあります。CUDNNはCuda Deep Neural Networkで、CUDAを前提にしたアーキテクチャなので、これもOFFにしました。
ENABLE_ZED_CAMERAはカメラのオプションのようですが、どうせCUDAを使わないならカメラからの入力をリアルタイムに検出する性能は出せないだろうし、有効にした時に必要な追加ライブラリを調べるのも面倒だったので、OFFにしています。
ENABLE_VCPKG_INTEGRATIONはOFFに変更していますが、Homebrewで手間なく必要な依存関係をインストールできるので、不要と判断しました。(Windowsなら使ったほうが楽)
変更できたら、保存して閉じます。
nanoで保存して閉じる方法
- Control + X (閉じるコマンド)
- Shift + Y (Y=保存して閉じる, N=保存しないで閉じる)
- Return (ファイル名は上書きなのでそのまま)
必要なパッケージをインストールする
さて、ビルドする前にいくつかパッケージをインストールしておく必要があります。インストールしない状態でビルドしようとすると、
% ./build.sh
./build.sh: line 57: cmake: command not found
./build.sh: line 58: cmake: command not found
usage: cp [-R [-H | -L | -P]] [-fi | -n] [-apvXc] source_file target_file
cp [-R [-H | -L | -P]] [-fi | -n] [-apvXc] source_file ... target_directory.
こんな感じで怒られてはインストールして、の繰り返しになります。😅
ということであらかじめインストール。
% brew install cmake opencv
インストールにはそれなりの時間がかかります。
cmakeとopencvそれぞれの説明を軽くしておきます。読みながら処理が終わるのを待ちましょう。
cmake
cmakeは、ビルドの自動化ツールです。
もともとC言語やC++で書かれたプログラムをコンパイルしたりリンクしたりするのはclangやgccなどのコンパイラだけでも行えるのですが、.cファイル、.hファイル、.oファイル、.soファイル(Windowsでいう.libファイル)など、気が遠くなるようなファイルをリンクしなければいけません。
そこでmakeというツールを使うことで、それぞれ依存関係を記述したMakefileという設定ファイルに基づき自動化していました。しかし設定ファイルであるMakefileを作るのもかなり大変だなってことで、色々と進化させたのがcmakeです。(最後の部分めっちゃ雑な説明😅)
ちなみに僕はCもC++もほとんど触ったことがないので、上記説明はdarknetをビルドするために調べた内容です、はい。
opencv
画像処理・画像解析用ライブラリです。
CMakeFiles.txtのオプションでOFFにすることもできるみたいです。
これをOFFにしてビルドすると、Augumentation warningが出ました。この警告だけをみる限り、普通の学習や物体検出には影響がなく、学習データを増殖させる時だけ影響があるように思えるけど真相はわかりません。てことで思考停止してONにしておきましょう。
ビルドする
下準備ができたらいよいよビルドです。
なんかwarningがけっこう表示されるかもしれないけど、気にしない、気にしない。
実行ファイル darknet が出来上がっていればビルドは成功です。
% ls -l
total 6320
drwxr-xr-x 4 dimaru staff 128 4 3 13:22 3rdparty
-rw-r--r-- 1 dimaru staff 21438 4 3 13:55 CMakeLists.txt
-rw-r--r-- 1 dimaru staff 1373 4 3 13:22 DarknetConfig.cmake.in
-rw-r--r-- 1 dimaru staff 515 4 3 13:22 LICENSE
-rw-r--r-- 1 dimaru staff 5938 4 3 13:22 Makefile
-rw-r--r-- 1 dimaru staff 59454 4 3 13:22 README.md
drwxr-xr-x 3 dimaru staff 96 4 3 13:22 build
-rwxr-xr-x 1 dimaru staff 7878 4 3 13:22 build.ps1
-rwxr-xr-x 1 dimaru staff 1960 4 3 13:22 build.sh
drwxr-xr-x 11 dimaru staff 352 4 3 15:46 build_release
drwxr-xr-x 92 dimaru staff 2944 4 3 13:22 cfg
drwxr-xr-x 3 dimaru staff 96 4 3 13:22 cmake
-rwxr-xr-x 1 dimaru staff 1311344 4 3 15:46 darknet
-rw-r--r-- 1 dimaru staff 10334 4 3 13:22 darknet.py
-rw-r--r-- 1 dimaru staff 9467 4 3 13:22 darknet_images.py
-rw-r--r-- 1 dimaru staff 5227 4 3 13:22 darknet_video.py
drwxr-xr-x 17 dimaru staff 544 4 3 13:22 data
-rwxr-xr-x 1 dimaru staff 110 4 3 13:22 image_yolov3.sh
-rwxr-xr-x 1 dimaru staff 110 4 3 13:22 image_yolov4.sh
drwxr-xr-x 5 dimaru staff 160 4 3 14:38 include
-rwxr-xr-x 1 dimaru staff 345 4 3 13:22 json_mjpeg_streams.sh
-rwxr-xr-x 1 dimaru staff 1303848 4 3 15:46 libdarknet.dylib
-rwxr-xr-x 1 dimaru staff 159 4 3 13:22 net_cam_v3.sh
-rwxr-xr-x 1 dimaru staff 159 4 3 13:22 net_cam_v4.sh
drwxr-xr-x 3 dimaru staff 96 4 3 13:22 results
drwxr-xr-x 25 dimaru staff 800 4 3 13:22 scripts
drwxr-xr-x 3 dimaru staff 96 4 3 14:38 share
drwxr-xr-x 143 dimaru staff 4576 4 3 15:46 src
-rwxr-xr-x 1 dimaru staff 216528 4 3 14:38 uselib
-rwxr-xr-x 1 dimaru staff 216528 4 3 14:38 uselib_track
-rw-r--r-- 1 dimaru staff 366 4 3 13:22 vcpkg.json
-rwxr-xr-x 1 dimaru staff 108 4 3 13:22 video_yolov3.sh
-rwxr-xr-x 1 dimaru staff 108 4 3 13:22 video_yolov4.sh
GitHubからcloneしてきた時は352ファイルだったのが6320ファイルになっているので、ほかにも色々とファイルが作成されているのでしょう。細かいことは知らんです。
使ってみる
ヘルプを見てみる
% ./darknet -h
GPU isn't used
OpenCV version: 4.5.2
Not an option: -h
GPUの活用は無効になっていて、OpenCVは4.5.2が使えるようになっていることがわかります。
ちなみに ./darknet -h としましたが、実際は -h オプションも --help オプションも受け付けてくれず、コマンド引数の詳細を調べることはできません。何もオプションを付けずに実行すると本当に参考にならないシンタックス説明が表示されるのみです。
% ./darknet
usage: ./darknet <function>
画像から物体検出してみる
使い方についてはHow to use on the command lineに書かれているサンプルだけが頼りなので、こちらを参考に画像からの物体検出をしてみましょう。
% ./darknet detector test cfg/coco.data cfg/yolov4.cfg yolov4.weights -thresh 0.25
Loading weights from yolov4.weights...Couldn't open file: yolov4.weights
yolov4.weightsが無いと言われてしまいました。
yolov4.weightsは、How to evaluate FPS of YOLOv4 on GPUにあるyolov4.weightsのリンクからダウンロードすることができます。(初見ごろしやな)
リンクから直接ダウンロードするなら、
% brew install wget
% wget https://github.com/AlexeyAB/darknet/releases/download/darknet_yolo_v3_optimal/yolov4.weights
とすればカレントディレクトリにDLできます。(URLは2021.4.3時点で有効なもの)
DLできたら気を取り直して画像から物体検出してみましょう。
GitHubからcloneしたdarknet/dataフォルダには、サンプル用の画像ファイルが入っています。検出対象として指定することになるので、どんなファイルがあるか見ておきます。
% ls -l data
total 3432
-rw-r--r-- 1 dimaru staff 140047 4 3 16:29 9k.tree
-rw-r--r-- 1 dimaru staff 625 4 3 16:29 coco.names
-rw-r--r-- 1 dimaru staff 387 4 3 16:29 coco9k.map
-rw-r--r-- 1 dimaru staff 163759 4 3 16:29 dog.jpg
-rw-r--r-- 1 dimaru staff 141886 4 3 16:29 eagle.jpg
-rw-r--r-- 1 dimaru staff 382965 4 3 16:29 giraffe.jpg
-rw-r--r-- 1 dimaru staff 80 4 3 16:29 goal.txt
-rw-r--r-- 1 dimaru staff 133495 4 3 16:29 horses.jpg
-rw-r--r-- 1 dimaru staff 218420 4 3 16:29 imagenet.labels.list
-rw-r--r-- 1 dimaru staff 246356 4 3 16:29 imagenet.shortnames.list
drwxr-xr-x 763 dimaru staff 24416 4 3 16:29 labels
-rw-r--r-- 1 dimaru staff 5476 4 3 16:29 openimages.names
-rw-r--r-- 1 dimaru staff 113880 4 3 16:29 person.jpg
-rw-r--r-- 1 dimaru staff 174515 4 3 16:29 scream.jpg
-rw-r--r-- 1 dimaru staff 135 4 3 16:29 voc.names
いざ、検出開始。引数にdata/dog.jpgを指定してみました。
% ./darknet detector test cfg/coco.data cfg/yolov4.cfg yolov4.weights -thresh 0.25 data/dog.jpg
...略...
[yolo] params: iou loss: ciou (4), iou_norm: 0.07, obj_norm: 1.00, cls_norm: 1.00, delta_norm: 1.00, scale_x_y: 1.05
nms_kind: greedynms (1), beta = 0.600000
Total BFLOPS 128.459
avg_outputs = 1068395
Loading weights from yolov4.weights...
seen 64, trained: 32032 K-images (500 Kilo-batches_64)
Done! Loaded 162 layers from weights-file
Detection layer: 139 - type = 28
Detection layer: 150 - type = 28
Detection layer: 161 - type = 28
data/dog.jpg: Predicted in 16170.291000 milli-seconds.
bicycle: 91%
dog: 98%
truck: 92%
pottedplant: 32%
すると検出結果がウィンドウで表示される。
ちゃんと検出できています!でもやっぱりGPUが使えないと遅い!😂