こんにちは、技術部でバックエンドエンジニアをしている金子です。
最近は流行りに乗じて、サウナに激ハマりしていて週3でサウナに入り浸っています。
さて、今回のテーマですが、簡単な物体検出のハンズオンをやってみたいと思います。 業務にて機械学習、特に物体検出について触っていて、業務で使うとなると色々な条件があり確かに難しいのです。 ただ、物体検出を行うだけであればツールも充実しており割と簡単に行うことが出来ます。
ハンズオン内容
今回は、ハンズオンということで「犬の顔の物体認識」をやってみることにします。 実際のタスクとしては、犬種の識別や様々な犬種で物体認識がしたくなりますが、今回は簡単のために特定の犬種での物体検出で行います。
用意するものは以下の3点です。
- Googleアカウント
Google Colaboratoryを使わせてもらうため、必要です。
有料版にしない限り、制限がかかることはありますが、無料で使うことができます。
- 犬の画像
画像はこちらからダウンロードさせていただきました。
今回は、Basenji
を選択しました。
- アノテーションツール
labelImgを使わせていただきました。
手順としては
- labelImgを使って、アノテーションデータを作成し、トレーニング用のデータを作成する
- Google Colaboratoryを使って、上記のデータを用い、yoloにて学習を行う
- 犬の顔の物体検出を行う
となります。
ハンズオン
1. labelImgを使って、アノテーションデータを作成する
以下のコマンドで、インストールと起動ができます。
$ pip3 install labelImg $ labelImg or $ labelImg [IMAGE_PATH] [PRE-DEFINED CLASS FILE]
以下の画像のように立ち上がるはずです。
次に各種設定をしていきます。項目は以下です。
- 画像にあるように
Auto Save mode
をON - 画面右側の
Use default label
にチェックを付け、今回の検出対象のdog
を入力
こうすることで、アノテーションするときに毎度、ラベルを選択する必要がなくります。
- アノテーションのファイル形式を
yolo
に設定
pascalVOCになっているところをクリックすると切り替わります。
- 左側の
Open Dir
から犬の画像が保存されているディレクトリを選択 - 適当なところにアノテーションファイルを保存するディレクトリを作成し、
Change Save Dir
からそのディレクトリを選択
ここまでで、準備が整ったのでアノテーションをしていきます。 以下のショートカットが便利です。
ショートカット | 操作 |
---|---|
w | RectBoxの作成 |
d | 次の写真へ移動 |
a | 前の写真へ移動 |
RectBox作成し、以下のように犬の顔部分を囲うように長方形をセットします。 これを繰り返し、全写真分のアノテーションを作成します。
作成が完了したら、以下のようなディレクトリ構成で保存しておきます。
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)
上記の画像のように、犬の顔の物体認識が出来ました。
まとめ
簡単と言っておきながら手順として書き出すと結構なボリュームになってしまいましたが、物体検出までの流れは掴んでいただけたかと思います。
実際の業務では、物体認識だけでなく、ユーザーの行動データからの予測など機械学習を使ってやってみたいことが多くあります。 現在、機械学習を機能に組み込めるかの検証中ですが、次回は何か実例を出せたらと思っております!