ロコガイド テックブログ

「地域のくらしを、かしこく、たのしく」する、株式会社ロコガイドの社員がいろいろな記事を書いています。

「地域のくらしを、かしこく、たのしく」する、株式会社ロコガイドの社員がいろいろな記事を書いています。

物体検出ハンズオン

f:id:shuhei_kaneko:20211223173546p:plain

こんにちは、技術部でバックエンドエンジニアをしている金子です。
最近は流行りに乗じて、サウナに激ハマりしていて週3でサウナに入り浸っています。

さて、今回のテーマですが、簡単な物体検出のハンズオンをやってみたいと思います。 業務にて機械学習、特に物体検出について触っていて、業務で使うとなると色々な条件があり確かに難しいのです。 ただ、物体検出を行うだけであればツールも充実しており割と簡単に行うことが出来ます。

ハンズオン内容

今回は、ハンズオンということで「犬の顔の物体認識」をやってみることにします。 実際のタスクとしては、犬種の識別や様々な犬種で物体認識がしたくなりますが、今回は簡単のために特定の犬種での物体検出で行います。

用意するものは以下の3点です。

  • Googleアカウント

Google Colaboratoryを使わせてもらうため、必要です。
有料版にしない限り、制限がかかることはありますが、無料で使うことができます。

  • 犬の画像

画像はこちらからダウンロードさせていただきました。 今回は、Basenji を選択しました。

  • アノテーションツール

labelImgを使わせていただきました。

手順としては

  1. labelImgを使って、アノテーションデータを作成し、トレーニング用のデータを作成する
  2. Google Colaboratoryを使って、上記のデータを用い、yoloにて学習を行う
  3. 犬の顔の物体検出を行う

となります。

ハンズオン

1. labelImgを使って、アノテーションデータを作成する

以下のコマンドで、インストールと起動ができます。

$ pip3 install labelImg
$ labelImg
or
$ labelImg [IMAGE_PATH] [PRE-DEFINED CLASS FILE]

以下の画像のように立ち上がるはずです。

f:id:shuhei_kaneko:20211223171655p:plain
labelImg画面

次に各種設定をしていきます。項目は以下です。

  • 画像にあるようにAuto Save modeをON
  • 画面右側のUse default labelにチェックを付け、今回の検出対象のdogを入力

こうすることで、アノテーションするときに毎度、ラベルを選択する必要がなくります。

  • アノテーションのファイル形式をyoloに設定

pascalVOCになっているところをクリックすると切り替わります。

  • 左側のOpen Dirから犬の画像が保存されているディレクトリを選択
  • 適当なところにアノテーションファイルを保存するディレクトリを作成し、Change Save Dirからそのディレクトリを選択

ここまでで、準備が整ったのでアノテーションをしていきます。 以下のショートカットが便利です。

ショートカット 操作
w RectBoxの作成
d 次の写真へ移動
a 前の写真へ移動

RectBox作成し、以下のように犬の顔部分を囲うように長方形をセットします。 これを繰り返し、全写真分のアノテーションを作成します。

f:id:shuhei_kaneko:20211223172028p:plain
アノテーションの作成

作成が完了したら、以下のようなディレクトリ構成で保存しておきます。

training
 ├── dataset.yaml
 ├── images
 │   ├── train
 │   │   ├── n02110806_1013.jpg
 │   │   ├── n02110806_1019.jpg
 │   │   ...
 │   └── valid
 │       ├── n02110806_2497.jpg
 │       ├── n02110806_2551.jpg
 │       ...
 └── labels
     ├── train
     │   ├── n02110806_1013.txt
     │   ├── n02110806_1019.txt
     │   ...
     └── valid
         ├── n02110806_2497.txt
         ├── n02110806_2551.txt
         ...

画像をtraining/images配下に、先程作成したアノテーションファイルをtraining/labels配下に配置します。
画像やアノテーションファイルの80%ぐらいを訓練用データとして train に、残りをテスト用データとして valid に保存しておきます。
また、dataset.yamlについては以下のように書いて保存しておきます。
dataset.yamlは学習のための画像データの所在と、分類したいラベルの種類とその名前を設定します。
今回は犬だけなので、dogのみです。

# train and val datasets (image directory or *.txt file with image paths)
train: training/images/train/
val: training/images/valid/

# number of classes
nc: 1

# class names
names: ['dog']

2. Google Colaboratoryを使って、上記のデータを用い、yoloにて学習を行う

ご自身のGoogle Driveの新規から、Google Colaboratoryを選択すると新しいノートブックを作成できます。 ※ Google Colaboratoryは、Colab ノートブックにコードを書き込み、ブラウザ上で実行できる環境です。

ノートブックが立ち上がったら、タブ中のランタイム -> ランタイムのタイプを変更を選択し、GPU を選択してください。

まず、自身のドライブをノートブックにマウントします。

from google.colab import drive
drive.mount('/content/drive')

次に作業用ディレクトリを作成し、yoloをクローンします。

mkdir ml_work_tmp
cd ml_work_tmp
!git clone https://github.com/ultralytics/yolov5

クローンしたyolov5ディレクトリに移動し、必要なライブラリのセットアップを行います。

cd yolov5
!pip install -qr requirements.txt
import torch
from IPython.display import Image, clear_output

GPUが使われているかのチェックを行います。

print('Setup complete. Using torch %s %s' % (torch.__version__, torch.cuda.get_device_properties(0) if torch.cuda.is_available() else 'CPU'))

以下のように出力されていれば、問題ありません。

Setup complete. Using torch 1.9.0+cu102 _CudaDeviceProperties(name='Tesla T4', major=7, minor=5, total_memory=15109MB, multi_processor_count=40)

もし、CPUが使われていた場合は以下のようにCPUと表示されますので、ランタイムの変更をしてください。

Setup complete. Using torch 1.10.0+cu111 CPU

ついに学習です。①で作成したtrainingディレクトリを、現在いるGoogle Drive上のyolov5ディレクトリにアップロードし 以下のコマンドを実行すると学習が始まります。 ※ 3時間ほどで完了しますが、ブラウザを閉じてしまうと処理が止まってしまうのでバックグラウンド等で開いておいてください。

また、オプションのepochsは訓練データを何回繰り返して学習させるかを表し、batchは何個ずつのデータが学習に使われるかを表します。

!python train.py --batch 32 --epochs 700 --data training/dataset.yaml --cfg training/yolov5s.yaml --weights ''

runs/train/exp/weights/best.pt にptファイルが出来ていることが確認出来れば学習が完了しています。

3. 犬の物体検出を行う

最後に、学習に使った画像ではない犬の画像を用意して物体検出してみます。 以下のコードで検出することができます。

!python detect.py --weights runs/train/exp/weights/best.pt --source <テスト用の画像パス> --save-txt

結果は/runs/detect配下に保存されていますので、以下のコマンドで確認することが出来ます。

Image(filename='runs/detect/exp/<テスト画像のファイル名>', width=640)

f:id:shuhei_kaneko:20211223172752j:plain
テスト画像の物体検出

上記の画像のように、犬の顔の物体認識が出来ました。

まとめ

簡単と言っておきながら手順として書き出すと結構なボリュームになってしまいましたが、物体検出までの流れは掴んでいただけたかと思います。

実際の業務では、物体認識だけでなく、ユーザーの行動データからの予測など機械学習を使ってやってみたいことが多くあります。 現在、機械学習を機能に組み込めるかの検証中ですが、次回は何か実例を出せたらと思っております!