10
3

More than 3 years have passed since last update.

IceVisionによるObjectDetection

Last updated at Posted at 2021-07-15

これは何

2021年で最もイケている物体検出フレームワークと言っても過言ではないIceVisionを使って標準データセットのペットデータセットを使ったObject Detectionを簡単に行うためのhands-on

IceVisionとは

過去記事参照

環境

Jupyterは結局オンプレのUbuntuで動かしています。
一応google colabでの動作確認も行いました。

手順

基本的には公式のチュートリアル「How to train the Fridge Objects Dataset」を踏襲します。
ただ、アップデートにdocument/exampleの更新が追い付いていないようなので、適宜icedataのリポジトリも参照しながら書き換えていきます。

まず、使うライブラリをimportします。

from icevision.all import *
import icedata

モデル作成

次に、使いたいmodelを定義します。とりあえず動かすだけなのでMMDetectionのRetinanetにしておきます。
MMDetectionTorchvisionEfficientDet、Yolov5をサポートしておりmodel.(library).(model_name)のように指定することでモデル構造を定義できます。

model_type = models.mmdet.retinanet

続けてbackboneを定義します。
これもかなりサポートされており、MMDetectionに関しては対応するモデルのbackboneフォルダに使えるbackboneが一覧で記載されています。(YoLoもディレクトリ内backbone.pyにあります。)
TorchvisionとEfficientDetに関してはちょっと違うところに説明が置いてあります。開発途中だからなのかな。。。
今回はとりあえずresnet50_fpn_1xを使います。

backbone = model_type.backbones.resnet50_fpn_1x

データセット作成

続けて、datasetを読み込みます。
今回はicevisionにインストールされているThe Oxford-IIIT Pet Dataset (CVPR 2012)を使います。Fine-Grained Object Detectionとでも言うタスクになるんでしょうか。
ちなみに、執筆時点ではreadme.mdに記載されているfridgeデータセットは使えません。
使えるデータセットはicedataのdocumentに記載があり、
Birds (Caltech-UCSD Birds 200 Dataset)
Biwi (BIWI Sample Keypoints (center of face))
Coco (COCO Dataset)
Fridge (Fridge Objects Dataset)
Ochuman (OCHuman Dataset)
Pennfudan (Penn-Fudan Database for Pedestrian Detection and Segmentation)
Voc(PASCAL VOC 2012 Dataset)
があるようです。
ここでdatasetとclass_mapを入れておきます。

data_dir = icedata.pets.load_data()
class_map = icedata.pets.class_map()

データセットに付属のperserが icedata.(dataset).parser に標準装備されており、簡単にパーサーを設定することができます。

parser = icedata.pets.parser(data_dir = data_dir, mask=False)

このパーサーはparser.parse()を用いて分割することができますが、これにはdata_splitterのオプションがあります。

data_splitter = RandomSplitter([0.9, 0.1])
train_records, valid_records = parser.parse(data_splitter)

データセットの可視化も show_recordsを用いることで簡単にできます。

show_records(train_records[:6], ncols=3, class_map=class_map)

image.png

petsデータセットは犬派(犬:猫 = 2:1)なんですよね。

次に、データセットの形を整形します。と言ってもかなり簡単です。
このライブラリの目的は、できるだけ少ない労力でモデルを変えつつ実験を行うことなので、sizeはEfficientDetに合わせて384にしておきます。
また、augumentationはtfms.A.aug_tfmsで指定できます。(ほかのaugumentationも使えます。)
できたものをDataset()でPyTorchのDatasetクラスに変換します。

presize = 512
size = 384
train_tfms = tfms.A.Adapter([*tfms.A.aug_tfms(size=size, presize=presize), tfms.A.Normalize()])
valid_tfms = tfms.A.Adapter([*tfms.A.resize_and_pad(size), tfms.A.Normalize()])
train_ds = Dataset(train_records, train_tfms)
valid_ds = Dataset(valid_records, valid_tfms)

次にデータローダーを準備します。

train_dl = model_type.train_dl(train_ds, batch_size=16, num_workers=4, shuffle=True)
valid_dl = model_type.valid_dl(valid_ds, batch_size=16, num_workers=4, shuffle=False)

学習

続けてモデルおよびmetricsを定義してしまいます。Retinanetの場合は以下のようになります。

model = model_type.model(backbone = backbone(pretrained = True), num_classes=len(parser.class_map))
metrics = [COCOMetric(metric_type=COCOMetricType.bbox)]

ここから先は通常のfastai (or PyTorch-Lighting)と同じ使い方になります。

learn = model_type.fastai.learner(dls=[train_dl, valid_dl], model=model, metrics=metrics)
learn.lr_find()

image.png

learn.fine_tune(20, 1e-3)

Nvidia RTX A6000で20epoch 30分程度でした。
これだけでpetの画像が学習できてしまいました。

推論

推論も1行でできます。

model_type.show_results(model, valid_ds, detection_threshold=.5)

image.png

さすがRetinanet、そんなに長いこと計算を回してないのに、かなりいい感じに推論できています。

自前データセットでの学習だったり、指標の計算に続く...かもしれません

10
3
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
3