はじめに
こんにちわ、swim-loverです。PythonとPytorchで物体検出を行っています。 Pythonを始めたばかりですが、「使いながら覚える」をコンセプトに勉強しています。今回は、実装サンプルの都合上、結果的にTensorflowに触れることになりました。
Part(1),Part(2)では、SSDを使った物体検出を行いました。今回は、SSDとは別のアルゴリズムであるYoLoを使って物体検出を行いたいと思います。
YoLo ざっくり理解
YoLoとは、You Only Look Onceの略した名称で、SSDと並び比較されることが多いようです。
YoLoは、SSDとならび、入力から結果出力までの全ステージでDeep Learningで処理する意味合いからEnd-to-Endの物体検出とのこと。
YoLoの論文からザックリ理解をしてみます。

Step1)入力画像を448 x 448の画像にリサイズする。
Step2)その画像に対して、Single Convolutional networkを行う。
Step3)Step2の結果について、Confidenceに基づいて、間引き処理を行う。
Step2)のSingle Convolutional networkでは、Multi Bounding Box(四角い枠)の処理と、物体のClass分類の処理を同時に行うようになっています。ちなみに、Multi Bounding Box(四角い枠)は何か物体がありそうな箇所を見つける処理と理解しています。
やはり、ポイントは、二つの処理を同時に行うことによって、とても速い速度で処理することができることでしょうか。これは期待できそうです。

Step1)入力画像をSxSのGrid(画像)に分割する。上の例では、S=7になります。
Step2)各Gridについて、B個のBoundingBox(四角の枠)とConfirence(コンフィデンス)Scoreを予測する。中央の上段の図には、黒い太枠が、2,3個見てています。
Step3)C個のClass Probalitity Map(クラス確率マップ)を作成する。(中央の下段の図)赤色のグリッドの箇所が車をマップ、黄色のグリッドの箇所が自転車のマップを、青色のグリッドの箇所が犬のマップを示しているものと思われます。
Step4)最後にSxSx(B*5+C)のテンソルを出力する。論文では、S=7,B=2,C=20(Class数)なので、7x7x30個のテンソル(出力データ)を得ます。
Yolo アーキテクチャ図

YoLoの論文のアーキテクチャ図になります。

SSDの論文からSSDとYoLoの比較の図になります。
これについては、また時間を作ってじっくり理解をしたいと思いますが、YoLoの方がシンプルな図になっているようです。
YoLo サンプル実装
前回まで同じく、Colab環境を使用します。
Google DriveのMy DriveをColab環境にマウントします。
from google.colab import drive drive.mount('/content/drive')
MyDrivreにディレクトリ’test_yolo_v3’を作成します。
mkdir test_yolo_v3
念の為、tensowflowの versionも確認しておきます。Cloab環境だと環境セットアップの手間が省けるのがメリットです。
import tensorflow as tf tf.__version__
2.8.0
Gitよりkeras版yolov3をダウンロードします。tensorflowのVersionが2.0以上なので、2.0以上に対応したyolov3を使用する必要があります。
!git clone https://github.com/zzh8829/yolov3-tf2
続いて、学習済みモデルをダウンロードします。
!wget https://pjreddie.com/media/files/yolov3.weights -o ./data/yolov3.weights
学習済みモデル(yolov3.weights)をkeras形式に変換します。
!python convert.py --weights ./data/yolov3.weights --output ./checkpoints/yolov3.tf
しかしながら、エラーが出てきました。reshape処理のところで不整合が生じています。
Traceback (most recent call last): File "convert.py", line 39, in <module> app.run(main) File "/usr/local/lib/python3.7/dist-packages/absl/app.py", line 312, in run _run_main(main, args) File "/usr/local/lib/python3.7/dist-packages/absl/app.py", line 258, in _run_main sys.exit(main(argv)) File "convert.py", line 26, in main load_darknet_weights(yolo, FLAGS.weights, FLAGS.tiny) File "/content/drive/MyDrive/test_yolo_v3/yolov3-tf2/yolov3_tf2/utils.py", line 66, in load_darknet_weights conv_shape).transpose([2, 3, 1, 0]) ValueError: cannot reshape array of size 51527 into shape (128,64,3,3)
いろいろ調べてみましたが、スクリプト修正に時間をかけたくなかったので、yolov3-tinyという別の学習済みファイルを試してみました。
!python convert.py --weights ./data/yolov3-tiny.weights --output ./checkpoints/yolov3-tiny.tf --tiny
今度はうまくいきました。これで前に進めます。
I0227 05:41:37.598141 140114706884480 convert.py:24] model created I0227 05:41:37.603230 140114706884480 utils.py:45] yolo_darknet/conv2d bn I0227 05:41:37.606598 140114706884480 utils.py:45] yolo_darknet/conv2d_1 bn I0227 05:41:37.609891 140114706884480 utils.py:45] yolo_darknet/conv2d_2 bn I0227 05:41:37.614180 140114706884480 utils.py:45] yolo_darknet/conv2d_3 bn I0227 05:41:37.620603 140114706884480 utils.py:45] yolo_darknet/conv2d_4 bn I0227 05:41:37.627354 140114706884480 utils.py:45] yolo_darknet/conv2d_5 bn I0227 05:41:37.642364 140114706884480 utils.py:45] yolo_darknet/conv2d_6 bn I0227 05:41:37.696121 140114706884480 utils.py:45] yolo_conv_0/conv2d_7 bn I0227 05:41:37.702009 140114706884480 utils.py:45] yolo_output_0/conv2d_8 bn I0227 05:41:37.715446 140114706884480 utils.py:45] yolo_output_0/conv2d_9 bias I0227 05:41:37.718433 140114706884480 utils.py:45] yolo_conv_1/conv2d_10 bn I0227 05:41:37.721494 140114706884480 utils.py:45] yolo_output_1/conv2d_11 bn I0227 05:41:37.731293 140114706884480 utils.py:45] yolo_output_1/conv2d_12 bias I0227 05:41:37.733283 140114706884480 convert.py:27] weights loaded I0227 05:41:39.185976 140114706884480 convert.py:31] sanity check passed I0227 05:41:39.391645 140114706884480 convert.py:34] weights saved
YoLov3 物体検出の実行
自前の画像ファイルを使って、物体検出を実行します。
!python3 detect.py --weights ./checkpoints/yolov3-tiny.tf --tiny --image ./data/sample.jpg
前輪と後輪が重なっている2台の自転車を検出できました。同じ画像をPart(2) SSDでも試しましたが、SSDの場合は、1台の自転車として認識されていました。

別の画像でも試してみます。4台の自転車が検出できています。

まとめ
今回、Tensorflowで物体検出(YoLo)の実装サンプルであるYoLov3-tinyを使って、物体認識を行ってみました。今回、keras形式へのデータ変換でエラーが発生し、更新に時間がかかりました。次回以降も物体認識をしてみたいと思います。

組み込み系ソフトエンジニアをしています。これまでフロントエンド技術は避けてきましたが、食わず嫌いをやめて、勉強を始めました。
趣味は、水泳、ロードバイク、ランニング、登山です。
組み込み系技術ネタ、勉強したフロントエンド技術、たまに趣味の運動について発信していきます。
どうぞよろしくお願いします。
コメント