コンテンツへスキップ

AlexeyAB/DarknetをNvidia Jetson Nanoにインストール

Raspberry Piとの一番の違いは、GPU対応で、Darknet・AlexeyABをシングルボードコンピューターにインストール出来ることが、大きな魅力となります。
しかも、インストールもWindows版よりも簡単だと思います。

参考記事:Windows10に AlexeyAB・Darknet・YOLO V3導入(Vestal Studio)

ライブラリーアップデート

  1. apt update
  2. apt upgrade -y

Cuda関係のパスを環境変数に登録

  1. export PATH=/usr/local/cuda-10.0/bin${PATH:+:${PATH}}
  2. export LD_LIBRARY_PATH=/usr/local/cuda-10.0/lib64${LD_LIBRARY_PATH:+:${LD_LIBRARY_PATH}}

DarknetのダウンロードとYoloモデルのダウンロード

  1. git clone https://github.com/AlexeyAB/darknet
  2. cd darknet
  3. wget https://pjreddie.com/media/files/yolov3.weights
  4. wget https://pjreddie.com/media/files/yolov3-tiny.weights

MakeFileを変更しGPU、OPENCV対応へ

Makefileを変更し、GPU、CudaとOpencv対応となるようにコンパイルオプションを変更します。.

  1. sudo vi Makefile

MakeFile変更内容
GPU=1
CUDNN=1
OPENCV=1

Darknetをコンパイル

  1. make

以上でDarknetが利用可能となります。

darknetフォルダで、以下サンプルコマンドを実行し、動作を確認してください。

  1. cd darknet
  2. ./darknet detector test cfg/coco.data yolov3.cfg yolov3.weights -ext_output dog.jpg

Make時にエラーが出て、以下変更を加えました。

変更1

NVCC=nvcc 部分を
NVCC=/usr/local/cuda/bin/nvcc
に変更

変更2 ライブラリ追加

sudo apt install libopencv-dev

参考にさせて頂いたサイト

created by Rinker
NVIDIA
¥19,000 (2021/08/19 16:46:56時点 Amazon調べ-詳細)

WEBカメラ/USBカメラ

リアルタイム画像検出で大切な入力デバイスとなるカメラ、各種選択肢があります。画角、フォーカス、露出などを考えていくと悩むことがたくさんあります。
カメラの安定動作や設置時の物理的な安定性など、安定した画像検出には、場面場面に合わせたカメラが必要になります。

今回探したカメラの要件

  • ある程度物理的な設置位置がずれた際も、画像検出を続けたい
  • 暗闇以外、昼夜画像検出可能な範囲での撮影が可能
  • USB接続で安定動作

カメラの要求仕様

  • 画角が広い(ある程度の物理設置位置の変更に対応可能、そもそも多少の広角は必須)
  • ある程度自動での画質設定(朝日などが当たると、画質は一気に変わります)
  • オートフォーカス (こちらもあると安心)
  • 過度な高画質は不要(画像検出時に必要な画素数はHDで十分)
  • 音声は基本的に使わない(画像検出のみ)

一番の要件は、広角でした。広角対応のカメラは以下が候補となりました。

オートフォーカスで手頃なカメラだと、サンワサプライ オートフォーカスWEBカメラ CMS-V45Sなどが出来ていました。画角65度と通常のWEBカメラよりは広角。

通常のWEBカメラは、58度前後で60度以下となります。
最初にBUFFALOの広角カメラを導入したこともあり、60度以下の画角では今回は、そもそも画像検出対象の画角となりませんでした。
また、広角になるとオートフォーカスも難しいと思うので、広角+オートフォーカスを満たそうとすると、一気に対象製品を探すのが難しいです。

今回選んだカメラは、ロジクール ウェブカメラ C615 ブラック フルHD 1080Pとなります。

画角が78°でオートフォーカス。
近距離(最長7cm)対応、高速オートフォーカス、HD光補正。
一方、マイクはステレオ未対応のモノラル、画質(720p/30fps)となり、最新機種よりはスペックダウンします。(ここが、納得の価格で入手出来るポイントだと思います)

まだ、導入後1週間ですので、Jetson Nanoとの組み合わせで利用し、何かあれば、またレビューさせて頂きます。

created by Rinker
NVIDIA
¥19,000 (2021/08/19 16:46:56時点 Amazon調べ-詳細)

一つ前の関連記事:NVIDIA Jetson Nano vs Raspberry Pi with NCS2 (Movidius Neural Compute Stick 2)

全242回のめざましじゃんけん結果取得を通じて

