➊ はじめに
リアルタイムで手の形を認識できれば、手話など色々なものへ応用が利きそうですよね。
以前は、YOLOを使用して、バウンディングボックスによる「じゃんけん」検出を行いました。今回は、YOLACTを使用して、セグメンテーションによる「じゃんけん」検出ができるかを検証したいと思います。なお、バウンディングボックスは画像内の物体の位置やクラスを検出しますが、セグメンテーションはそれに加えて画像内の各画素がどのカテゴリーに属するかまで検出するものです。

なお、セグメンテーションでの認識は、道路を認識したり、人や車を認識したりと自動運転などにも利用されている技術です。
➋ やること
「じゃんけん画像」から新たに学習データを作成し、YOLACTにより、新しい物体がセグメンテーションレベルで認識できるかの検証とそこまでのプロセスの確認をしたいと思います。(認識率云々ではなく、あくまで、物体認識までのプロセス確認がメインターゲットです。)
- 「じゃんけん画像」から新たに学習データを作成
- 「じゃんけん」がリアルタイムにセグメンテーションレベルで認識できるかの検証
- 「じゃんけん」検出の全体プロセスの確認
➌ 開発環境
学習はGPUが使用できるGoogle Colabで実施し、リアルタイム認識はwebcamが使えるLocal PCで実施したいと思います。
(1)開発環境
| 開発環境 | 備考欄 | 
|---|---|
| Google Colab | 学習(モデル生成)時に使用します。Googleアカウントがあれば誰でも無料で使用できます。GPUを利用でき学習スピードがとても早いためこちらを利用します。Google Colabでの利用の仕方は「 tutorial.ipynb」を参照すると便利です。 | 
| Local PC with webカメラ | 静止画撮影、ラベリング、物体検出時に使用します。今回は Local PCとして、win10を使用しました。pythonの仮想環境はanacondaを利用しました。 | 
(2)使用ツール
■Google Colab
| 必要なツール類 | 備考欄 | 
|---|---|
| YOLACT | Google Colab上では、学習(モデル生成)時に使います。フリーウェア(MIT Licence)です。 | 
■ローカルPC
| 必要なツール類 | 備考欄 | 
|---|---|
| YOLACT | ローカルPC上では、物体検出時に使います。 | 
| カメラアプリ   | win10標準アプリ。静止画撮影時に使います。相応のもので撮影できれば何でもOKです。 | 
| coco-annotaror | 学習データのアノテーションに使用します。フリーウェア(MIT License)です。 | 
➍ 学習データ収集
➤Local PCで作業してください。
静止画を集めるために、まずLocal PC(win10)でカメラアプリを起動し、グー・チョキ・パーの撮影を行います。Local PCにwin10以外を使用する方は、相応のアプリで写真を撮ってください。
(1)カメラアプリ設定
カメラアプリの設定ですが、写真の解像度を640x480の設定にしました。低速度撮影をONにし、2秒タイマーをかけると連続撮影がとても楽です。

(2)静止画撮影
「グー・チョキ・パー」を色んな角度から写真を撮ってください。私はアノテーション作業を簡素化するために、「グー・チョキ・パー」それぞれ単体の写真を各2枚ずつ、計6枚写真を撮りました。(みなさんは、いっぱい撮影してくださいね😅)

➎ アノテーション
➤Local PCで作業してください。
作業内容は、記事にまとめていますので、「こちらの記事」をご参考にアノテーションを作成してください。
ここでは説明を割愛します。
 
作成したアノテーションデータは、Local PCでは使用しませんが、後で、学習のためGoogle Colabへコピーしますので、以下のようにまとめておいてください。
janken
  │
  ├─choki1.jpg     … 画像データ
  ├─choki2.jpg
  ├─goo1.jpg
  ├─goo2.jpg
  ├─par1.jpg
  ├─par2.jpg
  └─janken.json    … cocoフォーマット
※janken.jsonに画像データまでのPATHを記載する部分がありますが、YOLACTはここを参照しません。YOLACTのconfigデータに画像までのPATHを記載するようになっていますので、画像のPATHを変更してもjanken.jsonの編集は不要です。
➏ Google Colab作業
➤Google Colabで作業してください。
(1)環境構築
環境構築の詳細は、記事にまとめていますので、「こちらの記事」をご参照ください。
■ライブラリインストール
!pip install cython
!pip install opencv-python pillow pycocotools matplotlib
!pip install torchvision==0.5.0
!pip install torch==1.4.0
■YOLACTインストール
%cd /content
!git clone https://github.com/dbolya/yolact.git
(2)学習データ移行
■学習データコピー
先程Local PCで作ったアノテーションデータ(janken)をGoogle Colabの「yolact/data/」配下へコピーしてください。
yolact
  └─data
    └─janken
       ├─choki1.jpg     … 画像データ
       ├─choki2.jpg
       ├─goo1.jpg
       ├─goo2.jpg
       ├─par1.jpg
       ├─par2.jpg
       └─janken.json    … cocoフォーマット
