[OneFormer] AIで物体検出する [Segmentation]

2022年12月29日木曜日

Artificial Intelligence

本記事では、OneFormerと呼ばれる機械学習手法を用いて、一つのモデルでpanoptic/instance/semantic segmentationを行う方法をご紹介します。

アイキャッチ

OneFormer

概要

従来のセグメンテーション技術は、panoptic/instance/semantic segmentationのそれぞれのタスクで最高のパフォーマンスを実現するため、それぞれのモデルを個別にトレーニングする必要がありました。

OneFormerでは、この3つのセグメンテーションタスクを、1つのアーキテクチャと1回のトレーニングで実現するユニバーサルイメージセグメンテーションフレームワークです。

比較
出典: OneFormer: One Transformer to Rule Universal Image Segmentation

なお、それぞれのセグメンテーションタスクの違いについては以下の記事をご参照下さい。

トランスフォーマーベースのOneFormerでは、panopticアノテーションから全てのラベルを導出しマルチタスクをトレーニングすることによりsemanticなどのグラウンドトゥルースドメインを均一にサンプリングしています。

この構成により、COCOなどいくつかのデータセットでSOTAを達成しています。

Architecture
出典: OneFormer: One Transformer to Rule Universal Image Segmentation

詳細はこちらの論文をご参照ください。

本記事では上記手法を用いて、任意の画像のpanoptic/instance/semantic segmentationを行います。

デモ(Colaboratory)

それでは、実際に動かしながらセグメンテーションタスクを実行します。
ソースコードは本記事にも記載していますが、下記のGitHubでも取得可能です。
GitHub - Colaboratory demo

また、下記から直接Google Colaboratoryで開くこともできます。
Open In Colab

なお、このデモはPythonで実装しています。
Pythonの実装に不安がある方、Pythonを使った機械学習について詳しく勉強したい方は、以下の書籍やオンライン講座などがおすすめです。

環境セットアップ

それではセットアップしていきます。 Colaboratoryを開いたら下記を設定しCPUを使用するようにしてください。

「ランタイムのタイプを変更」→「ハードウェアアクセラレータ」をCPUに変更

初めにGithubからソースコードを取得します。

%cd /content

!git clone https://github.com/SHI-Labs/OneFormer-Colab.git

# using Commits on Nov 18, 2022
%cd /content/OneFormer-Colab
!git checkout 08ae914313bd1ff4688eb5e58f7845760fd60643

%cd /content
!mv OneFormer-Colab OneFormer

次にライブラリをインストールします。

%cd /content/OneFormer

# install pytorch
!pip install torch==1.9.0 torchvision==0.10.0 --quiet
# install opencv
!pip install -U opencv-python --quiet
# install detectron2
!python -m pip install detectron2 -f https://dl.fbaipublicfiles.com/detectron2/wheels/cu102/torch1.9/index.html --quiet
!pip3 install natten==0.14.2 -f https://shi-labs.com/natten/wheels/cu102/torch1.9/index.html --quiet

# install other
!pip install git+https://github.com/cocodataset/panopticapi.git --quiet
!pip install git+https://github.com/mcordts/cityscapesScripts.git --quiet
!pip install -r requirements.txt --quiet
!pip install ipython-autotime
!pip install imutils

最後にライブラリをインポートします。

%cd /content/OneFormer

# Setup detectron2 logger
import detectron2
from detectron2.utils.logger import setup_logger
setup_logger()
setup_logger(name="oneformer")

# Import libraries
import numpy as np
import cv2
import torch
from google.colab.patches import cv2_imshow
import imutils
device = 'cuda' if torch.cuda.is_available() else "cpu"
print("using device is", device)

# Import detectron2 utilities
from detectron2.config import get_cfg
from detectron2.projects.deeplab import add_deeplab_config
from detectron2.data import MetadataCatalog
from demo.defaults import DefaultPredictor
from demo.visualizer import Visualizer, ColorMode

# import OneFormer Project
from oneformer import (
    add_oneformer_config,
    add_common_config,
    add_swin_config,
    add_dinat_config,
    add_convnext_config,
)

以上で環境セットアップは完了です。

Helper関数の定義

モデルのロードや、タスク定義用のHelper関数を定義します。

SWIN_CFG_DICT = {
    "cityscapes": "configs/cityscapes/oneformer_swin_large_IN21k_384_bs16_90k.yaml",
    "coco": "configs/coco/oneformer_swin_large_IN21k_384_bs16_100ep.yaml",
    "ade20k": "configs/ade20k/oneformer_swin_large_IN21k_384_bs16_160k.yaml"
    }

DINAT_CFG_DICT = {
    "cityscapes": "configs/cityscapes/oneformer_dinat_large_bs16_90k.yaml",
    "coco": "configs/coco/oneformer_dinat_large_bs16_100ep.yaml",
    "ade20k": "configs/ade20k/oneformer_dinat_large_IN21k_384_bs16_160k.yaml"
    }

def setup_cfg(dataset, model_path, use_swin):
  # load config from file and command-line arguments
  cfg = get_cfg()
  add_deeplab_config(cfg)
  add_common_config(cfg)
  add_swin_config(cfg)
  add_dinat_config(cfg)
  add_convnext_config(cfg)
  add_oneformer_config(cfg)
  if use_swin:
    cfg_path = SWIN_CFG_DICT[dataset]
  else:
    cfg_path = DINAT_CFG_DICT[dataset]
  cfg.merge_from_file(cfg_path)
  cfg.MODEL.DEVICE = 'cpu'
  cfg.MODEL.WEIGHTS = model_path
  cfg.freeze()
  return cfg