一番のテーマは、信頼性の向上です。
「全部の回次を正しく結果取得」
1回1回の信頼性向上・・・まだ、道半ば。誤判定をなくす、(運用コストが低く)信頼性の高いH/Wの導入。そして、H/Wの冗長化
イレギュラー開催などへの対応
・・・見えていない部分もありますが、ダブルポイントなどへの対応、年末年始など、個別開催時間への対応など
信頼性を向上するうえで、システムの構成予想削減(よりシンプルに)、より高信頼なハードウェアで。
最近ホットな出来事は、USBカメラの画像が悪い時(太陽の高さなど、テレビの設置環境に依存)の画像検出率低下、さらには誤判定。
これらを回避する途中に、エッジコンピューティングでの画像検出エンジンの高速化が実現しました。
(高速化や信頼性を主テーマとすると、他の方式もありますが、あくまで気になる分野や楽しそうな技術の採用を優先させております)

  • Raspberry Pi単体での画像検出を断念 (Windowsメインマシンでのモデル実行)
  • Raspberry Pi with NCS2での画像検出へ移行
    世界最速めざましじゃんけん結果公開Neural Compute Stick 2 ( NCS )
    この時点でもすでに、エッジコンピューティングの凄さに感動しました。
  • NVIDIA Jetson Nanoを試行開始(Keras + YOLO)
  • NVIDIA Jetson Nanoでlibdarknet.so利用(NVIDIA CUDAの真髄)
    YOLO / Darknetを動かす上で、アーキテクチャ的には一番良い選択なのだと思います。それにしても、Keras(TensorFlow)と比べて、倍速になるとはびっくりしました。
今後、記事化予定ですが、DarknetのGitHubより配布されているPythonスクリプトもPython3対応版となっております。
Makefileを変更し「LIBSO=1」、Pythonスクリプトより、ctypes import *を用いて、lib = CDLL("libdarknet.so", RTLD_GLOBAL)ライブラリを取り込み、Python 3のwrapperとして利用出来ました。
Keras導入時点のWEB記事では、導入が難しそうな記事も散見され、深追いしておりませんでした。

NVIDIA CUDA Toolkit 10.0 に対応しcuDNN 7.3など、機械学習時にデファクトスタンダートとなっているライブラリやフレームワークが多く、システムアーキテクチャの選択肢が非常に多いです。
今回も他フレームワークも視野に入れ、比較検討することが出来ました。TensorFlow や PyTorch、Caffe、Keras、MXNet などの機械学習 (ML) フレームワークに対応しています。ネイティブにインストールすることができます。

NVIDIA Jetsonの情報収集

NVIDIAの社員や関係者が強力にサポート、情報発信。
さすが、大手。ハードの供給体制もRaspberry Pi と比べて力強さを感じます。開発コミュニティーへの社員の書き込みが、本当にすごい。
オープンコミュニティの新しい形にも見えました。ハードでビジネスは成立し、技術者が率先して、コミュニティに参加。これは、弱点と感じた部分を、むしろ強み(正しい情報、責任感ある素早い対応)にしております。
今回は、特にこれらを体感出来ました。

関連記事:

NVIDIA Jetson Nanoで機械学習(推論)

Movidius Neural Compute Stick2とRaspberry Pi 3B +も利用しておりますが、GPU/推論向けデバイスが一体化されており、少しサイズは大きいです。
USB3.0などI/Fに差分もあるので、Raspberry Pi 4Bと比較したほうが良いかもしれません。ただし、Raspberry Pi 4B と NCS2を同時導入すると考えると、Jetson Nanoのほうがコストパフォーマンスが良いと思いますし、便利なフレームワーク利用により、開発時の手間(コスト)も考えると、機械学習にはNVIDIA Jetson Nanoがベストな選択と思います。

Jetson Nano、Raspberry Pi 3B + with NCS2 速度比較

めざましじゃんけん時に取得したWEBカメラ画像を216枚で画像認識エンジンを動作させた際の性能比較です。
以前同じテストを用いて、NCS2(Movidius Neural Compute Stick 2)導入により十分高速化された結果となりました。今回は、その結果と比べても十分に魅力的なJetson Nanoの結果が出ました。

参考記事:ディープラーニング向けUSBアクセラレーターNeural Compute Stick 2ー

