2025年5月30日

025-1.SPIKEプライム+ラズパイ+AIカメラ ロボットチャレンジ-第3回「AIカメラ用のモデルを作成する」

この記事では「レゴ エデュケーションSPIKEプライム(以下、SPIKE)」とRaspberry Pi(以下、ラズパイ)とAIカメラを組み合わせたロボットを作る方法について紹介します。(文/松原拓也)

◆ 3種類の画像を認識させる

前回に引き続き、ラズパイ公式のAIカメラ「Raspberry Pi AI Camera」を使って画像を認識します。 前回は、PyTorchを使って画像の認識に成功しました。しかし、AIアクセラレーションを使わず、ラズパイ側でソフトウェア的に処理していました。
今回はAIアクセラレーションを使って、AIカメラの性能をフルに活用します。


前回は「ラージハブ」と「ミニフィグ」、2種類の画像しか認識できませんでした。今回は「Lモーター」を追加して、全部で3種類の画像を認識できるようにします。
「train」フォルダの下には既に「large_hub」と「minifig」フォルダがありますが、ここに新しく「motor_l」フォルダを作り、Lモーターの画像ファイルを置きます。画像ファイルは、前回作成したcamera_picture_save.pyで撮影しました。


ターミナル(LXTerminal)を起動したら、仮想環境に切り替えます。「python -m venv .venv」「source .venv/bin/activate」と入力ましょう。すると、「.veny」と名付けた仮想環境に切り替わります。
AIカメラ(IMX500)はrpkという特殊なファイル形式でモデルを書き込みます。このファイルをネットワーク・ファームウェアと呼びます。ファイルを作成するツールとして、コンバーターパッケージャーがあります。コンバーターは別途インストールが必要です。コンバーターをインストールするには「pip install imx500-converter[pt]」と入力します。パッケージャーは「imx500-tools」に含まれています。
コンバーターに渡す変換ファイルを作るためには、モデルを量子化・圧縮しないといけません。そのためのツールがModel Compression Toolkit(MCT)です。MCTをインストールするには「pip install model-compression-toolkit」と入力します。

なぜか、前回に作成したモデルではコンバーターがエラーを出してしまって、動作しません。モデルに要求している仕様が少しでも違っていると受け付けないようです。エラーのメッセージの内容が専門的すぎて、問題点がわかりません。
モデルの作成方法を変えてみたり、何日か試行錯誤を繰り返してみたのですが、全く解決策が見つかりません。そこで、モデルを作り直すことにします。

◆ モデルを作り直す

AITRIOSのWebサイトで紹介されている方法に従って、いちからモデルを作り直します。次のWebページにモデル作成や量子化のコードが載っていますので、できる限りそのまま使うことにします。
https://developer.aitrios.sony-semicon.com/edge-ai-sensing/documents/pytorch-model-deployment-guide?version=2025-04-23

上記のWebページの「MobileNet v2 転移学習のサンプルコード」にあるコードをコピー&ペーストして、「train_model2.py」というファイル名で保存しました。このファイルは「train」フォルダと同じ階層に配置します。
今回の用途に合わせてコードを修正します。このサンプルでは「犬」「猫」の画像を認識するだけで、クラス数は2つに固定されています。そこで、画像フォルダの数に応じてクラス数が変化するようにコードを書き換えます。 さらにサンプルではデータセットのパスが「dataset/train」となっているので、「train」に変更します。

ターミナルを起動したら、仮想環境に切り替えます。そして、「python train_model2.py」とコマンドを入力します。コードを実行します。
実行すると、trainフォルダにある3種類の画像ファイルを学習して「weight.pth」というモデルを作成します。

上記Webページの「量子化のサンプルコード」にあるコードをコピー&ペーストして、「quantize.py」というファイル名で保存しました。
サンプルではクラス数が2で固定されていますので、画像フォルダの数に応じてクラス数が変化するようにコードを書き換えます。 さらにサンプルではデータセットのパスが「dataset/train」となっているので、「train」に変更します。

ターミナルで「python quantize.py」と入力してコードを実行します。 モデル「weight.pth」を読み込んで、それを量子化して、ONNX形式で保存します。ファイル名は「quantized.onnx」です。

◆モデルをパッケージ化する

コンバーターを実行して、モデル(ONNX形式)からpackerOut.zipというファイルを作ります。コンバーターにはPyTorch用とTensorFlow用がありますが、今回はPyTorch用を使います。
ターミナルで「imxconv-pt -i quantized.onnx -o outdir」を入力します。
コンバーターを実行する前から「outdir」フォルダが存在するとエラーになってしまいます。もし「outdir」フォルダが存在する場合には削除しておきましょう。

実行が完了するとカレントディレクトリに「outdir」フォルダが作られて、その中に「packerOut.zip」というファイルが作られます。packerOut.zipの中にはバイナリ化したモデルが入っています。

パッケージャーを実行して、rpkファイルを作成します。
ターミナルで「imx500-package -i ./outdir/packerOut.zip -o rpkdir」と入力します。

カレントディレクトリに「rpkdir」フォルダが作られて、その中に「network.rpk」が作成されます。rpkファイルはAIカメラのネットワーク・ファームウェアです。 このファイルを「picamera2/examples/imx500」フォルダに移動させます。
そして、同じ階層に「labels.txt」というテキストファイルを置きます。テキストファイルはmousepadというテキストエディタで作ります(ラズパイのOSに標準で入ってます)。ファイルの中には全てのクラス名を書いておきます。

◆ 分類デモを実行する

「picamera2/examples/imx500」フォルダにある「imx500_classification_demo.py」を開きます。AIカメラを分類を行うデモプログラムです。そのまま実行するとValueErrorなどが出ます。
修正前はラベル数が1000であることを前提していますが、それがエラーの原因となるので、関係する部分を削除します。さらに、スコアをソートする処理が、上位3件に対応させます。修正方法については次のWebページを参考にさせて頂きました(INFORMATION DEVELOPMENTさんの記事です)。
https://www.idnet.co.jp/column/page_376.html

仮想環境は必要ないので、Thonnyから実行します。
実行すると、最初にネットワーク・ファームウェア(network.rpk)をパソコンからAIカメラに転送します。少し待つと、カメラの画像とスコアが表示し続けます。 スコアは値が大きい順に上から表示されます。

カメラに被写体を写して、スコアを確認します。 ラージハブは「large_hub」、ミニフィグは「minifig」、Lモーターは「motor_l」の値が大きくなります。画像分類は成功です。

画像分類をしている様子です。
AIカメラのツールは全て無料なので、ぜいたくは言えませんが、使い方が難しいところもありました。
今回はここまでにしますが、この技術を使えば、画像を認識できるSPIKEのロボットを作ることができるかもしれません。

当ブログの内容は、弊社製品の活用に関する参考情報として提供しております。
記載されている情報は、正確性や動作を保証するものではありません。皆さまの創意工夫やアイデアの一助となれば幸いです。