Atom's tech blog

YOLO3の学習済みデータで物体検出してみた

概要

プログラミングせず物体検知のモデル(YOLO3)を使用してみることにする。 まずは備忘録も兼て少し説明から。

物体検出(Object Detection)とは 画像を読み込みし、画像の中に物体の位置とカテゴリ(クラス)を特定する方法です。画像の中の複数の物体を同時に検出することも可能です。参考までに代表的な物体検出ツールは以下になります。

物体検出ツール 概要
Single Shot Multibox Detector(SSD 入力画像を細分化して位置を少しずつスライドさせながら繰り返ししないで、1回で入力画像全域から複数の物体を検出する。精度はFaster R-CNNと同等だが、大幅な処理速度向上している。しかしYOLO2に比べ速度は若干劣る。
You Only Look Once(YOLO) SSDと同じく画像を一回のみ入力して物体の位置を算出する。YOLO3はSSDよりパフォーマンスはすごくいい (Qiita
Mask R-CNN ICCV 2017 Best Paper に選出された手法で、物体検出やセグメンテーションを実現(Qiita

セグメンテーション

このセグメンテーションもよく出る用語なので簡単に説明すると、基本的には物体検出と似ているが物体を矩型領域で認識するのではなく、画像のピクセル単位で推論するのがセグメンテーション。このセグメンテーションの難点は、重なった物体を区別できない。

さて.... 今回はYOLOを使ってみたいので、YOLOについて少しだけ理解したことの説明を入れてみた。

YOLOとは

「YOLO」とは、You Only Look Once(あなたは一度見るだけです) の頭文字を取ったものらしく、物体の位置検出とクラス分類を同時に行うことで、高速処理を可能にしたニューラルネットワークです。 例えばR-CNNやFast-CNNは入力画像を細分化して位置をずらして物体か判定して出力しますが、YOLOの場合は画像を一回のみ入力して物体の位置を算出します。

YOLOのバージョン

現在YOLOはバージョン2と3がありますが、その他に「Tiny YOLO」という小さいサイズののバージョンもあります。( YOLOサイト) YOLO3ではYOLO2に比べて速度は遅くなっているみたいですが、精度の方は向上してみたいです(ネット情報)。YOLO3は多オブジェクトも検出可能になっているみたいです。

物体検出を始める

それでは下記のツールバージョンで実施してみます。

  • MacOS Catalina
  • python3.5.6
  • Opencv3.4.2
  • xcode11.1
  • YOLOv3

YOLOのダウンロードとインストール

まずはダウンロード。 コマンドライン(git cloneコマンド)からも実施できるが、自分はGitHubのDarknetからダウンロード。念のために両方掲載しておきます。

パターン1:git cloneでダウンロードしインストールする場合

  • まずはダウンロードする場所に移動します
  • 「git clone ................... 」(下記参照)を入力しダウンロードします
  • 「cd darknet」を入力してdarknetフォルダに移動します
  • 「ls」を入力しビルドに必要なMakefileファイルがあることを確認します
  • 「make」を入力してビルドを実施しインストールします
$ git clone https://github.com/pjreddie/darknet.git
$ cd darknet
$ ls
LICENSE        LICENSE.mit    cfg       libdarknet.a    scripts
LICENSE.fuck   LICENSE.v1     darknet   libdarknet.so   src
LICENSE.gen Makefile       data    obj
LICENSE.gpl README.md     examples   python
LICENSE.meta   backup        include    results

$ make 

パターン2:ブラウザからダウンロードする場合

  • こちらから(Darknet)ダウンロードし、ダウンロードしたファイル一式(フォルダ毎)任意の場所に保存します。とこでも良い。
  • ダウンロードしたフォルダ名は「darknet-master」になっているので「darknet」に変更します。理由は特になし。そのままのフォルダ名でも問題ないだが、「git clone」と同じにしてみただけ。

f:id:iAtom:20201008150239j:plain

  • 「cd darknet」と入力してdarknetフォルダに移動します
  • 「ls」を入力しビルドに必要なMakefileファイルがあることを確認します
  • 「make」を入力してビルドを実施しインストールします
$ cd darknet/
$ ls
LICENSE        LICENSE.mit    cfg       libdarknet.a    scripts
LICENSE.fuck   LICENSE.v1     darknet   libdarknet.so   src
LICENSE.gen Makefile       data    obj
LICENSE.gpl README.md     examples   python
LICENSE.meta   backup        include    results

$ make 

YOLOのモデルデータをダウンロード

YOLOのインストールが完了したので使ってみましょう。 インストールしただけではまだ物体検知できないため、学習済みのモデル(.weights)ファイルをターミナルからダウンロードします。 自分は新しい「YOLO3」( yolov3.weights )を使ってみることにします。

$ curl https://pjreddie.com/media/files/yolov3.weights -O
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  236M  100  236M    0     0   127k      0  0:31:35  0:31:35 --:--:--  489k

256Mbyteもある。。。モデルファイルは結構大きいサイズ。 ファイル(yolov3.weights)があることを確認します。

$ ls
LICENSE     LICENSE.mit  cfg      libdarknet.a   results
LICENSE.fuck   LICENSE.v1   darknet  libdarknet.so  scripts
LICENSE.gen Makefile     data     obj            src
LICENSE.gpl README.md    examples pic          yolov3.weights
LICENSE.meta   backup       include  python

静止画像の物体検出

それでは...モデルファイルもダウンロードできたので、物体検出を実施してみます。 本当は動画で物体検出したいのですが、恐らくGPUマシンではないと結果を確認に時間がかかることと、ディープラーニング初心者でもあるので、まずは静止画像で物体検出から。

コマンドは以下で実施できるようです。 まず「pic」フォルダに推論をかけたい画像を保存しておきましょ。

$ cd pic
$ ls
bussiness.jpeg
$ cd ..

それでは実行します。

./darknet detect cfg/yolov3.cfg yolov3.weights pic/bussiness.jpeg

すると.... 以下が「ダーっと」突然表示します。 見てみると 左端のlayerを見ると「106」層になっていることがわかります。 あと最後の方に画像内の物体検出した名前と推論率を表示しています。 同じ物体がある場合は、どれの推論率かわからないが......。

layer     filters    size              input                output
    0 conv     32  3 x 3 / 1   608 x 608 x   3   ->   608 x 608 x  32  0.639 BFLOPs
    1 conv     64  3 x 3 / 2   608 x 608 x  32   ->   304 x 304 x  64  3.407 BFLOPs
    2 conv     32  1 x 1 / 1   304 x 304 x  64   ->   304 x 304 x  32  0.379 BFLOPs
    3 conv     64  3 x 3 / 1   304 x 304 x  32   ->   304 x 304 x  64  3.407 BFLOPs
    4 res    1                 304 x 304 x  64   ->   304 x 304 x  64
    5 conv    128  3 x 3 / 2   304 x 304 x  64   ->   152 x 152 x 128  3.407 BFLOPs
    6 conv     64  1 x 1 / 1   152 x 152 x 128   ->   152 x 152 x  64  0.379 BFLOPs
    7 conv    128  3 x 3 / 1   152 x 152 x  64   ->   152 x 152 x 128  3.407 BFLOPs
    8 res    5                 152 x 152 x 128   ->   152 x 152 x 128
    9 conv     64  1 x 1 / 1   152 x 152 x 128   ->   152 x 152 x  64  0.379 BFLOPs
   10 conv    128  3 x 3 / 1   152 x 152 x  64   ->   152 x 152 x 128  3.407 BFLOPs
   11 res    8                 152 x 152 x 128   ->   152 x 152 x 128
   12 conv    256  3 x 3 / 2   152 x 152 x 128   ->    76 x  76 x 256  3.407 BFLOPs
   13 conv    128  1 x 1 / 1    76 x  76 x 256   ->    76 x  76 x 128  0.379 BFLOPs
   14 conv    256  3 x 3 / 1    76 x  76 x 128   ->    76 x  76 x 256  3.407 BFLOPs
   15 res   12                  76 x  76 x 256   ->    76 x  76 x 256
   16 conv    128  1 x 1 / 1    76 x  76 x 256   ->    76 x  76 x 128  0.379 BFLOPs
   17 conv    256  3 x 3 / 1    76 x  76 x 128   ->    76 x  76 x 256  3.407 BFLOPs
   18 res   15                  76 x  76 x 256   ->    76 x  76 x 256
   19 conv    128  1 x 1 / 1    76 x  76 x 256   ->    76 x  76 x 128  0.379 BFLOPs
   20 conv    256  3 x 3 / 1    76 x  76 x 128   ->    76 x  76 x 256  3.407 BFLOPs
   21 res   18                  76 x  76 x 256   ->    76 x  76 x 256
   22 conv    128  1 x 1 / 1    76 x  76 x 256   ->    76 x  76 x 128  0.379 BFLOPs
   23 conv    256  3 x 3 / 1    76 x  76 x 128   ->    76 x  76 x 256  3.407 BFLOPs
   24 res   21                  76 x  76 x 256   ->    76 x  76 x 256
   25 conv    128  1 x 1 / 1    76 x  76 x 256   ->    76 x  76 x 128  0.379 BFLOPs
   26 conv    256  3 x 3 / 1    76 x  76 x 128   ->    76 x  76 x 256  3.407 BFLOPs
   27 res   24                  76 x  76 x 256   ->    76 x  76 x 256
   28 conv    128  1 x 1 / 1    76 x  76 x 256   ->    76 x  76 x 128  0.379 BFLOPs
   29 conv    256  3 x 3 / 1    76 x  76 x 128   ->    76 x  76 x 256  3.407 BFLOPs
   30 res   27                  76 x  76 x 256   ->    76 x  76 x 256
   31 conv    128  1 x 1 / 1    76 x  76 x 256   ->    76 x  76 x 128  0.379 BFLOPs
   32 conv    256  3 x 3 / 1    76 x  76 x 128   ->    76 x  76 x 256  3.407 BFLOPs
   33 res   30                  76 x  76 x 256   ->    76 x  76 x 256
   34 conv    128  1 x 1 / 1    76 x  76 x 256   ->    76 x  76 x 128  0.379 BFLOPs
   35 conv    256  3 x 3 / 1    76 x  76 x 128   ->    76 x  76 x 256  3.407 BFLOPs
   36 res   33                  76 x  76 x 256   ->    76 x  76 x 256
   37 conv    512  3 x 3 / 2    76 x  76 x 256   ->    38 x  38 x 512  3.407 BFLOPs
   38 conv    256  1 x 1 / 1    38 x  38 x 512   ->    38 x  38 x 256  0.379 BFLOPs
   39 conv    512  3 x 3 / 1    38 x  38 x 256   ->    38 x  38 x 512  3.407 BFLOPs
   40 res   37                  38 x  38 x 512   ->    38 x  38 x 512
   41 conv    256  1 x 1 / 1    38 x  38 x 512   ->    38 x  38 x 256  0.379 BFLOPs
   42 conv    512  3 x 3 / 1    38 x  38 x 256   ->    38 x  38 x 512  3.407 BFLOPs
   43 res   40                  38 x  38 x 512   ->    38 x  38 x 512
   44 conv    256  1 x 1 / 1    38 x  38 x 512   ->    38 x  38 x 256  0.379 BFLOPs
   45 conv    512  3 x 3 / 1    38 x  38 x 256   ->    38 x  38 x 512  3.407 BFLOPs
   46 res   43                  38 x  38 x 512   ->    38 x  38 x 512
   47 conv    256  1 x 1 / 1    38 x  38 x 512   ->    38 x  38 x 256  0.379 BFLOPs
   48 conv    512  3 x 3 / 1    38 x  38 x 256   ->    38 x  38 x 512  3.407 BFLOPs
   49 res   46                  38 x  38 x 512   ->    38 x  38 x 512
   50 conv    256  1 x 1 / 1    38 x  38 x 512   ->    38 x  38 x 256  0.379 BFLOPs
   51 conv    512  3 x 3 / 1    38 x  38 x 256   ->    38 x  38 x 512  3.407 BFLOPs
   52 res   49                  38 x  38 x 512   ->    38 x  38 x 512
   53 conv    256  1 x 1 / 1    38 x  38 x 512   ->    38 x  38 x 256  0.379 BFLOPs
   54 conv    512  3 x 3 / 1    38 x  38 x 256   ->    38 x  38 x 512  3.407 BFLOPs
   55 res   52                  38 x  38 x 512   ->    38 x  38 x 512
   56 conv    256  1 x 1 / 1    38 x  38 x 512   ->    38 x  38 x 256  0.379 BFLOPs
   57 conv    512  3 x 3 / 1    38 x  38 x 256   ->    38 x  38 x 512  3.407 BFLOPs
   58 res   55                  38 x  38 x 512   ->    38 x  38 x 512
   59 conv    256  1 x 1 / 1    38 x  38 x 512   ->    38 x  38 x 256  0.379 BFLOPs
   60 conv    512  3 x 3 / 1    38 x  38 x 256   ->    38 x  38 x 512  3.407 BFLOPs
   61 res   58                  38 x  38 x 512   ->    38 x  38 x 512
   62 conv   1024  3 x 3 / 2    38 x  38 x 512   ->    19 x  19 x1024  3.407 BFLOPs
   63 conv    512  1 x 1 / 1    19 x  19 x1024   ->    19 x  19 x 512  0.379 BFLOPs
   64 conv   1024  3 x 3 / 1    19 x  19 x 512   ->    19 x  19 x1024  3.407 BFLOPs
   65 res   62                  19 x  19 x1024   ->    19 x  19 x1024
   66 conv    512  1 x 1 / 1    19 x  19 x1024   ->    19 x  19 x 512  0.379 BFLOPs
   67 conv   1024  3 x 3 / 1    19 x  19 x 512   ->    19 x  19 x1024  3.407 BFLOPs
   68 res   65                  19 x  19 x1024   ->    19 x  19 x1024
   69 conv    512  1 x 1 / 1    19 x  19 x1024   ->    19 x  19 x 512  0.379 BFLOPs
   70 conv   1024  3 x 3 / 1    19 x  19 x 512   ->    19 x  19 x1024  3.407 BFLOPs
   71 res   68                  19 x  19 x1024   ->    19 x  19 x1024
   72 conv    512  1 x 1 / 1    19 x  19 x1024   ->    19 x  19 x 512  0.379 BFLOPs
   73 conv   1024  3 x 3 / 1    19 x  19 x 512   ->    19 x  19 x1024  3.407 BFLOPs
   74 res   71                  19 x  19 x1024   ->    19 x  19 x1024
   75 conv    512  1 x 1 / 1    19 x  19 x1024   ->    19 x  19 x 512  0.379 BFLOPs
   76 conv   1024  3 x 3 / 1    19 x  19 x 512   ->    19 x  19 x1024  3.407 BFLOPs
   77 conv    512  1 x 1 / 1    19 x  19 x1024   ->    19 x  19 x 512  0.379 BFLOPs
   78 conv   1024  3 x 3 / 1    19 x  19 x 512   ->    19 x  19 x1024  3.407 BFLOPs
   79 conv    512  1 x 1 / 1    19 x  19 x1024   ->    19 x  19 x 512  0.379 BFLOPs
   80 conv   1024  3 x 3 / 1    19 x  19 x 512   ->    19 x  19 x1024  3.407 BFLOPs
   81 conv    255  1 x 1 / 1    19 x  19 x1024   ->    19 x  19 x 255  0.189 BFLOPs
   82 yolo
   83 route  79
   84 conv    256  1 x 1 / 1    19 x  19 x 512   ->    19 x  19 x 256  0.095 BFLOPs
   85 upsample            2x    19 x  19 x 256   ->    38 x  38 x 256
   86 route  85 61
   87 conv    256  1 x 1 / 1    38 x  38 x 768   ->    38 x  38 x 256  0.568 BFLOPs
   88 conv    512  3 x 3 / 1    38 x  38 x 256   ->    38 x  38 x 512  3.407 BFLOPs
   89 conv    256  1 x 1 / 1    38 x  38 x 512   ->    38 x  38 x 256  0.379 BFLOPs
   90 conv    512  3 x 3 / 1    38 x  38 x 256   ->    38 x  38 x 512  3.407 BFLOPs
   91 conv    256  1 x 1 / 1    38 x  38 x 512   ->    38 x  38 x 256  0.379 BFLOPs
   92 conv    512  3 x 3 / 1    38 x  38 x 256   ->    38 x  38 x 512  3.407 BFLOPs
   93 conv    255  1 x 1 / 1    38 x  38 x 512   ->    38 x  38 x 255  0.377 BFLOPs
   94 yolo
   95 route  91
   96 conv    128  1 x 1 / 1    38 x  38 x 256   ->    38 x  38 x 128  0.095 BFLOPs
   97 upsample            2x    38 x  38 x 128   ->    76 x  76 x 128
   98 route  97 36
   99 conv    128  1 x 1 / 1    76 x  76 x 384   ->    76 x  76 x 128  0.568 BFLOPs
  100 conv    256  3 x 3 / 1    76 x  76 x 128   ->    76 x  76 x 256  3.407 BFLOPs
  101 conv    128  1 x 1 / 1    76 x  76 x 256   ->    76 x  76 x 128  0.379 BFLOPs
  102 conv    256  3 x 3 / 1    76 x  76 x 128   ->    76 x  76 x 256  3.407 BFLOPs
  103 conv    128  1 x 1 / 1    76 x  76 x 256   ->    76 x  76 x 128  0.379 BFLOPs
  104 conv    256  3 x 3 / 1    76 x  76 x 128   ->    76 x  76 x 256  3.407 BFLOPs
  105 conv    255  1 x 1 / 1    76 x  76 x 256   ->    76 x  76 x 255  0.754 BFLOPs
  106 yolo
Loading weights from yolov3.weights...Done!
pic/bussiness.jpeg: Predicted in 17.319105 seconds.
cell phone: 100%
cell phone: 97%
person: 65%
person: 100%
person: 100%
wine glass: 91%
cup: 100%
diningtable: 73%
cup: 59%

この推論した結果の画像は、コマンド実行したフォルダに「predictions.jpg 」で出力されています。 画像を見たいので以下のコマンドで表示します。

$ open predictions.jpg 

簡単に物体検出できてしまうのに驚いてしまいます。 f:id:iAtom:20201008150336j:plain

他の画像もトライ。 「pic」フォルダに推論をかけたい動物画像を保存し、ファイルがあることを確認します。

$ cd pic
$ ls
bussiness.jpeg  animal.jpeg
$ cd ..
$ ./darknet detect cfg/yolov3.cfg yolov3.weights pic/animal.jpeg
$ open predictions.jpg 

物体検出できてるー。

f:id:iAtom:20201008150416j:plain

もう一つ。車でもやってみよう。コマンドはイメージは省略します。m( )m 推論率は以下だった。

traffic light: 97%
traffic light: 68%
traffic light: 53%
traffic light: 52%
car: 95%
car: 89%
car: 86%
car: 77%
car: 77%
car: 71%
car: 68%
car: 54%
car: 53%
car: 53%
car: 52%
person: 52%
person: 54%
person: 54%
car: 100%
car: 99%
motorbike: 74%
bus: 70%
bus: 68%
car: 98%
car: 98%
car: 97%

f:id:iAtom:20201008150357j:plain

感想

今までプログラミングして何か新たな結果を出すことをしていたが、ディープラーニングのモデルファイルがあればプログラミングは不要なんだなーーと、熟感じる。 モデルファイルも新たな学習画像(クラス追加)を加えることで物体検知できるし。 ただ独自の物体を検出するには、それなりの画像収集する量も必要となる。 開発費には画像データ撮影や収集の工数など多くなるだろう。 その見積もりが難しい気がする。撮影するなら環境整備も必要になるし....。

会社で開発メンバーが色々画像を撮影しているのを見ているが、 非常に大変そうで、これがエンジニアのする仕事なのか?と... 疑問に思うこのごろです。

次は動画で物体検出ができるかやってみようかと....