Windows(GPU未使用)
Core i7 6700/(Skylake) クロック周波数:3.4GHz
15秒 opencv.dnn
Raspberry Pi 3
Model B+
ARM Cortex-A53 1.4GHz
785秒 opencv.dnn
Raspberry Pi 3
Model B+
ARM Cortex-A53 1.4GHz
+  Movidius Vision Processing Unit(Myriad 2)
105秒 opencv.dnn
NVIDIA Jetson Nano
Quad-core ARM A57 @ 1.43 GHz
109秒 opencv.dnn
NVIDIA Jetson Nano
Quad-core ARM A57 @ 1.43 GHz
+ 128-core Maxwell
46秒 Keras-YOLO
NVIDIA Jetson Nano
Quad-core ARM A57 @ 1.43 GHz
+ 128-core Maxwell
20秒 libdarknet.so (ctypes)
2019-08-14 20:34:48,460:202:INFO:ループ開始:D:\pic4ml\Janken_Target_Test\20190806_055717_102196_1.jpg 処理回数:1
2019-08-14 20:35:03,389:256:INFO:ジャンケン結果判定 Len(total_results): 3 List Values: 0,2,5
019-08-14 20:35:03,390:289:INFO:ジャンケン結果:Chokiを出してLose、相手はGoo
2019-08-15 12:11:10,292:202:INFO:ループ開始:/home/miki/cronScript/Janken_Target_Test/20190806_055717_102196_1.jpg 処理回数:1
2019-08-15 12:24:15,786:256:INFO:ジャンケン結果判定 Len(total_results): 3 List Values: 0,2,5
2019-08-15 12:24:15,787:289:INFO:ジャンケン結果:Chokiを出してLose、相手はGoo
2019-08-24 12:16:09,419:202:INFO:ループ開始:/home/miki/cronScript/Janken_Target_Test/20190806_055717_102196_1.jpg 処理回数:1
2019-08-24 12:17:54,200:256:INFO:ジャンケン結果判定 Len(total_results): 3 List Values: 0,2,5
2019-08-24 12:17:54,201:289:INFO:ジャンケン結果:Chokiを出してLose、相手はGoo
2019-10-05 11:01:36,900:4:INFO:ループ開始:/home/miki/hdd/cronScript/Janken_Target_Test/20190806_055717_102196_1.jpg 処理回数:1
2019-10-05 11:02:22,651:7:INFO:ジャンケン結果判定 Len(total_results): 3 List Values: 0,2,5
2019-10-05 11:02:22,701:30:INFO:ジャンケン結果:Chokiを出してLose、相手はGoo
2019-10-12 15:36:23,341:164:INFO:ループ開始:/home/miki/hdd/cronScript/Janken_Target_Test/20190806_055717_102196_1.jpg 処理回数:1
2019-10-12 15:36:43,531:210:INFO:ジャンケン結果判定 Len(total_results): 3 List Values: 0,2,5
2019-10-12 15:36:43,532:247:INFO:ジャンケン結果:Chokiを出してLose、相手はGoo
created by Rinker
NVIDIA
¥19,000 (2021/08/19 16:46:56時点 Amazon調べ-詳細)

関連記事:NVIDIA JETSON NANO

Intel Neural Compute Stick 2

Jetson Nanoからのメール送信

NVIDIA Jetson Nanoの利用を開始すると、Jetson Nanoの各種モジュールへ通知先のメールアドレスを設定することがあります。
パッケージのアップデートやログのローテーション処理時のエラーなどもメール通知することが可能です。

今回は、SSMTPをJetson Nanoに導入し、PHP経由で以前に構築したSynology SMTPを経由し、e-mailを送信できる環境の構築を行います。
SynologyでSMTP(メールサーバ)構築

ssmtpインストール

root@jetson:~# apt install ssmtp

ssmtp.confを編集。

root@jetson:~# vi /etc/ssmtp/ssmtp.conf
#
# Config file for sSMTP sendmail
#
# The person who gets all mail for userids < 1000
# Make this empty to disable rewriting.
root=postmaster

# The place where the mail goes. The actual machine name is required no
# MX records are consulted. Commonly mailhosts are named mail.domain.com
mailhub=@SynologyIP@

# Where will the mail seem to come from?
rewriteDomain=miki-ie.com

# The full hostname
hostname=jetson.miki-ie.com

# Are users allowed to set their own From: address?
# YES - Allow the user to specify their own From: address
# NO - Use the system generated From: address
FromLineOverride=YES

PHP構成定義ファイル(php.ini)変更

php.iniのファイルパス確認

PHPの利用するコンフィグファイルを確かめます。
コマンドラインで実行する場合は、WEBサーバで利用するコンフィグファイルは、通常異なります。

