SingleShotPoseをYOLOv2-Tinyベースにして高速化を試みる2
前回の記事からの続きです。
akifukka.hatenablog.com
6.Google Colaboratory ノートブックの作成
過去の記事と重なるところもありますが念のため。
- Googleドライブのsingleshotposeフォルダで右クリックして
「その他」-「Google Colaboratory」
で新規ノートブックを開きます。 - ランタイム-ランタイムのタイプを変更で次の通りセットアップします。
ランタイムのタイプ :Python3
ハードウェアアクセラレータ :GPU
このノートブックを保存する際にコードセルの出力を除外する:チェックを付ける(注)
(注)チェックを入れておかないとRefresh時に毎回ポップアップで確認を要求されてAuto Refrshが機能しません。
7.Google Colaboratoryの準備
過去の記事と重複しますが念のため。
(1)Googleドライブをマウントします。ノートブックで次を実行します。
from google.colab import drive
drive.mount('/content/drive')
(2)Googleドライブの中身をColaboratoryにコピーします。
%%bash
cp -r /content/drive/My\ Drive/singleshotpose/singleshotpose ./
(3)Colaboratoryのディスク上で解凍します。Googleドライブ上で解凍すると、えらく時間(半日)がかかりますが、Colaboratoryのディスク上では1分程度です。
%%bash
cd singleshotpose
tar xf LINEMOD.tar LINEMOD/ape
tar xf backup.tar backup/ape
tar xf backup_multi.tar -C multi_obj_pose_estimation/
tar xf VOCtrainval_11-May-2012.tar
8.学習
次のコマンドでサルの人形の姿勢推定の学習を開始します。3時間くらいかかります。Chromeをお使いならAuto Refreshを使った方がいいかもしれません。
Auto Refreshを使うと、最初のRefresh時だけポップアップが出るのでOKしてください。念のためRefresh時間を15秒くらいにして、2回目以降のRefresh時はポップアップが出ないのを確認してから、1時間に変更して最初のRefresh時のポップアップ確認をするのを推奨します。2回くらい失敗して止まってしまいました。結局原因はよくわからず、ポップアップを手動で確認してました・・・。
%%bash
cd /content/singleshotpose
python train.py --datacfg cfg/ape.data --modelcfg cfg/yolo-tiny-pose.cfg --initweightfile cfg/yolov2-tiny.conv.13 --pretrain_num_epochs 15
9.作動確認
(1)画像なし版
次のコマンドで動かしてみます。
%%bash
cd /content/singleshotpose
python valid.py --datacfg cfg/ape.data --modelcfg cfg/yolo-tiny-pose.cfg --weightfile /content/drive/My Drive/singleshotpose/singleshotpose/backup/ape/model.weights
YOLOv2版(高速化前)
YOLOv2-tiny版(高速化後)
計算時間は半分くらいになっていますが、次の通り誤差はだいぶ悪化しているようです。学習条件、ネットワーク構造等改善の余地ありそうです・・。
Mean 2D pixel error 2.68 -> 102.7
Mean vertex error 0.036 -> 0.319
Mean corner error 4.05 -> 21.46
Translation error 0.035m -> 0.318m
angle error 6.17deg -> 38.12deg
pixel error 2.68pix -> 102.7pix
(2)画像あり版
過去の記事と同じく、SingleShotPoseのプロジェクトに画面表示させるノートブックがあるので、この中身をコピーして使います
最初のコード(初期化の部分)
scipy.misc.imresizeのかわりにpillow及びnumpyを使います。赤字を追加します。
%matplotlib inline
import os
import time
import torch
from torch.autograd import Variable
from torchvision import datasets, transforms
import scipy.io
import warnings
warnings.filterwarnings("ignore")
import matplotlib.pyplot as plt
import scipy.misc
# insert
import numpy
from PIL import Image
# insert end
from darknet import Darknet
・
・
2番目のコード
変更箇所は2箇所です。赤字の通り変更します。
・コード全体の真ん中より下あたりです。visualizeで検索すると見つけられます。
・一番最後のところです。
if visualize:
# Visualize
plt.xlim((0, im_width))
plt.ylim((0, im_height))
# insert
# plt.imshow(scipy.misc.imresize(img, (im_height, im_width)))
plt.imshow(numpy.array(Image.fromarray(numpy.uint8(img*255)).resize((im_width,im_height))))
# insert end
# Projections
for edge in edges_corners:
plt.plot(proj_corners_gt[edge, 0], proj_corners_gt[edge, 1], color='g', linewidth=3.0)
plt.plot(proj_corners_pr[edge, 0], proj_corners_pr[edge, 1], color='b', linewidth=3.0)
plt.gca().invert_yaxis()
plt.show()
# Compute 3D distances
・
・
・
datacfg = 'cfg/ape.data'
#modelcfg = 'cfg/yolo-pose.cfg'
#weightfile = 'backup/ape/model_backup.weights'
modelcfg = 'cfg/yolo-tiny-pose.cfg'
weightfile = '/content/drive/My Drive/singleshotpose/singleshotpose/backup/ape/model.weights'
valid(datacfg, modelcfg, weightfile)
上記を変更後、順番に実行します。大量に画像が表示されるので適当に止めます。
YOLOv2版とYOLOv2-Tiny版の比較
YOLOv2版は青(推定値)と緑(正解値)が重なっているが、Tiny版は青が傾いています。
10.Jetson nanoで動かしてみる
(1)次の3つのファイルをJetson Nanoにコピーします。
- マイドライブ/singleshotpose/singleshotpose/backup/ape/model.weights
- マイドライブ/singleshotpose/singleshotpose/cfg/yolo-tiny-pose.cfg
- マイドライブ/singleshotpose/singleshotpose/darknet.py
(前回の記事5.で変更済みのもの)
上記をパソコンにダウンロード、ブラウザにJetson nanoのIPアドレス:8888を入力してJupitorLabを立ち上げ、左側のFile Browserにドラッグ&ドロップするとJetson Nanoにコピーできます。
(注)JetcardをインストールしないとJupitorを使えないかもしれません。インストールは次の記事の3.を参考にしてください。
(2)Containerの準備
本記事の最初の記事でJetson NanoにContainerを導入してSingleShotPoseを動かす環境を構築済みだとします。
Jetson NanoでSingleShotPoseを動かす - やってみた!
また、Containerの名前もsingleshotposeに変更されているものとします。
以降はJetson Nano上でのコマンド入力です。ちなみに、2019年10月末時点で、Container内にインストールされるパッケージのバージョンは次のとおりでした。
scipy 0.19.1
pytorch 1.3.0
torchvision 0.5.0
パッケージのバージョンはContainerの端末から次のコマンドで確認できます。
pip3 freeze
・Container起動
sudo docker start -i singleshotpose
・darknet.pyの退避
Dockerの端末で、次のコマンドで名前を変更します。
cd singleshotpose
mv darknet.py darknet_bak.py
・ファイルをContainerにコピー
ファイルのあるディレクトリで右クリック、Open in Terminal
sudo docker cp darknet.py singleshotpose:/singleshotpose
sudo docker cp yolo-tiny-pose.cfg singleshotpose:/singleshotpose/cfg
sudo docker cp model.weights singleshotpose:/singleshotpose/backup/ape
(3)実行
python3 valid.py --datacfg cfg/ape.data --modelcfg cfg/yolo-tiny-pose.cfg --weightfile backup/ape/model.weights
1枚あたりの計算時間は次の通り短縮されましたが期待ほどではありませんでした・・。
forward pass 0.020s -> 0.008s
get_region_box 0.51s -> 0.18s
prediction time 0.53s -> 0.19s
ここまでのノートブックのpdfを参考に張り付けておきます。
https://drive.google.com/file/d/1oc_Non9d7dTSiS4NUVuPBRyQ0y8eXbiN/view?usp=sharing
11.まとめ
SingleShotPoseのネットワーク構造をYOLOv2からYOLOv2-Tinyに変更、学習して約2.5倍高速化することが可能なことがわかりました。ただし精度が大幅に悪化しており改善の余地がありそうです。
12.追加で学習してみました
左がYOLOv2、真ん中がTiny、右が学習を何回か繰り返した結果です。
学習を繰り返してもこれ以上は改善しなさそうでした。
Mean 2D pixel error 2.68 -> 102.7 -> 25.4
Mean vertex error 0.036 -> 0.319 -> 0.117
Mean corner error 4.05 -> 21.46 -> 8.61
Translation error 0.035m -> 0.318m -> 0.117m
angle error 6.17deg -> 38.12deg -> 16.29deg
pixel error 2.68pix -> 102.7pix -> 25.4pix
おしまい