Mask R-CNNで、一般物体検出、セグメンテーションを実装する

こんにちは。山本@ABです。ようやく私も、テックブログに参戦です。

本日は、COCOデータセットにより学習済の、Mask R-CNN※というモデルを利用して、一般物体検出、セグメンテーションを動かしてみます。

今回紹介するのは、2019/3/22に発売された「AIプロジェクト実践読本」の第4章にかかれている推論プログラムの開発手順とほぼ同様の構成としています。

書籍をご購入いただけた方へ => 手順をタイピングするのが面倒な場合は、本ページからソースコードやコマンドをコピペしていただいてOKです!

「AIプロジェクト実践読本」には、Git や 開発環境(Visual Studio 2017)、必要なランタイムライブラリのインストール手順が手厚く書かれています。初心者の方は、書籍も合わせて参考にしてみてください。さらにはディープラーニングの実装上の構成要素として、「フレームワーク」「ネットワークモデル」「学習済みモデル」それぞれの定義、関連性も解説していますので、手っ取り早く理解をされたい方にはおすすめです。

課題解決とサービス実装のためのAIプロジェクト実践読本 ~第4次産業革命時代のビジネスと開発の進め方~

課題解決とサービス実装のためのAIプロジェクト実践読本 ~第4次産業革命時代のビジネスと開発の進め方~

  • 作者: 山本大祐,株式会社オプティム
  • 出版社/メーカー: マイナビ出版
  • 発売日: 2019/03/22
  • メディア: 単行本(ソフトカバー)
  • この商品を含むブログを見る

Google Colaboratory で動かす

  • 前提条件
    • 用意するもの
      • インターネットに接続されたPC1台(Chromeが動作する環境)
      • Googleアカウント1つ(Google Coraboratoryを利用する為)
  • 手順
    1. Google Colaboratory上で新しい実行空間を作成し、GPUを有効にする
    2. GitHubからMask R-CNNのソースコードを取得し、セットアップする
    3. GitHubからCOCO APIのソースコードを取得し、セットアップする
    4. COCOデータセットで訓練済のMask R-CNN学習済モデルをダウンロードする
    5. それを使ってサンプル画像を推論させて、結果を画面に表示する

※今回紹介するMask R-CNNの実装は、matterport社が公開するGitHubリポジトリのソースコードを使わせていただきます。

1. Colaboratoryの新しいドキュメントを作成し、GPUを有効にする

Webブラウザーで "https://colab.research.google.com/" を開きます。または、"Colaboratory" とググっても良いでしょう。

「PYTHON 3 の新しいノートブック」を選択します。これでドキュメント空間が作成されました。今回はGPUを使いますので、メニューの「ランタイム」→「ランタイムのタイプを変更」を開き、「ハードウェア アクセラレータ」を "GPU" としておきます。

2. Mask R-CNNのソースコードを取得し、セットアップする

GitHubからMask R-CNNのソースコードを取得します。Colaboratoryが提供してくれる仮想マシン上の "/content" ディレクトリにソースがクローンされるようにします。次に、Mask R-CNNが必要とするnumpy, tensorflow, kerasなどのライブラリはリポジトリに含まれる "requirements.txt" に記載されていますので、こちらを全てpipでインストールします。最後に、リポジトリに含まれるセットアップスクリプト "setup.py" を実行して完了です。

# gitからソースを取得
%cd /content
!git clone https://github.com/matterport/Mask_RCNN.git
  
# ライブラリを取得
%cd /content/Mask_RCNN
!pip install -r requirements.txt

# setup.pyを実行
%cd /content/Mask_RCNN
%run -i setup.py install

3. COCO APIのソースコードを取得し、セットアップする

GitHubからCOCO APIのソースコードを取得します。リポジトリに含まれるセットアップスクリプト "setup.py" を実行して完了です。

# COCO 用ソースを取得
%cd /content
!git clone https://github.com/waleedka/coco.git

# python用APIをインストール
%cd /content/coco/PythonAPI
%run -i setup.py build_ext --inplace
%run -i setup.py build_ext install

4. COCOデータセットで訓練済のMask R-CNN学習済モデルをダウンロードする

ここからはPythonを使ったコーディングになります。同様のソースコードが、Mask R-CNNリポジトリの "samples/demo.ipynb" にあるため、そちらをコピペして実行しても同じ結果が得られます。その場合、冒頭のROOT_DIR変数を仮想マシン上のパスである "/content/Mask_RCNN" に書き換える必要があるため、注意しましょう。

以下は、各種初期設定と、COCOデータセットで訓練済のMask R-CNN学習済モデルをダウンロードするまでの一連の処理となります。