root@jetson:~# php --ini
Configuration File (php.ini) Path: /etc/php/7.2/cli
Loaded Configuration File:         /etc/php/7.2/cli/php.ini
Scan for additional .ini files in: /etc/php/7.2/cli/conf.d
Additional .ini files parsed:      /etc/php/7.2/cli/conf.d/10-mysqlnd.ini,
/etc/php/7.2/cli/conf.d/10-opcache.ini,
/etc/php/7.2/cli/conf.d/10-pdo.ini,
/etc/php/7.2/cli/conf.d/20-calendar.ini,
/etc/php/7.2/cli/conf.d/20-ctype.ini,
/etc/php/7.2/cli/conf.d/20-curl.ini,
/etc/php/7.2/cli/conf.d/20-exif.ini,
/etc/php/7.3/cli/conf.d/20-curl.ini,
/etc/php/7.3/cli/conf.d/20-dom.ini,
/etc/php/7.3/cli/conf.d/20-exif.ini,
/etc/php/7.3/cli/conf.d/20-fileinfo.ini,
/etc/php/7.3/cli/conf.d/20-ftp.ini,
/etc/php/7.3/cli/conf.d/20-gd.ini,
/etc/php/7.3/cli/conf.d/20-gettext.ini,
/etc/php/7.3/cli/conf.d/20-iconv.ini,
/etc/php/7.3/cli/conf.d/20-imap.ini,
/etc/php/7.3/cli/conf.d/20-json.ini,
/etc/php/7.3/cli/conf.d/20-mbstring.ini,
/etc/php/7.3/cli/conf.d/20-mysqli.ini,
/etc/php/7.3/cli/conf.d/20-pdo_mysql.ini,
/etc/php/7.3/cli/conf.d/20-pdo_pgsql.ini,
/etc/php/7.3/cli/conf.d/20-pgsql.ini,
/etc/php/7.3/cli/conf.d/20-phar.ini,
/etc/php/7.3/cli/conf.d/20-posix.ini,
/etc/php/7.3/cli/conf.d/20-readline.ini,
/etc/php/7.3/cli/conf.d/20-shmop.ini,
/etc/php/7.3/cli/conf.d/20-simplexml.ini,
/etc/php/7.3/cli/conf.d/20-sockets.ini,
/etc/php/7.3/cli/conf.d/20-ssh2.ini,
/etc/php/7.3/cli/conf.d/20-sysvmsg.ini,
/etc/php/7.3/cli/conf.d/20-sysvsem.ini,
/etc/php/7.3/cli/conf.d/20-sysvshm.ini,
/etc/php/7.3/cli/conf.d/20-tokenizer.ini,
/etc/php/7.3/cli/conf.d/20-wddx.ini,
/etc/php/7.3/cli/conf.d/20-xmlreader.ini,
/etc/php/7.3/cli/conf.d/20-xmlwriter.ini,
/etc/php/7.3/cli/conf.d/20-xsl.ini

コマンドライン向けPHP構成ファイルphp.iniのsendmail_pathを変更

root@jetson:~# vi /etc/php/7.2/cli/php.ini

; For Unix only.  You may supply arguments as well (default: "sendmail -t -i").
; http://php.net/sendmail-path
sendmail_path = /usr/sbin/ssmtp -t

PHPのメール送信サンプルスクリプト

メールヘッダーにマルチバイト文字を利用する際は、mb_encode_mimeheaderを用いて、エンコーディングを行います。

php-mbstringをインストール

php-mbstringを導入していないと、エラーとなります。

PHP Fatal error: Uncaught Error: Call to undefined function mb_encode_mimeheader()

root@jetson:~# apt install php-mbstring 
<?php

function send_notice($title, $message){
$to = "kenichi.miki@gmail.com";
$headers = "From:". mb_encode_mimeheader("メール通知") ."<notice@192.168.0.108>".PHP_EOL;
if(mb_send_mail($to, $title, $message,$headers)){
echo "メールを送信しました";
} else {
echo "メールの送信に失敗しました";
}
}

send_notice("テストRaspi","メッセージテスト");
created by Rinker
NVIDIA
¥19,000 (2021/08/19 16:46:56時点 Amazon調べ-詳細)

NVIDIA Jetson Nano

NVIDIA CUDA Toolkit 10.0 に対応しcuDNN 7.3など、機械学習時にデファクトスタンダートとなっているライブラリやフレームワークが、利用可能になっています。
TensorFlow や PyTorch、Caffe、Keras、MXNet などの機械学習 (ML) フレームワークに対応しています。ネイティブにインストールすることができます。

Raspberry Pi with NCS2 VS Jetson

導入時に気になったのは、開発者コミュニティーです。
Raspberry Piは、歴史もあり、世界中の方々が同じような悩みを持ち、各種解決策がWEBに公開されています。一方で、NVIDIA Jetson Nanoは、どの程度このようなコアユーザーによる情報公開などがされているのか気になりました。

