Jetson Nano を使って転移学習をやってみます。
転移学習とはなんぞや(分かってる人には分かりやすく、分かってない人には分かりにくい説明^^)。
このページで作成しておいた、Jetson Nano(4GB)+Jetpack(4.4.1) + NVIDIA Container + Pytorch + TensorRT の環境です。
転移学習でモデルを再トレーニングする場合、メモリを大量に消費するのでデスクトップ環境は使いません。
CUI環境に変更します。また、CPU・GPUがフルに稼働するので冷却ファンは必須です。
Swapは4GBほど確保しておきます。
永続化します。
Disabling the Desktop GUI
Jetson NanoのRAMメモリは4GBしかありません。
メモリを節約するため、Desktopを停止して、CUIでやってみます。
以下を実行することで、ウィンドウマネージャーとデスクトップが使用する余分なメモリが解放されます。
Nano 2GBではなぜかinitが効きませんでしたので、CUI環境は以下のように設定します。
sudo systemctl set-default multi-user.target
sudo reboot
GUIに戻す
sudo systemctl set-default graphical.target
sudo reboot
CUI画面になります(2バイトキャラは文字化けしています)。
jetson-statsで実行状況をモニターしたり、スクリーンショットを撮ったりする場合は、仮想コンソールや、SSHを使います。
複数のコンソールを開く場合は、仮想コンソールなら、Alt + F2~F6で開きます。Alt + F1 で初期コンソールに復帰します(chvt 番号でも可)。
あるいは、Tera TermなどでSSHを複数接続して開きます。
CUIの環境ならメモリーはこの程度(約700~800MB、2GB版のLXDEなら300MBくらい)節約できます。
Desktop使用時
Desktopを使わない場合
Dockerを起動
Dockerの作成などはこのページをご参照ください。コンテナ名はmy_cont にしています。
Is the docker daemon running? というメッセージが出たら以下を実行。
sudo dockerd
【転移学習(Transfer Learning)】
Re-training on the Cat/Dog Dataset
Cat/Dogのデータセットを再トレーニングします。
ResNet-18を使ったイヌ科とネコ科の2クラス分類です。
以下は、独自のデータを収集して独自のカスタマイズされたモデルを作成することに加えて、転移学習を使用していくつかのサンプルデータセットでモデルを再トレーニングするためのステップバイステップの手順です。
Downloading the Data
トレーニング用のデータセットをダウンロードして解凍
Cat と Dog それぞれで、
学習用データ:2500枚 x 2
/jetson-inference/python/training/classification/data/cat_dog/train/cat
/jetson-inference/python/training/classification/data/cat_dog/train/dog
検証用データ:500枚 x 2
/jetson-inference/python/training/classification/data/cat_dog/val/cat
/jetson-inference/python/training/classification/data/cat_dog/val/dog
テスト用データ:100枚 x 2
/jetson-inference/python/training/classification/data/cat_dog/test/cat
/jetson-inference/python/training/classification/data/cat_dog/test/dog
Re-training ResNet-18 Model
RessNet-18 モデルを使って再トレーニング
モデルのresnet18-5c106cde.pth はtrain.py の実行中にダウンロードされます。
epoch数はデフォルトで35、再トレーニングは大体4時間くらいが想定されます。
Nano 4GBで大体4時間、2GB版ならSwapを使うことになりますが、それでも4時間半くらいで実行完了しました。Xavier NX なら2時間ほどです。
jetson-statsを見てみます。
GPUはフル稼働状態です。メモリはCUIのみの環境なので余裕がありますが、デスクトップ環境で使っていれば、ほぼ満杯状態だと思われます。
冷却ファンは必須です。無いと回路周りの温度が60度くらいになって、Warningが出続けます。
トレーニングは中断->再開ができます。
Ctr + C で中断。
再開する場合は resumeオプションを使います。引数の並びはこうです。
epoch-start(マニュアルでは start-epoch)はオプションであり、厳密には必須ではありません….だそうです。
Cat/Dog の場合はこうです。
epoch の途中で中断した場合、再開はepoch の初めからになります。
再トレーニング終了
train.py のマニュアル
Converting the Model to ONNX
再トレーニングされたResNet-18モデルをTensorRTで実行するには、PyTorchモデルをONNX形式に変換して、TensorRTがロードできるようにする必要があります。
ちなみに、上記再トレーニングでアップデートされるファイルは以下の4つです。
/jetson-inference/python/training/classification/models/cat_dog
● checkpoint.pth.tar
● labels.txt
● model_best.pth.tar
● tensorboardフォルダー内のファイル
提供されている onnx_export.py スクリプトで Cat/Dog モデルを変換します。
ディレクトリは上記と同じ
/jetson-inference/python/training/classification
これで、resnet18.onnxというモデルがアップデートされます。
/jetson-inference/python/training/classification/models/cat_dog/resnet18.onnx
Processing Images with TensorRT
TensorRTで画像を処理します。
例えばcat画像で推論実行。
画像はdata/cat_dog/test/cat/02.jpg、実行結果はcat_02.jpgという画像で出力します。
X11への接続が要求されますが、無くてもOKです(気になる方はコンテナ起動前にsudo xhost si:localuser:rootを実行しておきます)。
imagenet.py --model=models/cat_dog/resnet18.onnx --input_blob=input_0 --output_blob=output_0 --labels=data/cat_dog/labels.txt data/cat_dog/test/cat/02.jpg cat_02.jpg
上記のドッカースクリプトでコンテナを作成した場合、以下の場所が共有されています。
コンテナ ホスト
/jetson-inference/build/aarch64/bin/images/test <—-> ~/work/jetson-inference/data/images/test
以下のように実行すれば結果画像は共有ディレクトリに出力されるのでホスト側で直接見ることができます。
imagenet.py --model=models/cat_dog/resnet18.onnx --input_blob=input_0 --output_blob=output_0 --labels=data/cat_dog/labels.txt data/cat_dog/test/cat/02.jpg /jetson-inference/build/aarch64/bin/images/test/cat_02.jpg
初回はresnet18.onnxが読み込まれてコンパイルされるので少々時間がかかります。コンパイル後のモデルは/resnet18.onnx.1.1.8201.GPU.FP16.engineなどの名前で以下に保存されています(.engineの拡張子があればTensorRTで読み込めます)。
/jetson-inference/python/training/classification/models/cat_dog/resnet18.onnx.1.1.8201.GPU.FP16.engine
結果画像を共有ディレクトリに出力しない場合、画像は以下に出力されています。
/jetson-inference/python/training/classification/cat_02.jpg
この場合コンテナ内の画像は直接見れないのでホスト側にコピーします。
コンテナのIDを調べます。
画像をフルパスで指定します、こんな感じ。
sudo docker cp <コンテナのID>:/jetson-inference/python/training/classification/cat_02.jpg ~/cat_02.jpg
ホストのホームディレクトリに画像がコピーされます。
画像の左上に「91.70%の確からしさで猫」が表示されています。
Dogの画像はどうでしょう。
推論(コンテナで実行)
imagenet.py --model=models/cat_dog/resnet18.onnx --input_blob=input_0 --output_blob=output_0 --labels=data/cat_dog/labels.txt data/cat_dog/test/dog/02.jpg dog_02.jpg
結果をコピー(ホストで実行)
sudo docker cp 8be5ccad5b84:/jetson-inference/python/training/classification/dog_02.jpg ~/dog_02.jpg
「87.43%の確からしさで犬」
Processing all the Test Images
テスト画像(100枚)をすべて使って検証してみます。
出力用のフォルダーを作っておきます。
実行。
imagenet --model=models/cat_dog/resnet18.onnx --input_blob=input_0 --output_blob=output_0 --labels=data/cat_dog/labels.txt data/cat_dog/test/cat data/cat_dog/test_output_cat
imagenet --model=models/cat_dog/resnet18.onnx --input_blob=input_0 --output_blob=output_0 --labels=data/cat_dog/labels.txt data/cat_dog/test/dog data/cat_dog/test_output_dog
結果を確認しました、こんな感じ。
ネコ科の正解:61/100
イヌ科の正解:79/100
イヌ科はチュートリアルに近い正解率ですが、ネコ科が低いです。
テスト画像にイヌ科の動物(タヌキやキツネ)が居ないか少なかったから?
epoch を60にして再トレーニングしても結果は同じでしたね。
現在、ネコ科(2500)、イヌ科(2500)ですが画像を増やしてやってみる必要がある…..かも。
下記のGenerating More Data (Optional)にあるスクリプトを使って訓練画像5000枚/epoch 35で再トレーニングしてみましたが正解率はだいたいこんなものでした。テスト画像を再生成して5回ほど検証してみた結果では正解率はネコ科で60%程度に収まりました。
Running the Live Camera Program
カメラプログラムを実行して、それがどのように機能するかを確認できます。
ホスト側でX セッションへのアクセスを許可。
ラズパイ用のカメラ(V2)
imagenet.py --model=models/cat_dog/resnet18.onnx --input_blob=input_0 --output_blob=output_0 --labels=data/cat_dog/labels.txt csi://0
USBカメラ(単体で接続している場合、カメラ番号は0)
imagenet.py --model=models/cat_dog/resnet18.onnx --input_blob=input_0 --output_blob=output_0 --labels=data/cat_dog/labels.txt /dev/video0
Generating More Data (Optional)
Cat / Dogデータセットの画像は、cat-dog-dataset.shスクリプトを使用して、ILSCRV12のより大きな22.5GBサブセットからランダムに取得されました。 この最初のCat / Dogデータセットは、トレーニング時間を短縮するために意図的に小さく保たれていますが、このスクリプトを使用すると、追加の画像を使用してデータセットを再生成し、より堅牢なモデルを作成できます。
Cat / Dogデータセットを拡張する場合は、最初にここからソースデータをダウンロードします。
データセットが大きいほどトレーニングに時間がかかります。
Next1
ここでは事前学習モデル(Pre trained Model)はResNet-18が使われています。
違うモデル(SSD-Mobilenet)を使ってみます。
Next2
自前の学習データを収集してやってみます。
Collecting your own Classification Datasets
便利なツールをご用意しました…….とあるので使ってみます。
カメラ画面からデータを作成
Next3
Deep Learning Nodes for ROS/ROS2
ROS/ROS2(Robot Operating System)でディープラーニング処理(process/thread)
SLAMに続く
Jetson Nano(2GB)冷却ファン
Appendix
NVIDIAのTransfer Learing についてはここも参照
NVIDIA Transfer Learning Toolkit
注:TLT(Transfer Learning Toolkit)のコンテナーはx_86アーキテクチャーのプラットフォームでのみ実行できます。TLTでトレーニングされたモデルは、Jetsonを含むすべてのNVIDIAプラットフォームにデプロイできます。
Leave a Reply