import os
import sys
import random
import math
import numpy as np
import skimage.io
import matplotlib
import matplotlib.pyplot as plt

# Root directory of the project
ROOT_DIR = os.path.abspath("/content/Mask_RCNN")

# Import Mask RCNN
sys.path.append(ROOT_DIR)  # To find local version of the library
from mrcnn import utils
import mrcnn.model as modellib
from mrcnn import visualize
# Import COCO config
sys.path.append(os.path.join(ROOT_DIR, "samples/coco/"))  # To find local version
import coco

%matplotlib inline 

# Directory to save logs and trained model
MODEL_DIR = os.path.join(ROOT_DIR, "logs")

# Local path to trained weights file
COCO_MODEL_PATH = os.path.join(ROOT_DIR, "mask_rcnn_coco.h5")
# Download COCO trained weights from Releases if needed
if not os.path.exists(COCO_MODEL_PATH):
    utils.download_trained_weights(COCO_MODEL_PATH)

# Directory of images to run detection on
IMAGE_DIR = os.path.join(ROOT_DIR, "images")

5. サンプル画像を推論して、結果を画面に表示する

これで全ての準備が整ったため、Mask R-CNNリポジトリに含まれるサンプル画像を読み込ませて推論させていきます。

class InferenceConfig(coco.CocoConfig):
    # Set batch size to 1 since we'll be running inference on
    # one image at a time. Batch size = GPU_COUNT * IMAGES_PER_GPU
    GPU_COUNT = 1
    IMAGES_PER_GPU = 1

config = InferenceConfig()
# config.display()


# Create model object in inference mode.
model = modellib.MaskRCNN(mode="inference", model_dir=MODEL_DIR, config=config)

# Load weights trained on MS-COCO
model.load_weights(COCO_MODEL_PATH, by_name=True)


# COCO Class names
# Index of the class in the list is its ID. For example, to get ID of
# the teddy bear class, use: class_names.index('teddy bear')
class_names = ['BG', 'person', 'bicycle', 'car', 'motorcycle', 'airplane',
               'bus', 'train', 'truck', 'boat', 'traffic light',
               'fire hydrant', 'stop sign', 'parking meter', 'bench', 'bird',
               'cat', 'dog', 'horse', 'sheep', 'cow', 'elephant', 'bear',
               'zebra', 'giraffe', 'backpack', 'umbrella', 'handbag', 'tie',
               'suitcase', 'frisbee', 'skis', 'snowboard', 'sports ball',
               'kite', 'baseball bat', 'baseball glove', 'skateboard',
               'surfboard', 'tennis racket', 'bottle', 'wine glass', 'cup',
               'fork', 'knife', 'spoon', 'bowl', 'banana', 'apple',
               'sandwich', 'orange', 'broccoli', 'carrot', 'hot dog', 'pizza',
               'donut', 'cake', 'chair', 'couch', 'potted plant', 'bed',
               'dining table', 'toilet', 'tv', 'laptop', 'mouse', 'remote',
               'keyboard', 'cell phone', 'microwave', 'oven', 'toaster',
               'sink', 'refrigerator', 'book', 'clock', 'vase', 'scissors',
               'teddy bear', 'hair drier', 'toothbrush']


# Load a random image from the images folder
file_names = next(os.walk(IMAGE_DIR))[2]
for file_name in file_names:
  image = skimage.io.imread(os.path.join(IMAGE_DIR, file_name))

  # Run detection
  results = model.detect([image], verbose=1)

  # Visualize results
  r = results[0]
  visualize.display_instances(image, r['rois'], r['masks'], r['class_ids'], 
                              class_names, r['scores'])

Webブラウザー上に実行結果として、レンダリングされた画像がいくつか表示されれば成功です。

https://cdn-ak.f.st-hatena.com/images/fotolife/o/optim-tech/20190328/20190328134712.png

Jupyter Notebookを使ってローカルマシンで動かす

Mask R-CNNの基本的な動作が確認できたら、身近なカメラデバイスであるWebカメラやAndroidスマホ等を接続し、あなたの手元のマシンで実行する、リアルタイム推論にチャレンジしていきましょう。

  • 前提条件
    • Webカメラが搭載されたMacまたはWindows PC
      • 高速なリアルタイム推論を行う場合は、nvidia-driverをインストールできるGPUが搭載されたマシンを推奨(ここではWindows10を用いた手順を説明します)
      • GPUが無い場合は、フレームレートが遅くなるが、CPUによる推論を行う
    • Android OSがインストールされたスマホまたはタブレット(後のスマホカメラとの結合に利用)
  • 手順
    • 実行環境を整える
      1. Minicondaで仮想環境(Python, Jupyter Notebook, TensorFlow, Keras)を作成する
      2. Jupyter Notebook上で新しい実行空間を作成する
      3. Mask R-CNN 及び COCO API のソースコードを取得し、それぞれセットアップする
      4. COCOデータセットで訓練済のMask R-CNN学習済モデルをダウンロードする
    • Webカメラを連携する
      1. Webカメラからリアルタイム画像を取得し、結果を画面に表示する
    • スマホカメラを連携する
      1. スマホカメラをIPカメラ化する
      2. スマホカメラからリアルタイム画像を取得し、結果を画面に表示する

