Help us understand the problem. What is going on with this article?

YOLO V3に、VoTTでアノテーションを付けた独自のデータセットを学習させる

More than 1 year has passed since last update.

YOLO V3を試すだけであれば学習済みモデルを使えばよいのですが、「やっぱり独自の物体検出をやってみたい!」ということで、独自のデータセットを学習させてみました。その内容を紹介します。

今回はグーの手を検出するだけのモデルを作成することとし、自分のグーの手を撮影し、その動画にVoTTでアノテーションを付けて学習データにしました。
yologu1.jpg

私が実行した環境

  • Windows 10 Home
  • NVIDIA GTX1080Ti
  • CUDA 9.1.85.3
  • CuDNN 7.1.3
  • Python 3.6.5
  • Tensorflow-gpu 1.12.0
  • Keras 2.2.4
  • opencv-python 4.0.0.21
  • matplotlib 3.0.2
  • Pillow 5.4.1
  • VoTT 1.7.2

まずはYOLO V3を動かす

以下のPythonライブラリをインストール
tensorflow、keras、opencv-python、matplotlib、pillow

Yolo V3のソース一式をダウンロードし、任意のパスに配置
https://github.com/qqwweee/keras-yolo3

学習済みモデルをダウンロードし、"keras-yolo3"フォルダに配置
https://pjreddie.com/media/files/yolov3.weights

weightsをkeras用に変換
python convert.py yolov3.cfg yolov3.weights model_data/yolo.h5

YOLOの実行(静止画)

python yolo_video.py --image
"Input image filename:"と聞かれたらファイル名を入力します。

YOLOの実行(動画)

python yolo_video.py --input hoge.mp4

上記でYOLOが動くことを確認できたら、安心して独自データセットの収集に取り組みます。

データの収集

今回は自分のグーの手をあらゆる角度からただひたすら動画撮影します。
後で1秒毎にアノテーションを付けるので、500枚ほどの学習データを集める想定で10分ほどiPhoneの前でグーの手をグリグリ動かします。

データにアノテーションを付ける

十分な動画が撮れたらアノテーションを付けていきます。
マイクロソフトが公開しているVoTTというアノテーションツールだと、動画へのアノテーションが楽ちんです。

VoTTをダウンロードしてインストールします。
https://github.com/Microsoft/VoTT/releases

VoTTはmp4、oggの動画ファイルに対応しています。
今回はiPhoneで撮影した動画を使ったのでffmpegでmov形式からmp4形式に変換しました。
また、私の環境ではFullHDだと学習中にメモリ不足でエラーが発生したので解像度を下げました。
ffmpeg -i hoge.mov -s 416x234 hoge.mp4

あとはVoTTでこの動画ファイルを読み込んで黙々とアノテーションをつけていきます。
途中で「こんな同じ様な画像ばっかりで意味があるのか…」という考えがよぎりましたが、それほど大変でもないので最後までやりきりました。

一通りアノテーションを付け終えたらExport Tagsを選択し、"Tensorflow Pascal VOC"形式でExportします。
vott.jpg

アノテーションをYOLO V3形式にする

YOLO V3のソースに付属している"voc_annotation.py"を使い、VOC形式のアノテーションをYOLO V3で学習する形式に変換します。

voc_annotation.pyの処理に合わせたファイル構成にする

"keras-yolo3"フォルダに"VOCDevkit"というフォルダを作成します。
VoTTからExportした"hoge_output"フォルダの名称を"VOC2007"に変更し、先の"VOCDevkit"フォルダ内に移動します。

"keras-yolo3/VOCDevkit/VOC2007/ImageSets/Main"フォルダに"train.txt"を作成します。
テキストファイルには"keras-yolo3/VOCDevkit/VOC2007/JPEGImages"フォルダ内の全jpgファイルを拡張子なしで列挙します。

このような感じ
hoge_frame_1
hoge_frame_2
...

"train.txt"をコピーして"test.txt"、"val.txt"を作成します。
学習用と評価用などでデータを振り分ける場合は振り分けておいても構いません。

voc_annotation.pyの処理を修正する

VoTTで出力したファイルには、アノテーション位置がfloatで書かれています。そのままでは"voc_annotation.py"で読み込めないので、下記のようにfloatからintに変換するようにソースを修正します。

voc_annotation.py,21行目あたり
        b = (int(float(xmlbox.find('xmin').text)),
             int(float(xmlbox.find('ymin').text)),
             int(float(xmlbox.find('xmax').text)),
             int(float(xmlbox.find('ymax').text)))

また、6行目あたりのclassesのリストも自分で学習させる内容に合わせて修正します。今回は1クラスなのでclasses = ["gu"]としておきました。

voc_annotation.pyで変換する

あとは"voc_annotation.py"を実行して変換します。
python voc_annotation.py

出力された"2007_train.txt"がYOLO V3用のアノテーションの形式です。

このような形式
~\keras-yolo3/VOCdevkit/VOC2007/JPEGImages/hoge_frame_1.jpg 100,200,250,300,0
~\keras-yolo3/VOCdevkit/VOC2007/JPEGImages/hoge_frame_2.jpg 200,100,300,400,0
...

学習

独自のクラスの列挙

"keras-yolo3\model_data"フォルダに"my_classes.txt"を作成し、自分で学習させるクラスを列挙します。
今回はguとだけ記載しました。

train.pyの修正

"train.py"が"2007_train.txt"、"my_classes.txt"を読み込むように修正します。
17行目の"annotation_path"に"2007_train.txt"を指定します。
19行目の"classes_path"に"model_data/my_classes.txt"を指定します。

また、私の環境ではデフォルトのbatch_sizeだと学習中にメモリ不足でエラーが発生したので減らしました。
57行目と76行目の"batch_size"を32から8にしています。

学習用にweightsをコンバート

学習用にweightsをコンバートします。
python convert.py -w yolov3.cfg yolov3.weights model_data/yolo_weights.h5

学習の実行

python train.py

学習済みモデルは"\keras-yolo3\logs\000\trained_weights_final.h5"として生成されます。

学習済みモデルで物体検出

学習済みモデル、クラスを指定して起動します。

YOLOの実行(静止画)

python yolo_video.py --model logs/000/trained_weights_final.h5 --classes model_data/my_classes.txt --image

YOLOの実行(動画)

python yolo_video.py --model logs/000/trained_weights_final.h5 --classes model_data/my_classes.txt --input hoge.mp4

学習に用いたのは自分のグーだけでしたが、うちの子のグーも検出できました。
yologu2.jpg

顔でもグーと検出される時もありましたが…

moto2g
ガジェットマニア 兼 システムエンジニア。 プライベートでは気ままに面白いものを作るのが好き。
https://majipon.jp/blog/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away