Yolo3、Tiny-Yolo3での独自学習方法
画像検出に向けて、独自に準備した教師データを用いて、AlexeyAB Darknetを用いて、YOLO3、Tiny-YOLO3で独自学習を行います。
YOLO3とTiny-YOLO3での独自学習時の違いは、独自学習時に指定するコンフィグファイルの違いのみとなります。処理速度と画像検出の違いとなっておりますが、画像検出対象により向き不向きもあると思うので、両方での試行をお勧めします。
また、YOLO2など以前のフレームワークも利用しましたが、画像検出精度や検出速度で、明らかにYOLO3のほうが良いので、学習後のモデル動作環境がYOLO3で問題なければ、YOLO3の利用をお勧めします。
参考にさせて頂いたサイト
前提条件
AlexeyAB Darknetを用いて、YOLO3・Tiny-YOLO3で独自学習に向けた準備
LabelImg利用方法(アノテーション)で準備した、7クラスの学習を行います。
最終的な、独自学習を実行する際のコマンドラインは以下となります。
darknet.exe detector train cfg/obj.data cfg/yolov3-voc-janken.cfg darknet53.conv.74
- darknet.exe
Windows10に AlexeyAB・Darknet・YOLO V3導入(Vestal Studio)でコンパイルした実行ファイル。(「darknet\build\darknet\x64」に格納されています) - obj.data(obj.data内で指定するobj.names)の2ファイル
- yolov3-voc-janken.cfg、yolo3, tiny-yolo3向けに事前準備されたモデル定義をコピーして独自学習向けに作成
- darknet53.conv.74、学習開始時の初期ウェイトファイル。yolo3とtiny-yolo3では異なるファイルを用います。
obj.dataに、train(学習データー)とvalid(検証データー)のリストを設定します。
このtrainとvalidのファイルリストは、LabelImg利用方法(アノテーション)でラベリングしたフォルダで、以下のスクリプト(process.py)を実行し、自動的に作成します。
process.pyですが、データファイルのパス指定、ファイル名、テストデータの割合を指定します。以下の例では、検証データを全体のファイル数の10%を検証データに指定されています。
import glob, os
# Current directory
current_dir = os.path.dirname(os.path.abspath(__file__))
# Directory where the data will reside, relative to 'darknet.exe'
path_data = 'data/obj/'
# Percentage of images to be used for the test set
percentage_test = 10;
# Create and/or truncate train.txt and test.txt
file_train = open('train.txt', 'w')
file_test = open('test.txt', 'w')
# Populate train.txt and test.txt
counter = 1
index_test = round(100 / percentage_test)
for pathAndFilename in glob.iglob(os.path.join(current_dir, "*.jpg")):
title, ext = os.path.splitext(os.path.basename(pathAndFilename))
if counter == index_test:
counter = 1
file_test.write(path_data + title + '.jpg' + "\n")
else:
file_train.write(path_data + title + '.jpg' + "\n")
counter = counter + 1
- train.txt トレーニング用画像ファイル一覧
- test.txt 検証用画像ファイル一覧
obj.data(obj.data内で指定するobj.names)の2ファイル
「darknet\build\darknet\x64\cfg\obj.data」ファイル
学習クラス数をClassに登録します。作成した、train.txtとtest.txtファイルパスを指定します。
次に作成する、cfg/obj.namesと学習結果を格納するフォルダbackupを指定します。
classes = 7
train = train.txt
valid = test.txt
names = cfg/obj.names
backup = backup/
「darknet\build\darknet\x64\cfg\obj.names」ファイル
学習クラス名一覧を指定します。
janken_active
janken_goo
janken_choki
janken_pa
janken_won
janken_lose
janken_draw
yolov3-voc-janken.cfg、yolo3, tiny-yolo3向けに事前準備されたモデル定義をコピーして独自学習向けに作成
Yolo3向けcfgファイル作成
「darknet\build\darknet\x64\cfg\」フォルダ内の初期ファイルをコピーして、自己学習向けのコンフィグファイルを作成します。yolov3.cfg、yolo-obj.cfgをコピー元ファイルとして、編集するコンフィグファイルを作成します。
- Batch数を変更します。
batch=64
- Subdivisionsを変更します。
subdivisions=8
- 学習するクラス数に合わせて、最大バッチ回数を指定します。
学習するクラス数×2000となります。
7クラスでの学習の際には、max_batches=14000
とします。 - Stepsを最大バッチ回数の80%と90%になるように修正します。
最大バッチ回数が14000の場合は、steps=11200,12600
とします。 - 3つある[yolo]レイヤーのClassesを、今回学習させる7に変更します。
- [yolo]レイヤー直前の[convolutional]レイヤーのfiltersを変更します。
filtersの値は、(classes + 5)×3とします。
7クラスの場合は、(7+5)×3=36を指定します。
Tiny-Yolo3向けcfgファイル作成
「darknet\build\darknet\x64\cfg\」フォルダ内の初期ファイルをコピーして、自己学習向けのコンフィグファイルを作成します。yolov3-tiny-obj.cfg、yolov3-tiny_obj.cfgをコピー元ファイルとして、編集するコンフィグファイルを作成します。
yolov3-tiny-obj.cfg
based on cfg/yolov3-tiny_obj.cfg
- Batch数を変更します。
batch=64
- Subdivisionsを変更します。
subdivisions=8
- 学習するクラス数に合わせて、最大バッチ回数を指定します。
学習するクラス数×2000となります。
7クラスでの学習の際には、max_batches=14000
とします。 - Stepsを最大バッチ回数の80%と90%になるように修正します。
最大バッチ回数が14000の場合は、steps=11200,12600
とします。 - 2つある[yolo]レイヤーのClassesを、今回学習させる7に変更します。
- [yolo]レイヤー直前の[convolutional]レイヤーのfiltersを変更します。
filtersの値は、(classes + 5)×3とします。
7クラスの場合は、(7+5)×3=36を指定します。
学習開始時の初期ウェイトファイル準備
Yolo3向け初期ウェイトファイルダウンロード
https://pjreddie.com/media/files/darknet53.conv.74よりdarknet53.conv.74ファイルをダウンロードします。ダウンロードしたdarknet53.conv.74ファイルが初期ウェイトファイルとなります。
darknet53.conv.74
Tiny-Yolo3向けウェイトファイルダウンロード
https://pjreddie.com/media/files/yolov3-tiny.weightsよりyolov3-tiny.weightsファイルをダウンロードし、darknet.exeおよび標準のcfgファイルを用いて、初期ウェイトファイルを準備します。
darknet.exe partial cfg/yolov3-tiny.cfg yolov3-tiny.weights yolov3-tiny.conv.15 15
yolov3-tiny.conv.15
AlexeyAB/DarknetでYOLO3トレーニング開始
最初に示したコマンドラインで自己学習を開始します。
darknet.exe detector train cfg/obj.data cfg/yolov3-voc-janken.cfg darknet53.conv.74
Out of Memory
Out of Memoryが出る場合、GPUのメモリ不足となり、設定ファイルの変更が必要となります。設定ファイルで設定した、 subdivisions=16
を「32」や「64」へ変更し実行可能な設定へ変更が必要です。
32の倍数での画像サイズの縮小でも学習時のメモリサイズを減らすことが出来ます。width=256、height=256 などへwidth, heightを変更。