はじめに
今回は、物体検出のためのライブラリYOLOv3を紹介する。アルゴリズムの説明はせず、導入手順、オリジナル画像を訓練する手順、その後の予測手順を示す。
環境
動作確認した環境は以下の通り。
導入手順
とても簡単である。このサイトに記載されているように以下を実行すれば良い。
1 2 3 |
$> git clone https://github.com/pjreddie/darknet $> cd darknet $> make |
GPUをサポートしたい場合は、ディレクトリdarknet内のMakefileに記載されている「GPU=0」を「GPU=1」に変更したのちmakeすれば良い(ここを参照のこと)。
GPU=1
CUDNN=0
OPENCV=0
OPENMP=0
DEBUG=0ARCH= -gencode arch=compute_30,code=sm_30 \
-gencode arch=compute_35,code=sm_35 \
-gencode arch=compute_50,code=[sm_50,compute_50] \
-gencode arch=compute_52,code=[sm_52,compute_52]
# -gencode arch=compute_20,code=[sm_20,sm_21] \ This one is deprecated?
…
YOLOv3はC言語とCUDAで実装されている。GPUをサポートしたい場合はあらかじめCUDAのドライバをインストールしておく必要がある。私の環境ではCPU版(Mac)、GPU版(EC2インスタンスp2.xlarge)ともに上の手順でコンパイルすることができた。
訓練手順
おおまかな手順は以下の通り。
- 訓練・テスト画像へのパスが記載されたファイルを作る。
- ラベルを記載したファイルを作る。
- 設定ファイルを記述する。
- 訓練コマンドを実行する。
以下詳細を示す。
訓練・テスト画像へのパスが記載されたファイルの作成
それぞれのファイル名をtrain.txt、test.txtとする(名前は任意である)。train.txtの中身は以下の通り。
/root/data/yolov3/images/0010.jpg
/root/data/yolov3/images/0144.jpg
/root/data/yolov3/images/0043.jpg
/root/data/yolov3/images/0026.jpg
…
訓練画像へのパスを羅列したものである。また、各画像の物体位置を記載したファイルを画像ファイル名と同じ名前(拡張子のみtxtとする)で、同じディレクトリ内に作成しておく。上の例で言えば、ディレクトリ /root/data/yolov3/images内に、0010.txtや0144.txtなどを保存する。0010.txtの中身は以下の通り。
0 0.601302 0.521296 0.261979 0.496296
3 0.301302 0.721296 0.361979 0.696296
5 0.901302 0.221296 0.161979 0.396296
…
1行にひとつの矩形を記載する。各行のフォーマットは以下の通り。
<ラベル> <矩形の中心座標x/画像幅> <矩形の中心座標y/画像高さ> <矩形の幅/画像幅> <矩形の高さ/画像高さ>
数値は画像の幅と高さで正規化されていることに注意する。数値は空白で区切られる。test.txtについても同じことを繰り返す。
ラベルを記載したファイルの作成
ここではclasses.txtとする(名前は任意である)。その中身は以下の通り。
person
bicycle
car
motorbike
aeroplane
bus
train
truck
boat
traffic light
…
上から順に0,1,..のように整数値に変換されて使われる。
設定ファイルの作成
設定ファイルは以下の2つである。
- mytrain.data
- mytrain.cfg
いずれも名前は任意である。
mytrain.data
このファイルの中身は以下の通り。
classes = 20
train = /root/data/train.txt
test = /root/data/test.txt
names = /root/data/classes.txt
backup = /root/data/backup
classesにはクラス数を、次の3行には前述した3つのファイルへのパスを、backupには出力ファイルを保存するディレクトリへのパスを記載する(このファイルのサンプルはダウンロードしたディレクトリdarknet/cfg内にある)。
mytrain.cfg
このファイルのサンプルはダウンロードしたディレクトリdarknet/cfg内にある。いずれかを参考にして記述すれば良い。このファイルに記載されるのは訓練時に使われるハイパーパラメータであるが、クラス数に応じて変更しなければならない行がある。例えば、cfg/yolov3-voc.cfgをベースにするなら
- 605行目:filters=75
- 611行目:classes=20
- 689行目:filters=75
- 695行目:classes=20
- 773行目:filters=75
- 779行目:classes=20
を書き換える。classes=3とするなら、filters=24(=classes+5)*3)とする。また、このファイルの先頭にある以下の部分
[net]
# Testing
batch=1
subdivisions=1
# Training
#batch=64
#subdivisions=16
…
は、テスト・訓練時のバッチサイズ(batch)とそれを何分割するか(subdivisions)を指定している。テスト・訓練に応じてコメントアウト・インする。これらの数値は適当に調節する。さらに、このファイルにはmax_batchesというパラメータがある。このパラメータには、訓練データ数をバッチサイズ単位で数えたときの数を記載する(cfg/yolov3-voc.cfgのmax_batchesには大変大きな値(50200)が設定されているので注意が必要である)。
訓練コマンドの実行
以下を実行する。
1 |
<pre wp-pre-tag-1=""> |
gt; /root/buildspace/darknet/darknet detector \
train \
cfg/mytrain.data \
cfg/mytrain.cfg \
/root/data/voc/models/darknet53.conv.74
3行目と4行目は前述したファイルへのパスである。5行目には訓練済みモデルへのパスを指定する。ここに従って以下のコードでダウンロードしておく。
1 |
<pre wp-pre-tag-2=""> |
gt; wget https://pjreddie.com/media/files/darknet53.conv.74
上のコードを実行すると、標準出力にログを表示しながら訓練が始まる。nanが混じるが気にする必要はない。nanが頻繁に表示されても経験上訓練はできている。
予測手順
訓練が終わると、backupに指定したディレクトリ内にmytrain.backupとmytrain_final.weightsという名前のファイルができている。前者は再学習する際に使うファイルである。上の訓練コマンドの /root/data/voc/models/darknet53.conv.74の代わりにmytrain.backupを指定すれば前回の続きから学習を始めることができる。mytrain_final.weightsは予測時に使う重みである。ダウンロードしたディレクトリdarknet/python内にあるdarknet.pyをベースにすれば予測コードをPythonで記述することができる。
まとめ
今回は、YOLOv3を用いてオリジナル画像で訓練し、Pythonコードで予測する手順を示した。大変良くできたライブラリである。