1. Minicondaで仮想環境(Python, TensorFlow, Keras, Jupyter)を作成する

はじめに、Minicondaをインストールします。"https://conda.io/en/latest/miniconda.html" より、自分の環境にあったインストーラをダウンロードして、実行します。Minicondaがインストールできたらターミナル(Windowsの場合はAnaconda Prompt)を開き、以下のコマンドで TensorFlow, Keras, Jupyter の仮想環境を作成し、アクティベートします。

$ conda create -n ai tensorflow-gpu keras jupyter
$ conda activate ai

Mac利用者や、GPUに対応していない環境では "tensorflow-gpu" が存在しないとエラーになる場合があります。その場合は以下のように "-gpu"を外したTensorFlowを指定してください。GPU環境と比較して実行速度がお取りますが、CPUでの推論により動作自体は可能です。

$ conda create -n ai tensorflow keras jupyter
$ conda activate ai

また、TensorFlow, Kerasについてはバージョン違いで動作がうまくいかない場合があります。その場合は、以下のようにバージョンを固定してインストールを試みてみてください。

$ conda install -c conda-forge tensorflow=1.3
$ pip install keras==2.0.8

Windowsの場合は、MS VCコンパイラを使うため、Visual Studio 2017をインストールしておいてください。無償のCommunity版で構いませんが、インストール時に「C++ ワークロードを使用したデスクトップ開発」を選択します。

2. Jupyter Notebook上で推論プログラムを実行する

以下のコマンドを実行して、Jupyter Notebookを起動します。

$ jupyter notebook

Webブラウザー上に開かれたJupyter Notebook上で、作業用ディレクトリを作成します。今回は、"~/work" フォルダを作成して、そこに Python3 のノートブックを作成しましょう。このページでは、以降の細かい手順の説明はしませんが、以下のファイルをJupyter Notebook上で実行すると、目的のプログラムが実行できるはずです。

ダウンロード (maskrcnn_camera.ipynb) * https://drive.google.com/open?id=141bbsGRqkKDpnOL0CckeMvOo_e6KH2od

Webカメラやスマホカメラと連携させ、リアルタイム推論を動かしている様子。

https://cdn-ak.f.st-hatena.com/images/fotolife/o/optim-tech/20190328/20190328134701.png

細かい手順を知りたい方は、「AIプロジェクト実践読本」の第4章と照らし合わせながら理解を進めてみると良いでしょう。

課題解決とサービス実装のためのAIプロジェクト実践読本 ~第4次産業革命時代のビジネスと開発の進め方~

課題解決とサービス実装のためのAIプロジェクト実践読本 ~第4次産業革命時代のビジネスと開発の進め方~

  • 作者: 山本大祐,株式会社オプティム
  • 出版社/メーカー: マイナビ出版
  • 発売日: 2019/03/22
  • メディア: 単行本(ソフトカバー)
  • この商品を含むブログを見る

トラブルシューティング

2019年3月27日現在、Jupyter Notebookを普通に入れてしまうと、画面が真っ白になるという不具合が起きるそうです。 その場合は、conda install notebook=5.7.4 などとして、notebookのバージョンを落としてみると、うまくいくようです。

qiita.com

また、「AIプロジェクト実践読本」の第4章の手順では、Cython と scikit-image がインストールされないようなので、つまずくようであれば入れてあげてください。

$ conda install cython
$ conda install scikit-image

GPUを利用する環境では、実行時に以下のエラーが出る可能性があります。この場合、CUDA SDKのインストール(および、CUDAドライバーのインストール)をしてあげてください。

InternalError: cudaGetDevice() failed. Status: CUDA driver version is insufficient for CUDA runtime version

qiita.com

おわりに

凄まじい勢いで新規サービスローンチ・ビジネス立上げを行うオプティムは、必要とされる技術が日進月歩で変遷する空間でもあります。 新しい要素技術、開発手法を身に着けながら、まだ見ぬサービスを作り出したいと意気込みをお持ちの方、ぜひお問い合わせてください!

www.optim.co.jp