
New(2021/02/17)
Jetson Nanoで学習済みモデルを使って、いろいろやってみる(2-1)転移学習(ResNet-18)
でやった再学習(トレーニング)をColabでやってみました。
Jetson Nanoで学習済みモデルを使って、いろいろやってみる(2-1)ではResNet-18の学習済みモデルを使ってみました。ここではSSD-Mobilenetを使ってみます。
チュートリアルはこちら。Re-training SSD-Mobilenet
画像を使うトレーニングはかなりのリソースを使います。Jetson Nano には負担が大きいです。
そこで今回はトレーニングはGoogle Colab、推論はJetson Nano という具合に役割を分担してやってみます。
チュートリアルでは8種類のフルーツを分類検出していますが、趣向を変えてオフィス用品を分類検出してみます。
使うデータセットはGoogleのOpen Images Dataset V6です。601クラスあります。
その中から以下の5クラスを使います。
Printer:プリンタ
Television:テレビジョン
Whiteboard:ホワイトボード
Chair:いす
Desk:つくえ
こんな感じ。
以下で/home/jetson となっている部分は適宜ご自分のユーザー名で置き換えてください。
チュートリアルにあるようにまずはJetsonにコンテナを作成
これはJetsonの推論実行用の環境です。
ここで作られるコンテナにはdetectnet(バイナリ)やTensorRT(共有オブジェクト)、jetsonモジュールなどが含まれています。
イメージはjetpack(4.4.1)ベースで、OSはUbuntu 18.04.5 LTSです。
Docker Hubからイメージを引っ張ってきます。
1 |
sudo docker pull dustynv/jetson-inference:r32.4.4 |
作業用のフォルダーを作っておきます。
1 2 |
mkdir work-ssd cd work-ssd |
jetson-inferense をクローン
1 |
git clone --recursive https://github.com/dusty-nv/jetson-inference |
コンテナ作成用のシェルを編集。
1 2 |
cd jetson-inference sudo nano docker/run.sh |
コンテナはmy_ssdという名前で永続化しておきます。
1 2 3 4 5 |
sudo docker run --runtime nvidia -it --rm --network host -e DISPLAY=$DISPLAY \ -v /tmp/.X11-unix/:/tmp/.X11-unix \ -v /tmp/argus_socket:/tmp/argus_socket \ $V4L2_DEVICES $DATA_VOLUME $USER_VOLUME \ $CONTAINER_IMAGE $USER_COMMAND |
↓
1 2 3 4 5 |
sudo docker create --name my_ssd --runtime nvidia -it --network host -e DISPLAY=$DISPLAY \ -v /tmp/.X11-unix/:/tmp/.X11-unix \ -v /tmp/argus_socket:/tmp/argus_socket \ $V4L2_DEVICES $DATA_VOLUME $USER_VOLUME \ $CONTAINER_IMAGE $USER_COMMAND |
コンテナを作成して起動
途中でモデルのダウンロードを聞いてきますが、デフォルトのままで了解しておきます。
コンテナ作成後、起動
1 2 |
docker/run.sh sudo docker start -i my_ssd |
アップデートと必要なアプリのインストール
1 2 3 |
apt update apt install wget cd /jetson-inference/python/training/detection/ssd |
事前学習済みのネットワークモデルをダウンロードしておきます。
wget https://nvidia.box.com/shared/static/djf5w54rjvpqocsiztzaandq1m3avr7c.pth -O models/mobilenet-v1-ssd-mp-0_675.pth
exit か Ctrl + D で一旦コンテナを終了。
作業用に新しくフォルダーを作ってそこにssdフォルダをコピーしておきます。
このssdフォルダーがColabの作業環境になります。
1 |
mkdir /home/jetson/Colab-SSD |
/jetson-inferenceはコンテナからマウントされているので、ホストとコンテナでデータを共有できます。
sudo cp /home/jetson/work-ssd/jetson-inference/python/training/detection/ssd /home/jetson/Colab-SSD
Google Driveでトレーニングの事前準備
作業環境をColabでも使えるようにGoogleドライブにアップしておきます。
Google Drive はColabからマウントでき、15GBまでなら無償で使えます。
ブラウザーでドライブにアクセスして、先のColab-SSDフォルダーをアップロード
Google Colabでトレーニング準備
ブラウザーでGoogle Colabを開きます。
最初にNotebookを作成する際にGPUも使えるようにします。
ファイルー>ノートブックを新規作成
ランタイムをクリックー>ランタイムのタイプを変更
GPUを選んで保存します。
ファイルのアイコンをクリック
事前にGoogleドライブにアップしておいた環境が使えるようにドライブをマウントします。
マウントするとドライブが表示されるので、カレントディレクトリを変更します。
1 |
%cd "/content/drive/My Drive/Colab-SSD/ssd" |
ColabのNotebookではセルの左にある矢印付きの丸いボタンをクリックすれば実行されます。
環境をチェックしてみます。
visionフォルダーが見えます。ここにトレーニングに必要なモジュールが置かれています。
トレーニングに使うライブラリがそろっているかチェック。
セルに以下をコピー・ペーストして実行、エラーが出なければOKです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
import os import sys import logging import argparse import itertools import torch from torch.utils.data import DataLoader, ConcatDataset from torch.optim.lr_scheduler import CosineAnnealingLR, MultiStepLR from vision.utils.misc import str2bool, Timer, freeze_net_layers, store_labels from vision.ssd.ssd import MatchPrior from vision.ssd.vgg_ssd import create_vgg_ssd from vision.ssd.mobilenetv1_ssd import create_mobilenetv1_ssd from vision.ssd.mobilenetv1_ssd_lite import create_mobilenetv1_ssd_lite from vision.ssd.mobilenet_v2_ssd_lite import create_mobilenetv2_ssd_lite from vision.ssd.squeezenet_ssd_lite import create_squeezenet_ssd_lite from vision.datasets.voc_dataset import VOCDataset from vision.datasets.open_images import OpenImagesDataset from vision.nn.multibox_loss import MultiboxLoss from vision.ssd.config import vgg_ssd_config from vision.ssd.config import mobilenetv1_ssd_config from vision.ssd.config import squeezenet_ssd_config from vision.ssd.data_preprocessing import TrainAugmentation, TestTransform |
その他はこんな感じ。
Pythonのバージョンは3.6.9
1 |
sys.version |
torchでGPUが使えることが確認できます。
1 |
torch.cuda.is_available() |
NVIDIAのCUDAのバージョンは10.1です。
1 |
!nvcc -V |
ついでに、どんなGPUが使えるのか見てみます。
1 |
!nvidia-smi |
おお!Tesla T4 です。でもいつもこれとは限らないようです。k80が割り当てられたりp100だったり。
学習用の画像データをダウンロードしてトレーニング実行
AWSのs3 からOpen images の画像データをダウンロードできるようにします。
1 |
!pip3 install -v -r requirements.txt |
チュートリアルに倣って、 ダウンロード実行。
!python3 open_images_downloader.py --max-images=2500 --class-names "Printer,Television,Whiteboard,Chair,Desk" --data=data/office
トレーニング開始
!python3 train_ssd.py --data=data/office --model-dir=models/office --batch-size=4 --epochs=30
トレーニングにはだいたい1時間ちょっとかかります。
Tesla T4 なので、むちゃくちゃ速いかというとそんなでもなく、Jetson Nano(4GB)の4~5倍という体感です。
終了したらモデルをTensorRTで推論に使えるように、ONNX形式に変換しておきます。
1 |
!python3 onnx_export.py --model-dir=models/office |
こんなファイルです。30MBくらい。
Jetson Nano で推論準備
作成されたファイルを推論実行用にJetson nano へフィードバックしておきます。
ファイルはマウントしておいたGoogleドライブに作成されているので、ドライブを開いてダウンロードします。
対象になるのは、Colab-SSD/ssd/models/office/labels.txt , ssd-mobilenet.onnxの2つです。
右クリックで実行、ブラウザーのダウンロードフォルダーに保存されます。
ホスト側で、フィードバック先のフォルダーを作っておきます。
1 |
mkdir /home/jetson/work-ssd/jetson-inference/python/training/detection/ssd/models/office |
ダウンロードしたファイルをコピーします。
sudo cp /home/jetson/Downloads/* /home/jetson/work-ssd/jetson-inference/python/training/detection/ssd/models/office
Jetson Nano で推論
画像を準備して検証してみます。
適当な画像を探してきて、/home/jetson/Picturesフォルダーなどにoffice_1.jpgなどの名前で保存しておきます。
1 |
sudo cp /home/jetson/Pictures/office_1.jpg /home/jetson/work-ssd/jetson-inference/data/images |
コンテナを起動。
1 |
sudo docker start -i my_ssd |
推論実行
1 2 3 4 5 6 7 |
cd /jetson-inference/python/training/detection/ssd IMAGES=/jetson-inference/data/images detectnet --model=models/office/ssd-mobilenet.onnx --labels=models/office/labels.txt \ --input-blob=input_0 --output-cvg=scores --output-bbox=boxes \ "$IMAGES/office_1.jpg" $IMAGES/test/office_1.jpg |
detectnetはバイナリ版とpython版の2種類あります。上記はバイナリで実行されていますが、detectnet.pyでも実行可です。
また、バイナリ版とpython版ではオブジェクト検出の結果の表示が若干異なります。
TesnsorRTはコンテナを作成する際に使ったイメージ(jetson-inference:r32.4.4)に共有オブジェクトとして含まれています。(/usr/lib/python3.6/dist-packages/tensorrt/tensorrt.so)
detectnetは初回実行時、モデルのロードとコンパイルで少々お時間かかります。
でも2回目以降の実行は高速化されています。
以下のフォルダー内の結果を確認
/home/jetson/work-ssd/jetson-inference/data/images/test
椅子と机が検出されています。
Appendix
NVIDIAのTransfer Learing についてはここも参照
NVIDIA Transfer Learning Toolkit
NVIDIA Transfer Learning Toolkit を使用したカスタムの学習済みモデル (Pre-Trained Model) による学習
注:TLT(Transfer Learning Toolkit)のコンテナーはx_86アーキテクチャーのプラットフォームでのみ実行できます。TLTでトレーニングされたモデルは、Jetsonを含むすべてのNVIDIAプラットフォームにデプロイできます。
Appendix2
コンテナを別のPCに移行させる場合
コンテナはホストのディレクトリをマウントする設定になっているので、ホスト側のディレクトリをtarボールアーカイブしておきます。
1 |
tar cfvz my-ssd.tar.gz my-ssd |
コンテナをイメージにします
1 |
sudo docker commit my_ssd my_ssd:latest |
Dodcker Hub にアカウントをもっている場合はこのままpush してもいいかもしれません。
イメージやコンテナはLinuxなどのファイルシステムからは見えません(DockerはOverlayFSというのを使っているそうです)。
tarボールアーカイブすることでファイルシステムで扱えるようになります。
1 |
sudo docker save my_ssd:latest > my_ssd.tar.gz |
この2つのファイルを適当な手段で移行しておきます。
移行したら展開します。
ディレクトリをホームで展開
1 |
tar xvf my-ssd.tar.gz -C ~/ |
イメージを展開
1 |
sudo docker load < my_ssd.tar.gz |
後はrunなりcreateなりしてコンテナを起動
run.shを使う場合は、使用する$CONTAINER_IMAGE名をmy_ssd:latestに変更しておきます。
Resnet-18の場合
手順のみ
Jetson Nanoで学習済みモデルを使って、いろいろやってみる(2-1)転移学習(ResNet-18)
の内容に準じます。
コンテナmy_contで画像のダウンロードまでをやっておきます。
このフォルダーをホスト側にディレクトリを作っておいて、そこにコピーします。
1 |
mkdir resnet18-classific |
コピー。
sudo docker cp my_cont:/jetson-inference/python/training/classification/. /home/jetson/resnet18-classific
train.pyを修正しておきます。
なぜかColabではviewでサイズ数を変更するTensorの各要素が、メモリ上で要素順に並んでくれないようです。
500行目で以下のようなエラー
RuntimeError: view size is not compatible with input tensor’s size and stride (at least one dimension spans across two contiguous subspaces). Use .reshape(…) instead.
viewの前にcontiguous()を付ければメモリ上で要素順に並び、上記のエラーを回避できるようです。
correct_k = correct[:k].view(-1).float().sum(0, keepdim=True)
↓
correct_k = correct[:k].contiguous().view(-1).float().sum(0, keepdim=True)
あるいはメッセージ通りにreshapeを使う。
correct_k = correct[:k].reshape(-1).float().sum(0, keepdim=True)
このフォルダーを上で実行したようにGoogle Drive にフォルダーごとアップロード
Google Colab を開いてGPUを使うNotebookを作成。
Driveをマウントして、カレントディレクトリを移動
1 |
%cd /content/drive/MyDrive/resnet18-classific/ |
ライブラリーをチェック
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
import argparse import os import random import shutil import time import warnings import torch import torch.nn as nn import torch.nn.parallel import torch.backends.cudnn as cudnn import torch.distributed as dist import torch.optim import torch.multiprocessing as mp import torch.utils.data import torch.utils.data.distributed import torchvision.transforms as transforms import torchvision.datasets as datasets import torchvision.models as models from reshape import reshape_model |
で、再トレーニングを実行します。
1 |
!python3 train.py --model-dir=models/cat_dog data/cat_dog |
Jetson Nano では4時間くらいかかっていましたが、Colab(T4)では1時間くらいで終了しました。
以上
Leave a Reply