ずっと昔にYolov3の独自データ学習をして以来、長らく物体検出手法の学習を試してませんでした。
が、業務上、新しい物体検出を使って独自データでの学習をする羽目になったため、久しぶりにやってみることにしました。
ここで使う手法はYOLOX、またアノテーションツールには「VoTT」を使います。
なお、YOLOXの独自データの学習にはGPUが必須、CUDAのインストール、PytorchもGPU版が必要です。
(0) YOLOXのダウンロード、前準備、動作確認
まずは、これを入手しておきましょう。
今回使うのは、以下のサイトから入手するYOLOXです。
GitHub - Megvii-BaseDetection/YOLOX: YOLOX is a high-performance anchor-free YOLO, exceeding yolov3~v5 with MegEngine, ONNX, TensorRT, ncnn, and OpenVINO supported. Documentation: https://yolox.readthedocs.io/
Windowsなら、「<>Code」をクリックして「Download ZIP」を選択すると、ZIPファイルがダウンロードされます。
これを解凍し、適当なフォルダに入れておきましょう。
(我が家では「C:\linux」というフォルダの直下に「YOLOX-main」として入れました)
まずはこれを使えるようにします。
Windows PowerShellを開き、「cd c:\linux\YOLO-main」と入力して上のフォルダに入ります。
我が家では「大規模言語モデル「ELYZA-7b」と自作小説「計算士と空中戦艦」で「RAG」をしてみた: EeePCの軌跡」の記事にある通り、CUDA 12.1を入れてあるので、
pip install torch==2.2.1 torchvision==0.17.1 torchaudio==2.2.1 --index-url https://download.pytorch.org/whl/cu121
と、PytorchのCUDA 12.1版を入れておきました。
それ以外にも、
numpy
opencv_python
loguru
tqdm
torchvision
thop
ninja
natsort
tabulate
psutil
tensorboard
辺りのライブラリも入れてください。
他にも「pycocotools」をインストールしなきゃならないんですが、これを入れるには「VS Build tools 2022」が必要です。
Microsoft C++ Build Tools - Visual Studio
(インストール方法は、「大規模言語モデル「ELYZA-7b」と自作小説「計算士と空中戦艦」で「RAG」をしてみた: EeePCの軌跡」の前準備を参照)
ついでに、環境変数に以下の設定を入れてください。
下の「検索」で「環境変数」とやると、環境変数の設定窓が開けるので、そこにあるPathに
C:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools\VC\Tools\MSVC\14.39.33519\bin\Hostx64\x64
C:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools\Common7\IDE
を加えます。
また、「LIB」という変数を作成し「C:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools\VC\Tools\MSVC\14.39.33519\lib\x64; C:\Program Files (x86)\Windows Kits\10\Lib\10.0.22621.0\ucrt\x86; C:\Program Files (x86)\Windows Kits\8.1\Lib\winv6.3\um\x86」を記入。
「INCLUDE」という変数には「C:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools\VC\Tools\MSVC\14.39.33519\include; C:\Program Files (x86)\Windows Kits\10\Include\10.0.22621.0\ucrt」
と入れておきます。
(時期や環境によっては、2022や14.39.33519の数値が違うことがあります。Program Filesの中を確認し、それぞれの環境に合わせたフォルダ名を記入してください)
これをやらないと、先の学習時にエラーが出ます。
あと、YOLOX-mainの中に「setup.py」があるんですが、これは実行しないでください。
何かと不具合が起きやすいので、これを利用しない方法で書きます。
今後のために、以下のファイルを「YOLOX-main」の直下にコピーしておきます。
tools\train.py
tools\demo.py
また、学習モデル「yolox_nano.pth」を以下からダウンロードし、YOLOX-mainの直下に入れておきます。
https://github.com/Megvii-BaseDetection/YOLOX/releases/download/0.1.1rc0/yolox_nano.pth
適当な動画ファイルをつかって、動作確認をします。
python demo.py webcam -n yolox-nano -c .\yolox_nano.pth
なお、この後必要となるので、このフォルダ内に「data」というフォルダを、「datasets」フォルダの下に「COCO」というフォルダを作っておきます。
ちなみに「data」フォルダには、学習させたい画像ファイルを入れておきます。
(1) VoTTで学習データ作成(アノテーション)
まずは、以下からVoTTを入手します。
Releases · microsoft/VoTT
「Assets」の下の「vott-2.2.0-win32.exe」をクリックすると、ダウンロードされます。
ダウンロードが終わったら、これをダブルクリックしてインストールします。
デスクトップにあるvottのアイコンをダブルクリックすると、以下のような画面が出てきます。
ここでは、新規プロジェクトをクリック。
すると、こんな感じの画面が出てくるはずです。
表示名は、適当でいいです(ここではtestとしました)。
その下のソース接続、ターゲット接続ですが、ここはそれぞれ先ほど作った「data」と「datasets-COCO」を選びます。
それぞれの接続の横にある「Add Connection」をクリックすると、上のような表示が出ます。
表示名は適当に入れて、プロバイダーは「ローカルファイルシステム」とすると、その下に「フォルダを選択」というのが出てくるので、フォルダを選択して「接続を保存」をクリックします。
あと、下にある「タブ」には、今回作りたいラベル名を入れておきます。
なお、今回は子供の運動会の画像から「人」と「帽子」を検出するものを作ることにしました。なので、ここは「human」「hat」と入れておきます。
そこまでできたら、プロジェクトを保存、とします。
すると、dataフォルダ内にある画像を読み込み、こんな感じの画面が出てきます。
ここで、アノテーションという作業を行います。
具体的には、検出したいものを選択し、ラベル付けするという作業です。これが結構大変。
まずは、人を囲みます。
囲んだ後に、右上の出てくるリストから「human」を選択すると、この枠にhumanというラベルが付けられます。
なおこの場合、1つ目が「human」、2つ目が「hat」となっているので、枠を選んだ後に数字の1キーを押すと「human」、2を押すと「hat」とラベル付けされます。
この数字キーでのラベル付けはすごく便利です。
そんな調子で、じゃんじゃんラベル付けをしていきます。
だいたい1枚の画像から20個程度の人、帽子のラベルを作成、これを25枚ほどやりました。
たった26枚でも、地獄の作業でした。
この作業を終えて保存する前に、画面左の真ん中編にある斜め上矢印のアイコン「エクスポート」をクリックします。
以下のような画像が出てくるので、プロバイダーを「Pascal VOC」、アセットの状態を「訪問済みアセットのみ」として「エクスポート設定を保存」をクリックします。
その後に、今度は画面上にある、斜め上矢印をクリックします。
すると、アノテーションデータが保存されたというメッセージが出てきます。
これで、学習データの作成は完了です。
※ VoTTは画像だけでなく、動画データからもアノテーションすることが可能です。
が、Windowsの場合は次の変換以降が上手くいかないので、必ず動画を複数枚の静止画にしてからアノテーションするようにしてください。
(2) Pascal VOC⇒COCOへの変換
YOLOXは学習モデルをCOCOの形式に変換してやる必要があります。
このため、Pascal VOC⇒COCOへ変換するコマンドを使います。
以下のサイトで、「<>Code」から「Download ZIP」を選択。
GitHub - tatsuya-fukuoka/convert_pascalvoc2coco: VOTTで出力したPascal VOC形式のXMLファイルをCOCO形式のJSONファイルへ変換するスクリプト
ダウンロードされたZIPファイルを解凍し、出てきた「convert_pascalvoc2coco-main」というフォルダを「YOLOX-main」の直下に入れます。
「datasets\COCO」の中にあるフォルダ(「test-PascalVOC-export」という名前)を「convert_pascalvoc2coco-main」の中に移動してやります。
そこで、Windows PowerShell上で上のフォルダに移動後、
python convert_vott_voc2coco.py test-PascalVOC-export
と実行。すると[YYYYMMDD_HHMMSS]_COCO_Formatという名前のフォルダができます。
その中にあるフォルダ、ファイル類をごっそり「datasets\COCO」の中に入れます。
(3) 学習実行
いよいよ、学習実行です。
が、ちょっと前準備が必要。
「exp\example\custom」というフォルダにある「nano.py」というファイルを開きます。
その中にある「self.data_dir = "datasets/coco128"」を「self.data_dir = "datasets/COCO"」に書き換えます。
また、self.var_annの下あたりに「self.max_epoch = 300」「self.num_classes = 2」
を追記しておきます。(num_classesは自身で作ったラベル数に変えてください)
self.data_dir = "datasets/COCO"
self.train_ann = "instances_train2017.json"
self.val_ann = "instances_val2017.json"
self.max_epoch = 300
self.num_classes = 2
こんな感じになっていればOK。
また、ラベル名については、「yolox\data\datasets」にある「coco_classes.py」の中の「COCO_CLASSES = (」以下を書き換えます。今回の場合は、下のようになります。
COCO_CLASSES = (
"human",
"hat",
)
ここは変えなくても動きますが、おかしなラベル名になるので変えておいた方が無難です。
ここでようやく、学習を実行します。
python train.py -f exps/example/custom/nano.py -d 1 -b 16 --fp16 -o --cache
すると、こんな画面が出てきます。
うちの環境(GTX1650Ti)だと、だいたい30分くらいで300エポックが実行されました。
終わると、「YOLOX_outputs\nano」に~.pthという学習モデルが大量に入っているはずなので、そのなかの「best_ckpt.pth」をYOLOX-mainの直下に移動しておきます。
そこで、適当な動画ファイル(ここでは0002.mp4)を使って推論してみます。
python demo.py video -f exps/example/custom/nano.py -c best_ckpt.pth --path 00002.mp4 --conf 0.3 --tsize 640 --save_result --device gpu
すると「YOLOX_outputs\nano\vis_res」の下にフォルダが作成されて、その中にアウトプットされた動画ファイルが入ってます。
こんな感じで、ちゃんと?推論されてました。
というか、ちょっとhumanが過検出されてる感はありますが。
(ついでに言うと、humanとhatのラベルがなぜか逆でしたが)
まあ、とりあえず動くことは動きました。
あとはたくさんアノテーションをしてやればよさそうです。
なお、tensorboardを使って学習の状況を確認できます。
tensorboard --logdir .\YOLOX_outputs\nano\tensorboard
とコマンド入力し、下に出てきた「http://localhost:6006」をCTRLキーを押しながらクリックすると、ブラウザが開いてグラフが表示されます。
これを見ると、100エポックくらいまでは全然学習されてなくて、300の手前で頭打ちになってます。
学習データのアノテーションが、いい加減 or 少なすぎたんですかね?
いずれにせよ、これで独自データによる学習ができました。
実用上はonnx形式に変換してやりたいところ。そうすれば、Raspberry Pi辺りで動かせるんですけどね。まだそちらは上手くいってません。
最近のコメント