結論からするとNVIDIAの社員や関係者が協力にサポート、情報発信。
さすが、大手ですね、ハードの共有体制もRaspberry Pi と比べて感心しましたが、開発コミュニティーへの社員の書き込みが、本当にすごい。
オープンコミュニティの新しい形にも見えました。ハードでビジネスは成立し、技術者が率先して、コミュニティに参加。これは、弱点と感じた部分を、むしろ強み(正しい情報、責任感ある素早い対応)にしております。
あとは、ケースやファンなど、市場の大きさに合わせて、周辺のアクセサリーメーカーが追従してくれば、IoTにおけるローエンドエッジデバイスの筆頭になりそうです。
個人的には、Intel NCS2も引き続き注目して行きます。OpenCVのDNNに対応していたりと、まだまだ一長一短があるように感じます。
ただし、機械学習や推論を目的としたIoTデバイスの本命は、Jetson Nanoになりそうです。IntelのNCSはベアボーン系のミニPCかな。

関連記事:

NVIDIA Jetson Nanoで機械学習(推論)

Movidius Neural Compute Stick2とRaspberry Pi 3B +も利用しておりますが、GPU/推論向けデバイスが一体化されており、少しサイズは大きいです。
USB3.0などI/Fに差分もあるので、Raspberry Pi 4Bと比較したほうが良いかもしれません。ただし、Raspberry Pi 4B と NCS2を同時導入すると考えると、Jetson Nanoのほうがコストパフォーマンスが良いと思いますし、便利なフレームワーク利用により、開発時の手間(コスト)も考えると、機械学習にはNVIDIA Jetson Nanoがベストな選択と思います。NVIDIAですから。

Jetson Nano、Raspberry Pi 3B + with NCS2 速度比較

めざましじゃんけん時に取得したWEBカメラ画像を216枚で画像認識エンジンを動作させた際の性能比較です。
以前同じテストを用いて、NCS2(Movidius Neural Compute Stick 2)導入により十分高速化された結果となりました。今回は、その結果と比べても十分に魅力的なJetson Nanoの結果が出ました。

参考記事:ディープラーニング向けUSBアクセラレーターNeural Compute Stick 2ー

Windows(GPU未使用)
Core i7 6700/(Skylake) クロック周波数:3.4GHz
15秒 opencv.dnn
Raspberry Pi 3
Model B+
ARM Cortex-A53 1.4GHz
785秒 opencv.dnn
Raspberry Pi 3
Model B+
ARM Cortex-A53 1.4GHz
+  Movidius Vision Processing Unit(Myriad 2)
105秒 opencv.dnn
NVIDIA Jetson Nano
Quad-core ARM A57 @ 1.43 GHz
109秒 opencv.dnn
NVIDIA Jetson Nano
Quad-core ARM A57 @ 1.43 GHz
+ 128-core Maxwell
46秒 Keras-YOLO
2019-08-14 20:34:48,460:202:INFO:ループ開始:D:\pic4ml\Janken_Target_Test\20190806_055717_102196_1.jpg 処理回数:1
2019-08-14 20:35:03,389:256:INFO:ジャンケン結果判定 Len(total_results): 3 List Values: 0,2,5
019-08-14 20:35:03,390:289:INFO:ジャンケン結果:Chokiを出してLose、相手はGoo
2019-08-15 12:11:10,292:202:INFO:ループ開始:/home/miki/cronScript/Janken_Target_Test/20190806_055717_102196_1.jpg 処理回数:1
2019-08-15 12:24:15,786:256:INFO:ジャンケン結果判定 Len(total_results): 3 List Values: 0,2,5
2019-08-15 12:24:15,787:289:INFO:ジャンケン結果:Chokiを出してLose、相手はGoo
2019-08-24 12:16:09,419:202:INFO:ループ開始:/home/miki/cronScript/Janken_Target_Test/20190806_055717_102196_1.jpg 処理回数:1
2019-08-24 12:17:54,200:256:INFO:ジャンケン結果判定 Len(total_results): 3 List Values: 0,2,5
2019-08-24 12:17:54,201:289:INFO:ジャンケン結果:Chokiを出してLose、相手はGoo
created by Rinker
NVIDIA
¥19,000 (2021/08/19 16:46:56時点 Amazon調べ-詳細)

関連記事:NVIDIA JETSON NANO

Intel Neural Compute Stick 2

新しい記事を公開しました:NVIDIA Jetson Nano USB ディスクをルート構成

USB接続外部接続構成

ディスク構成は、SDカードおよびUSB接続のHDD/SSDとなりますが、USB接続の外部ディスクにルートディレクトリを配置させたUSB接続の外部HDD/SSDブート構成が構築出来ました。

以下が、NVIDIAより提供されているSDカードイメージとなり、パーティションナンバー1番のAPPを外部接続のHDDやSSDに格納し、2番から12番をSDカードに格納し、USB3.0を認識出来るようにファイルを追加し、SDカードとUSB外部接続のHDD/SSDを準備します。