※Google Colabにコピーしたデータは、揮発しますので、ご注意を!長期的に学習を行う場合は、Google Drive等へ格納することをオススメします。
■YOLACTのCONFIG書き換え
アノテーションデータ(janken)を読み込めるように、「config.py」を書き換えます。以下の2箇所に「janken_dataset」と「yolact_resnet50_janken_config」を追加します。
「
config.py」は、以下の場所にあります。
yolact/data/config.py
❖1箇所目:「DATASETS」の終わりに以下追加
                                   ︙
# ----------------------- DATASETS ----------------------- #
                                   ︙
################################# 追加 ####################################### 
janken_dataset = dataset_base.copy({
    'name'        : 'Janken',
    # 学習用
    'train_info'  : 'data/janken/janken.json',
    'train_images': 'data/janken/',
    # 検証用
    'valid_info'  : 'data/janken/janken.json',
    'valid_images': 'data/janken/',
    'has_gt'      : True,
    # クラス名
    # janken.jsonの[categories]-[name]を参照して設定すること
    'class_names' : ('choki', 'goo', 'par',),
    # ラベルマップ
    # janken.jsonの[categories]-[id]を参照して設定すること
    'label_map'   : { 9:1, 10:2, 11:3 }
})
################################# 追加 ####################################### 
                                   ︙
❖2箇所目:「YOLACT v1.0 CONFIGS」の終わりに以下追加
                                   ︙
# ----------------------- YOLACT v1.0 CONFIGS ----------------------- #
                                   ︙
################################# 追加 ####################################### 
yolact_resnet50_janken_config = yolact_resnet50_config.copy({
	'name': 'yolact_resnet50_janken',
	# Dataset stuff
	'dataset': janken_dataset,
	'num_classes': len(janken_dataset.class_names) + 1,
	# Image Size
	'max_size': 640,
})
################################# 追加 ####################################### 
                                   ︙
(3)学習用重みダウンロード
以下コマンドにて、学習用の重み「resnet50-19c8e357.pth (約100MB)」を、「/yolact/weights/」配下へダウンロードします。
%cd /content/download_google_drive
!python download_gdrive.py\
            1Jy3yCdbatgXa5YYIdTCRrSV0S9V5g1rn\
            /content/yolact/weights/resnet50-19c8e357.pth
(4)学習
■train.py実行
train.pyにより学習を始めます。--batch_size=6としているのは、学習データが6個のため。普通はこんな少ないことは無いと思いますが、学習データが7個以下(8個未満)の場合は、これをつけないとエラーになります。
%cd /content/yolact/
!python train.py --config=yolact_resnet50_janken_config\
                 --batch_size=6\
                 --save_folder=weights/
■train.py実行結果
数分~数時間程度、放ったらかしにし学習を進めさせます…
Scaling parameters by 0.75 to account for a batch size of 6.
loading annotations into memory...
Done (t=0.00s)
creating index...
index created!
loading annotations into memory...
Done (t=0.00s)
creating index...
index created!
Initializing weights...
Begin training!
/content/yolact/utils/augmentations.py:309: VisibleDeprecationWarning: Creating an ndarray from ragged nested sequences (which is a list-or-tuple of lists-or-tuples-or ndarrays with different lengths or shapes) is deprecated. If you meant to do this, you must specify 'dtype=object' when creating the ndarray
  mode = random.choice(self.sample_options)
[  0]       0 || B: 5.329 | C: 17.079 | M: 4.833 | S: 2.806 | T: 30.047 || ETA: 19 days, 4:35:06 || timer: 1.554
/content/yolact/utils/augmentations.py:309: VisibleDeprecationWarning: Creating an ndarray from ragged nested sequences (which is a list-or-tuple of lists-or-tuples-or ndarrays with different lengths or shapes) is deprecated. If you meant to do this, you must specify 'dtype=object' when creating the ndarray
  mode = random.choice(self.sample_options)
/content/yolact/utils/augmentations.py:309: VisibleDeprecationWarning: Creating an ndarray from ragged nested sequences (which is a list-or-tuple of lists-or-tuples-or ndarrays with different lengths or shapes) is deprecated. If you meant to do this, you must specify 'dtype=object' when creating the ndarray
  mode = random.choice(self.sample_options)
Computing validation mAP (this may take a while)...
Calculating mAP...
       |  all  |  .50  |  .55  |  .60  |  .65  |  .70  |  .75  |  .80  |  .85  |  .90  |  .95  |