def setup_modules(dataset, model_path, use_swin):
  cfg = setup_cfg(dataset, model_path, use_swin)
  predictor = DefaultPredictor(cfg)
  metadata = MetadataCatalog.get(
    cfg.DATASETS.TEST_PANOPTIC[0] if len(cfg.DATASETS.TEST_PANOPTIC) else "__unused"
  )
  if 'cityscapes_fine_sem_seg_val' in cfg.DATASETS.TEST_PANOPTIC[0]:
    from cityscapesscripts.helpers.labels import labels
    stuff_colors = [k.color for k in labels if k.trainId != 255]
    metadata = metadata.set(stuff_colors=stuff_colors)
    
  return predictor, metadata

def panoptic_run(img, predictor, metadata):
  visualizer = Visualizer(img[:, :, ::-1], metadata=metadata, instance_mode=ColorMode.IMAGE)
  predictions = predictor(img, "panoptic")
  panoptic_seg, segments_info = predictions["panoptic_seg"]
  out = visualizer.draw_panoptic_seg_predictions(
    panoptic_seg.to(device), segments_info, alpha=0.5
    )
  
  return out

def instance_run(img, predictor, metadata):
  visualizer = Visualizer(img[:, :, ::-1], metadata=metadata, instance_mode=ColorMode.IMAGE)
  predictions = predictor(img, "instance")
  instances = predictions["instances"].to(device)
  out = visualizer.draw_instance_predictions(predictions=instances, alpha=0.5)
  return out

def semantic_run(img, predictor, metadata):
  visualizer = Visualizer(img[:, :, ::-1], metadata=metadata, instance_mode=ColorMode.IMAGE)
  predictions = predictor(img, "semantic")
  out = visualizer.draw_sem_seg(
    predictions["sem_seg"].argmax(dim=0).to(device), alpha=0.5
  )
  return out

TASK_INFER = {
    "panoptic": panoptic_run, 
    "instance": instance_run, 
    "semantic": semantic_run
    }

学習済みモデルのセットアップ

ここでは、論文発表元が公開している学習済みモデルをGoogle Colaboratoryにダウンロードします。

以下では、ADE-20kデータセットでトレーニングされたbackborn DiNAT-Lを使用したモデルをダウンロードしています。

%cd /content/OneFormer
!mkdir pretrained

use_swin = False

if use_swin == False:
  # download wight, backborn: DiNAT-L, ADE20k dataset
  !wget -c https://shi-labs.com/projects/oneformer/ade20k/250_16_dinat_l_oneformer_ade20k_160k.pth \
        -O pretrained/250_16_dinat_l_oneformer_ade20k_160k.pth
  # init modules
  predictor, metadata = setup_modules("ade20k", "pretrained/250_16_dinat_l_oneformer_ade20k_160k.pth", use_swin)
else:
  # download wight, backborn: Swin-L, ADE20k dataset
  !wget -c https://shi-labs.com/projects/oneformer/ade20k/250_16_swin_l_oneformer_ade20k_160k.pth \
        -O pretrained/250_16_swin_l_oneformer_ade20k_160k.pth
  # init modules
  predictor, metadata = setup_modules("ade20k", "pretrained/250_16_swin_l_oneformer_ade20k_160k.pth", use_swin)

テスト画像のセットアップ

ここでは、モデルに入力する画像をWeb上から取得します。

%cd /content/OneFormer
!mkdir input_img

!wget -c https://www.pakutaso.com/shared/img/thumb/YAT4M3A7518_TP_V.jpg \
      -O input_img/test01.jpg

img = cv2.imread("input_img/test01.jpg")
img = imutils.resize(img, width=640)
cv2_imshow(img)

以下の画像を使用します。

input画像

panoptic segmentation

それでは、panoptic segmentationを実行します。

# setup task
task = "panoptic"

# inference
%load_ext autotime
out = TASK_INFER[task](img, predictor, metadata).get_image()

# show result
cv2_imshow(out[:, :, ::-1])

出力結果は以下の通りです。
任意の画像に対しても良好な精度で検出できています。

panoptic

instance segmentation

続いて、instance segmentatiaonを実行します。
先ほどと同じモデルに対してtaskを切り替えるのみで実行可能です。

# setup task
task = "instance"

# inference
%load_ext autotime
out = TASK_INFER[task](img, predictor, metadata).get_image()

# show result
cv2_imshow(out[:, :, ::-1])

出力結果は以下の通りです。

instance

semantic segmentation

最後にsemantic segmentationを実行します。

# setup task
task = "semantic"

# inference
%load_ext autotime
out = TASK_INFER[task](img, predictor, metadata).get_image()

# show result
cv2_imshow(out[:, :, ::-1])

出力結果は以下の通りです。

semantic

モデル一つで、それぞれのタスクを切り替えられることが確認できます。

まとめ

本記事では、OneFormerを用いてpanoptic/instance/semantic segmentationを行う方法を紹介しました。

モデルを一本化できることで、トレーニング時間を削減でき、モデルの管理も容易になるため、社会実装向け技術であるように思います。

また本記事では、機械学習を動かすことにフォーカスしてご紹介しました。
もう少し学術的に体系立てて学びたいという方には以下の書籍などがお勧めです。ぜひご一読下さい。


また動かせるだけから理解して応用できるエンジニアの足掛かりに下記のUdemyなどもお勧めです。

参考文献

1.  論文 - OneFormer: One Transformer to Rule Universal Image Segmentation

2. GitHub - SHI-Labs/OneFormer

AIで副業ならココから!

まずは無料会員登録

プロフィール

メーカーで研究開発を行う現役エンジニア
組み込み機器開発や機会学習モデル開発に従事しています

本ブログでは最新AI技術を中心にソースコード付きでご紹介します


Twitter

カテゴリ

このブログを検索

ブログ アーカイブ

TeDokology