Sector size (logical/physical): 512B/512B 
Partition Table: gpt 
Disk Flags:  
Number  Start   End     Size    File system  Name  Flags
2      1049kB  1180kB  131kB                TBC  
3      2097kB  2556kB  459kB                RP1  
4      3146kB  3736kB  590kB                EBT  
5      4194kB  4260kB  65.5kB               WB0  
6      5243kB  5439kB  197kB                BPF  
7      6291kB  6881kB  590kB                TOS  
8      7340kB  7406kB  65.5kB               EKS  
9      8389kB  9044kB  655kB                LNX 
10      9437kB  9896kB  459kB                DTB 
11      10.5MB  10.6MB  131kB                RP4 
12      11.5MB  11.6MB  81.9kB               BMP  
1      12.6MB  15.9GB  15.9GB  ext4         APP

通常のSDカード構成

SDカードイメージダウンロード

以下のURLに従い、利用するOSの手順でSDカードを準備しJetson Nano Developer Kit SD Card Imageを作成すれば、SDカードを用いてJetson Nanoの起動は可能となります。

Write Image to the microSD Card

(Windows)SDカードフォーマット

Raspberry Piで起動ディスクを作成する際にも使う、おなじみのツールでSDカードをフォーマットします。

SD Memory Card Formatter for Windows Download

SDカードへOSイメージを焼き付け

こちらもRaspberry Piの起動ディスク作成でもおなじみのツールとないrます。

EtcherでダウンロードしたSDカードイメージをSDカードにコピーします。

「jetson-nano-sd-r32.2-2019-07-16.zip」「sd-blob-b01.img」

外部USB接続のHDDやSSDを用いたブート構成のディスク作成

以下のサイトが情報源となります。詳細も書かれています。
NVIDIA Jetson Nano: How to Install Rootfs on External USB Drive

最新のSDカードイメージと同様のバージョンで、SDカード用とUSB接続のHDD/SSD用のイメージが公開されています。

Etcherでそれぞれのイメージをコピーします。
USB接続のHDDやSSDへイメージを書き込む際には、以下の警告メッセージが出ますが、「Continue」続けるを選択して、イメージの作成を行います。

以上で、SDカードとUSB接続のHDDやSSDとのブート構成でのJetson Nanoの起動が出来ました。
まだ、導入時点なので、もう少しパーティション構成も検討し、本格導入する予定です。Jetson Nanoは正解なのか?
現時点の日本では、Raspberry Piほどコミュニティーが活性化されていないのが実態。ただし、機械学習を考えると、魅力的なスペックです。

created by Rinker
NVIDIA
¥19,000 (2021/08/19 16:46:56時点 Amazon調べ-詳細)

NVIDIA Jetson NanoのCUDAが最適では?

4GB Raspberry Pi 4 Computer Model Bをついに導入かと秒読み状態でしたが、
そういえば、NVIDIAから気になるシングルボードNvidia Jetson Nano。
少し調べましたが、NVIDIA JETSON NANOが正解では?

「Raspberry Pi 4 model B」の発売日が、2019年6月24日。
「NVIDIA JETSON NANO」の発売発表が、2019年3月。
ほとんど差がありません。しかも、国内での発売状況を見ると、しっかりとリリースに向けて準備できているNVIDIA。更に数多くの上位機種。品質面も安心?

すべての機械学習や画像検出を、シングルボードコンピューターで動作させることを考えている方におすすめだと思います。

画像検出のFPSパフォーマンス

一目瞭然、ここまでの速度が達成出来るんだ。
しかも、こんなに多くのフレームワークに対応している。
たしかに、NVIDIA CUDAですものね。。

Raspberry Pi3やIntel Neural Compute Stick2などとの比較もバッチリです。
Raspberry Pi 4とIntel Neural Compute Stick2の組み合わせを考えましたが、おそらく、NVIDIA128CUDAコアに、数多くのフレームワークサポート。
どちらが安全な買い物かと考えると、答えは簡単と思います。

さて、Intel Neural Compute Stick2をすでに導入している私のシステムですが、そのような状況下でもNVIDIA Jetson Nanoの導入を判断しました。

NVIDIA Jetson Nano仕様

