Jetson nano 2GB モデルを買いました。これで推論をさせてみるところまでやってみました。いくつか、うまくいかない場合があったので、今後のためにも作業手順をまとめておこうと思いました。
OS を起動するまでの準備
OS イメージを microSD に書き込む
microSD カードとの相性があるとの話で心配していましたが、今回はこちらのカードを使ってうまく起動できているように思います。
OS イメージは、こちらのものを使用しました。
https://developer.nvidia.com/embedded/jetpack
今回使用したバージョンは JetPack 4.6 で、ファイル名は “jetson-nano-2gb-jp46-sd-card-image.zip” でした。ここは所持しているボードの種類に合わせてダウンロードします。
ダウンロードしたファイルを展開して得られた img ファイルを balenaEtcher を用いて書き込みます。書き込みが終わると、各パーティションを Windows が検出して、ドライブ番号を割り当ててくる&フォーマットしますか?と聞かれますが、全ての問い合わせはキャンセルで閉じておきます。
この microSD カードを Jetson Nano に装着して、電源を入れます。ここでもし以下のような画面が出てしまう場合には、正しくOSイメージを認識できていないようです。
他のバージョンの img を書いてみたり、何度か繰り返していると正常に動く状態になったりしました。自分が出遭ったときには、jetpack の img と jetbot の img を交互に書き込んだりしていましたね。
電源について
電源については、 Raspberry Pi 4 用にと準備していた AC アダプタを使用しています。このアダプタは 5V 3.1A 供給できるので、この Jetson Nano ボードでもうまく合致しました。一方で、 Ancker の Ancker Nano II アダプタから直接 USB-C でつないでも電源が入りませんでした。 電源を供給できるかの量を満たしていても不十分っぽいです。
初期セットアップ
問題なく起動できると、最初にライセンス同意を求められます。
他にもキーボードの設定や、Wi-Fi アダプタが利用可能であれば Wi-Fi の設定などがあります。
また、ディスクのサイズを変更して最大化することもここで聞かれるので設定しておきます。
その他、起動後の設定
自分の環境では、5W のモードで動作させています。ファンを取り付けていないせいか、パフォーマンス最大化のモードではカメラ取り扱っていた時に不安定になっていました。
このパフォーマンスモードを設定するコマンドが、以下の通りです。
$ sudo nvpmodel -m 1
ここで、 -m 0 とすればパフォーマンス最大化モードに設定できます。-m 1 で、5W 消費電力モードです。5W モードだと、CPU 4コアのうち2コアを使用するようです。
推論する前の準備
ここからはサンプルとして提供されていたものを実行するための前準備を行います。
メモリの設定
/zram でスワップが用意されているのですが、これを解除して、 10GB のスワップファイルを別途用意しました。そのときの手順は以下の通りです。
# スワップを一旦無効にする
$ sudo swapoff -a
$ sudo systemctl disable nvzramconfig
# スワップファイルを拡張する
$ sudo dd if=/dev/zero of=/swapfile bs=1M count=10240
$ sudo mkswap /swapfile
# スワップを有効にする
$ sudo swapon -p 1 /swapfile
# 念のため再起動
$ sudo reboot
自分の場合には最初の時点でスワップファイルが作成されていたので、そのファイルを拡張するようにしました。
これで再起動後に、以下のコマンドを実行してみて、スワップファイルが有効になるか確認しておきます。
$ free -h
total used free shared buff/cache available
Mem: 1.9G 204M 1.1G 26M 689M 1.6G
Swap: 10.0G 0B 10.0G
デスクトップ環境が起動しないように設定
メモリを節約するため、デスクトップ環境が起動しないようにしておきます。設定したら、次のステップのために再起動しておきます。
$ sudo systemctl set-default multi-user.target
$ sudo reboot
推論させてみる
初めての機械学習・推論ということで、 GitHub に用意されているサンプルを使わせてもらいます。
ここにあるものを使わせてもらうのですが、色々と整った Docker コンテナを使ってしまおうと思います。このとき、ベースとしている OS 環境に合わせたものを使うようにしましょう。バージョンがズレていると、この後の処理がうまく出来ないようです。
JetPack 4.6 を使用しているので、コンテナは dustynv/jetson-inference:r32.6.1 を使用します。以下のスクリプトを用意して、コンテナを起動してみます。このスクリプトを ~/nvdli-data ディレクトリで作成しておきました。
(~/nvdli-data/docker_dli_run.sh)
#!/bin/bash
sudo docker run --runtime nvidia -it --rm --network host \
--volume ~/nvdli-data:/nvdli-nano/data \
--device /dev/video0 \
--volume /tmp/argus_socket:/tmp/argus_socket \
--memory=500M --memory-swap=8G \
nvcr.io/nvidia/dli/dli-nano-ai:v2.0.1-r32.6.1
自分の環境では、 CSI カメラを接続しているためこのようになっています。USB カメラの場合には一部設定が不要なようです。
この後、コンテナを起動します。
$ cd ~/nvdli-data
$ ./docker_dli_run.sh
コンテナを起動したら、Web ブラウザでアクセスします。 http://(hostIP):8888/ にアクセスすると以下のような画面になります。パスワードは dlinano で、アクセスします。
ログイン後は、classification/classification_interactive.ipyn ファイルを開きます。
今回は CSICamera のほうを使用するので、最初のコードを以下の図のように変更しています。
ここでカメラの生成に失敗する場合には、うまくカメラの認識が出来ていないか、各種バージョンのズレはないのかなどをチェックしておきましょう。
あとは、各コードブロックを順番に実行していき、最後のブロックを実行すると、ブラウザ上でカメラの様子も含めた UI が出現します。
学習と推論
ここでカメラに thumb-up, thumb-down の自分の手を写して、いくつかの角度、パターンなどを登録していきます。カテゴリを変更して、add ボタンを押していくだけでよいようです。
それぞれ20パターンくらいとったところで、 ephocs に 10 くらいの数値を入れ、train ボタンを押して学習させます。学習が終わった後、自分の手をカメラに写すと、右側に現在はどちらの状態か、推論した結果を表示するようです。
最初の train 実行時には、フリーズしたかと思うくらいに固まるのですが、その後学習の様子が動き出すのでしばらくは見守っていた方がよさそうです。
推論のツールについての説明はこちらの Web 記事の方が分かりやすくてよかったです。