-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+
   box | 52.59 | 100.0 | 100.0 | 100.0 | 58.58 | 50.17 | 50.17 | 50.17 | 16.83 |  0.00 |  0.00 |
  mask | 95.02 | 100.0 | 100.0 | 100.0 | 100.0 | 100.0 | 100.0 | 100.0 | 100.0 | 75.08 | 75.08 |
-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+
(5)学習終了
■学習終了→モデル生成
Calculating mAPを見て、良い結果が得られたら学習を中断させます。学習を中断させると、そこまで学習させたネットワークが「--save_folder」に生成されます。Google Colabでの中断のさせ方は、「ストップボタン」を押すか、「CTRL+MI」で中断させることができます。
※PCで学習させている場合は、普通に「CTRL+C」で中断です。
Stopping early. Saving network...
生成されるモデルのファイル名は、「<config>_<epoch>_<iter>.pth」となります。
例えば、今回はこんな感じのファイル名でモデルが生成されました。yolact/weights/
yolact_resnet50_janken_1364_1364_interrupt.pth(約120MB)
➐ Local PC作業
➤Local PCで作業してください。
(1)環境構築
環境構築の詳細は、記事にまとめていますので、「こちらの記事」をご参照ください。
■Python環境構築
conda create -n yolact37 python=3.7
conda activate yolact37
■YOLACTインストール
git clone https://github.com/dbolya/yolact
cd yolact
■ライブラリインストール
pip install cython matplotlib opencv-python "pillow<7.0" PyQt5
pip install "git+https://github.com/philferriere/cocoapi.git#egg=pycocotools&subdirectory=PythonAPI"
pip install torch==1.2.0 torchvision==0.4.0 -f https://download.pytorch.org/whl/torch_stable.html
■モデルの保存
Google Colabで生成したモデル(yolact_resnet50_janken_1364_1364_interrupt.pth)をLocal PCの「yolact/weights/」配下へダウンロードします。
(2)物体検出
それではいよいよ今回のクライマックスです😊ドキドキ❤
■eval.py実行
Local PCで以下のコマンドを実行してください。
「--video=0」を別な番号(0, 1, 2, …)に変えると、別のデバイスを使うこともできます。
python eval.py --trained_model=weights/yolact_resnet50_janken_1364_1364_interrupt.pth --score_threshold=0.1 --top_k=3 --video_multiframe=1 --video=0
■eval.py実行結果
学習データがありえないくらい少ない状況でしたが、「グー・チョキ・パー」をリアルタイムでちゃんと認識できました😄🎉
しかし、学習データをケチったため、認識率はかなり低く、セグメンテーションもちょっと雑ですね。もっと学習データが欲しいです。

➑ OMAKE
色々記事を書いているので、まとめておきます。
(1)画像認識ツール紹介記事
| No. | ツール名 | 検出ターゲット | 環境 | 記事 | Thumbnail | 
|---|---|---|---|---|---|
| 1 | YOLO v5 | じゃんけん検出 | ①GoogleColab ②LocalPC+webcam | 【YOLO V5】AIでじゃんけん検出 |  | 
| 2 | YOLACT | じゃんけん検出 | ①GoogleColab ②LocalPC+webcam | 【YOLACT】AIでじゃんけん検出 |  | 
| 3 | YOLACT | COCOデータセット | ①GoogleColab | 【リアルタム物体検知】YOLACT for Google Colab【YOLOを超えた?】 |  | 
| 4 | YOLACT | COCOデータセット | ①LocalPC+webcam | 【リアルタム物体検知】YOLACT for win10+webcam【セグメンテーション検出】 |  | 
(2)アノテーションツール紹介記事
| No. | ツール名 | 対応フォーマット | 対応ツール | 記事 | Thumbnail | 
|---|---|---|---|---|---|
| 1 | labelImg | YOLO/PascalVOC形式 | YOLO v5 … | 【YOLO V5】AIでじゃんけん検出 |  | 
| 2 | coco-annotator | COCO形式 | YOLACT … | 【coco-annotaror】アノテーションツール |  | 
➒ 以上
学習データがありえないくらい少なく、また教師データと検証データも同じという最悪の状況でしたが、なんとか**「じゃんけん」を認識してくれました**😊。セグメンテーションで物体検出をさせる場合、学習データのアノテーション作業がとても時間がかかる作業となってきます。仕事であれば発注したいレベルです。QiitaのAI好きが集まって「学習データをみんなで作ろう会」を発足したい気分でした😁。
ちなみに「じゃんけん」の検出において、セグメンテーション方式で検出する意味はないんじゃないかと思いましたが、AIがなぜそれを「Goo」と認識したのかなど推論の見える化ができて、これはこれでありなんじゃないかと思いました。
技術はどんどん進化していて、数年後にはこの技術も当たり前になっていると思うと、なんかワクワクしてきますね😉。
お疲れ様でした!