GPU128 基の NVIDIA CUDA® コアを実装した NVIDIA Maxwell アーキテクチャ
CPUクアッドコア ARM® Cortex®-A57 MPCore プロセッサ
メモリ4 GB 64 ビット LPDDR4
ストレージ16 GB eMMC 5.1 フラッシュ
ビデオ エンコード4K @ 30 (H.264/H.265)
ビデオ デコード4K @ 60 (H.264/H.265)
カメラ12 レーン (3x4 または 4x2) MIPI CSI-2 DPHY 1.1 (1.5 Gbps)
コネクティビティギガビット イーサネット
ディスプレイHDMI 2.0 または DP1.2 | eDP 1.4 | DSI (1 x2) の 2 つ同時
UPHY1 x1/2/4 PCIE、1x USB 3.0、3x USB 2.0
I/O1x SDIO / 2x SPI / 4x I2C / 2x I2S / GPIOs
サイズ69.6 mm x 45 mm
コネクタ260 ピン エッジ コネクタ

NVIDIA Jetson NanoとRaspberry Pi4との比較

Raspberry Pi 4NVIDIA Jetson Nano
CPUQuad-core ARM Cortex-A72 64-bit @ 1.5 GhzQuad-Core ARM Cortex-A57 64-bit @ 1.42 Ghz
GPUBroadcom VideoCore VI (32-bit)NVIDIA Maxwell w/ 128 CUDA cores @ 921 Mhz
Memory4 GB LPDDR4**4 GB LPDDR4
NetworkingGigabit Ethernet / Wifi 802.11acGigabit Ethernet / M.2 Key E (for Wifi support)
Display2x micro-HDMI (up to 4Kp60)HDMI 2.0 and eDP 1.4
USB2x USB 3.0, 2x USB 2.04x USB 3.0, USB 2.0 Micro-B
Other40-pin GPIO40-pin GPIO
Video EncodeH264(1080p30)H.264/H.265 (4Kp30)
Video DecodeH.265(4Kp60), H.264(1080p60)H.264/H.265 (4Kp60, 2x 4Kp30)
CameraMIPI CSI portMIPI CSI port
StorageMicro-SDMicro-SD
created by Rinker
NVIDIA
¥19,000 (2021/08/19 16:46:56時点 Amazon調べ-詳細)

アダプタでの給電を利用する方は、ジャンパーピンが必要です。

Yolo3、Tiny-Yolo3での独自学習方法

画像検出に向けて、独自に準備した教師データを用いて、AlexeyAB Darknetを用いて、YOLO3、Tiny-YOLO3で独自学習を行います。
YOLO3とTiny-YOLO3での独自学習時の違いは、独自学習時に指定するコンフィグファイルの違いのみとなります。処理速度と画像検出の違いとなっておりますが、画像検出対象により向き不向きもあると思うので、両方での試行をお勧めします。

また、YOLO2など以前のフレームワークも利用しましたが、画像検出精度や検出速度で、明らかにYOLO3のほうが良いので、学習後のモデル動作環境がYOLO3で問題なければ、YOLO3の利用をお勧めします。

参考にさせて頂いたサイト

前提条件

AlexeyAB Darknetを用いて、YOLO3・Tiny-YOLO3で独自学習に向けた準備

LabelImg利用方法(アノテーション)で準備した、7クラスの学習を行います。
最終的な、独自学習を実行する際のコマンドラインは以下となります。

darknet.exe detector train cfg/obj.data cfg/yolov3-voc-janken.cfg darknet53.conv.74
  1. darknet.exe
    Windows10に AlexeyAB・Darknet・YOLO V3導入(Vestal Studio)でコンパイルした実行ファイル。(「darknet\build\darknet\x64」に格納されています)
  2. obj.data(obj.data内で指定するobj.names)の2ファイル
  3. yolov3-voc-janken.cfg、yolo3, tiny-yolo3向けに事前準備されたモデル定義をコピーして独自学習向けに作成
  4. darknet53.conv.74、学習開始時の初期ウェイトファイル。yolo3とtiny-yolo3では異なるファイルを用います。

obj.dataに、train(学習データー)とvalid(検証データー)のリストを設定します。
このtrainとvalidのファイルリストは、LabelImg利用方法(アノテーション)でラベリングしたフォルダで、以下のスクリプト(process.py)を実行し、自動的に作成します。

process.pyですが、データファイルのパス指定、ファイル名、テストデータの割合を指定します。以下の例では、検証データを全体のファイル数の10%を検証データに指定されています。

import glob, os

# Current directory
current_dir = os.path.dirname(os.path.abspath(__file__))

# Directory where the data will reside, relative to 'darknet.exe'
path_data = 'data/obj/'

# Percentage of images to be used for the test set
percentage_test = 10;

# Create and/or truncate train.txt and test.txt
file_train = open('train.txt', 'w')  
file_test = open('test.txt', 'w')

# Populate train.txt and test.txt
counter = 1  
index_test = round(100 / percentage_test)  
for pathAndFilename in glob.iglob(os.path.join(current_dir, "*.jpg")):  
    title, ext = os.path.splitext(os.path.basename(pathAndFilename))

    if counter == index_test:
        counter = 1
        file_test.write(path_data + title + '.jpg' + "\n")
    else:
        file_train.write(path_data + title + '.jpg' + "\n")
        counter = counter + 1
  • train.txt トレーニング用画像ファイル一覧
  • test.txt 検証用画像ファイル一覧

obj.data(obj.data内で指定するobj.names)の2ファイル

「darknet\build\darknet\x64\cfg\obj.data」ファイル

学習クラス数をClassに登録します。作成した、train.txtとtest.txtファイルパスを指定します。
次に作成する、cfg/obj.namesと学習結果を格納するフォルダbackupを指定します。

classes = 7
train = train.txt
valid = test.txt
names = cfg/obj.names
backup = backup/

「darknet\build\darknet\x64\cfg\obj.names」ファイル

学習クラス名一覧を指定します。

janken_active
janken_goo
janken_choki
janken_pa
janken_won
janken_lose
janken_draw

yolov3-voc-janken.cfg、yolo3, tiny-yolo3向けに事前準備されたモデル定義をコピーして独自学習向けに作成

Yolo3向けcfgファイル作成

「darknet\build\darknet\x64\cfg\」フォルダ内の初期ファイルをコピーして、自己学習向けのコンフィグファイルを作成します。yolov3.cfg、yolo-obj.cfgをコピー元ファイルとして、編集するコンフィグファイルを作成します。

  • Batch数を変更します。batch=64
  • Subdivisionsを変更します。subdivisions=8
  • 学習するクラス数に合わせて、最大バッチ回数を指定します。
    学習するクラス数×2000となります。
    7クラスでの学習の際には、max_batches=14000 とします。
  • Stepsを最大バッチ回数の80%と90%になるように修正します。
    最大バッチ回数が14000の場合は、steps=11200,12600とします。
  • 3つある[yolo]レイヤーのClassesを、今回学習させる7に変更します。
  • [yolo]レイヤー直前の[convolutional]レイヤーのfiltersを変更します。
    filtersの値は、(classes + 5)×3とします。
    7クラスの場合は、(7+5)×3=36を指定します。

Tiny-Yolo3向けcfgファイル作成

「darknet\build\darknet\x64\cfg\」フォルダ内の初期ファイルをコピーして、自己学習向けのコンフィグファイルを作成します。yolov3-tiny-obj.cfg、yolov3-tiny_obj.cfgをコピー元ファイルとして、編集するコンフィグファイルを作成します。

yolov3-tiny-obj.cfg based on cfg/yolov3-tiny_obj.cfg

  • Batch数を変更します。batch=64
  • Subdivisionsを変更します。subdivisions=8
  • 学習するクラス数に合わせて、最大バッチ回数を指定します。
    学習するクラス数×2000となります。
    7クラスでの学習の際には、max_batches=14000 とします。
  • Stepsを最大バッチ回数の80%と90%になるように修正します。
    最大バッチ回数が14000の場合は、steps=11200,12600とします。
  • 2つある[yolo]レイヤーのClassesを、今回学習させる7に変更します。
  • [yolo]レイヤー直前の[convolutional]レイヤーのfiltersを変更します。
    filtersの値は、(classes + 5)×3とします。
    7クラスの場合は、(7+5)×3=36を指定します。

学習開始時の初期ウェイトファイル準備

Yolo3向け初期ウェイトファイルダウンロード

https://pjreddie.com/media/files/darknet53.conv.74よりdarknet53.conv.74ファイルをダウンロードします。ダウンロードしたdarknet53.conv.74ファイルが初期ウェイトファイルとなります。

darknet53.conv.74

Tiny-Yolo3向けウェイトファイルダウンロード

https://pjreddie.com/media/files/yolov3-tiny.weightsよりyolov3-tiny.weightsファイルをダウンロードし、darknet.exeおよび標準のcfgファイルを用いて、初期ウェイトファイルを準備します。

darknet.exe partial cfg/yolov3-tiny.cfg yolov3-tiny.weights yolov3-tiny.conv.15 15

yolov3-tiny.conv.15

AlexeyAB/DarknetでYOLO3トレーニング開始

最初に示したコマンドラインで自己学習を開始します。

darknet.exe detector train cfg/obj.data cfg/yolov3-voc-janken.cfg darknet53.conv.74

Out of Memory

Out of Memoryが出る場合、GPUのメモリ不足となり、設定ファイルの変更が必要となります。設定ファイルで設定した、 subdivisions=16 を「32」や「64」へ変更し実行可能な設定へ変更が必要です。

32の倍数での画像サイズの縮小でも学習時のメモリサイズを減らすことが出来ます。width=256、height=256 などへwidth, heightを変更。