Arduino UNO Qを使った基板外観検査機製作に挑戦 Part 3: データ収集、モデルの学習とテスト

Arduino UNO Qと組込み機械学習エンジン「Edge Impulse」を使用してプリント基板の外観検査システムの構築を目指しています。
このシリーズの記事では、Arduino UNO Q(066-5593)と組込み用機械学習エンジンEdge Impulseを使ったAI/MLのモデル学習により、プリント基板製造工程の外観チェックをAI化させる事を目的にしています。
パート1では、想定するユースケース、およびUNO Qのハード構成や高度なプロトタイピングを実現する開発環境App Labについて紹介しました。パート2では、Uno Q等のハード部材をセットアップし、Arduino開発環境App LabとEdge Impulseの起動と実行、そしてモデル学習用の基板の準備を行いました。
パート3の今回は、Edge Impulse Studioを使用したデータ取得、モデル学習、評価テストを行っていきたいと思います。
なお一般的に機械学習 (ML) は人工知能 (AI) の一部と見なされており、このシリーズ記事中は両方の用語が同じ意味で使用される場合があります。
当面の課題

今回、チェックの合否判定としてはフレーム内のSOT23パッケージのトランジスタの数を用いる事にしました。実際の基板製造の現場では、より多くの部品について多面的で複雑なチェックを行う必要がありますが、その分学習量が増えてしまいます。今回はシステムの試作が目的なのでチェック項目を単純化させて行います。
モデルと方法
機械学習モデルをゼロから学習させる場合、ある程度の精度を出すには非常に大規模なデータセットが必要とすなります。これをサポートするため、学習と評価テストの両方に使用できる標準データセットが既に存在しています。その一例としてImageNetが挙げられます。ImageNetでは、2万以上のカテゴリにまたがる1,400万枚以上の手書きアノテーション付き画像をデータベース化しています。
また幸いなことに、比較的少数のデータセットしかなくても、Transfer learning(転移学習)と呼ばれる手法を活用できます。これは、事前学習済みのモデルを出発点として、特定の問題に合わせて微調整していく手法です。これにより、膨大なデータセットを構築する手間が省けるだけでなく、学習を実行するための強力なコンピューティングリソースへのアクセスも不要になります。

Edge Impulseプラットフォームでは、この転移学習を活用することで、マイコンからより強力なLinuxベースシステムまで、それぞれのプラットフォームに最適化された複数のモデルをサポートすることができます。さらに、独自のカスタムモデルをプラットフォームにアップロードすることも可能です。
今回、私たちはFOMO(Faster Objects, More Objects)MobileNetV2 0.35を採用しました。これはEdge Impulseが開発した新しいモデルで、より大規模なMobileNetV2モデルをバックボーンとして利用しています。その利点は、特に軽量(MobileNet SSDと比較して最大30分の1の処理能力とメモリ使用量)であること、高速であること、そして複数のオブジェクトをカウントしてその位置を特定できることなどです。0.1と0.35というサフィックスの意味など、詳細についてはFOMOのドキュメントをご覧ください 。
データ収集

前回の記事では、UNO QにソフトウェアをインストールしてEdge Impulse Studioとカメラを連携させる方法と、GStreamerを使って画像を直接キャプチャし、Edge Impulse CLI経由でアップロードする方法を紹介しました。スマートフォン、Webインターフェース、クラウドストレージなど、他の方法も利用可能です。
各データ取得メカニズムにはそれぞれ独自の利点があります。例えば、小規模なデータセットの場合、Webインターフェースからのプレビューとキャプチャの利便性、そしてEdge Impulse CLIは、大量のファイルやそれらに関連付けられた機械生成のラベルやメタデータがある場合に特に便利です。AmazonやGoogleなどのクラウドストレージを利用できることは、特に大規模なデータセットを扱うチームやプロジェクト間で作業する人にとって大きなメリットとなります。
object detection(検出チュートリアル)では、学習と評価テストに約50倍の画像を撮影することを推奨していたため、合計55倍の画像を撮影しました。上の画像では、ズームとフォーカスレベルを変え、ボードを回転させたり切り抜いたりしています。画像は学習用ディレクトリと評価用ディレクトリに分割し、推奨される80/20の比率で撮影しました。
{
"version": 1,
"files": [
{
"path": "training/PCBA01-A.jpg",
"name": "PCBA01-A.jpg",
"category": "training",
"label": {
"type": "label",
"label": "SOT23"
}
},
{
"path": "training/PCBA01-B.jpg",
"name": "PCBA01-B.jpg",
"category": "training",
"label": {
"type": "label",
"label": "SOT23"
}
},
{
"path": "training/PCBA01-C.jpg",
"name": "PCBA01-C.jpg",
"category": "training",
"label": {
"type": "label",
"label": "SOT23"
}
},
Edge Impulse CLIを使って画像をアップロードしてみることにし、そのためのinfo.labelsファイルを作成しました。その一部は上記に示されています。しかし、その後Studioで各パーツの実際の位置をラベル付けする際に、各パーツに付けていた「SOT23」というラベルが冗長であることに気付きました。
画像は次のようにアップロードされました。
$ edge-impulse-uploader --directory pcba-data --info-file pcba-data/info.labels

次にStudioに行き、データ取得中の画像を確認しました。

続いて、ラベル付けキューに進み、キャプチャした各画像に表示される SOT23 部品のラベル付けに進みます。

これにより、部分的に切り取られたデバイスにラベルを付けるかどうかという疑問が生じました。灰色の余白は、モデルの入力寸法の関係で使用されない画像領域を示しています。この点について検討したところ、切り取られたオブジェクトがいくつかあるとモデルの堅牢性が向上する可能性がある一方で、50%以上切り取られたり遮蔽されたりするとノイズが発生する可能性があることがわかりました。
Impulseを生成

「インパルス」は、特徴抽出と機械学習モデルを組み合わせたパイプラインであり、画像などの入力データを処理し、それを使用してモデルを学習します。
サイドメニューから「Create Impulse(新しいインパルスの作成)」を選択し、320x320ピクセルの入力画像を最短軸に合わせてリサイズしました。画像ブロック(白)にはデフォルトのオプションが設定されています。オブジェクト検出ブロックには、ラベルがSOT23である出力特徴が1つだけあることがわかります。

インパルスを保存し、メニューの「Image(画像)」を選択すると、色深度としてRGBまたはグレースケールを選択できるようになりました。次に、「Generate Features(特徴抽出)」を選択しました。少し待つと処理が完了し、右側のプロットで特徴を調べることができました。
出力機能が 2 つ以上ある場合、それぞれのクラスターが存在し、これらが明確に定義/分離されることが期待されるため、このプロットははるかに興味深いものになることに注意してください。
Training Attempt #1

次に、Object Detectionを選択し、ここからFOMO MobileNetV2 0.35モードを選択し、学習設定をデフォルトのままにしました。

「Save & Train(保存して評価)」をクリックし、学習プロセスが完了するまで少し待つ必要がありました。残念ながら、重要な評価指標であるF1スコアはわずか68.3%で、混同行列からも結果が芳しくないことがわかりました。

次のモデルテストではさらにショックを受けました。精度はわずか 27.27%。
何が起きている?!
正直、面食らってしまいました。いったい自分がどこで間違えたのか。多くの変数を考慮すると、パフォーマンス低下の原因として思い当たる事象としては以下あたりだと思います。
- モデルの選択:
- FOMO MobileNetV2 0.35 が、今回のケースに対して適切な選択ではなかったのかも
- 学習設定:
- もっと学習サイクルが必要だったのかも
- 学習率が違うのかも
- 高度なオプションの設定が必要?
- データ:
- 切り取った部分をもっと多く、あるいは少なくラベル付けしたほうがよかったかも
- 焦点が合っていない画像が多かった?
- 回転画像をもっと用意する必要あった?
- 各フレーム上の他のデバイスへのラベル付けした方が精度上がるかも?
再挑戦

再挑戦にあたり、さらに引きの画像セットを新たに使用し、SOT23だけでなくSOIC16部品にもラベルを付けしてみました。が、残念ながら結果はさらに悪く、この時点で、Edge Impulse の専門家にアドバイスを求めることにしました。
分析
結論から言えば、画像セットの中でフォーカスやズームのレベルを混在させていて、それをフォーカスやズームを一貫しているはずの場所に配置させた事が私の間違いの原因だでした。
さらに、モデルが元々学習した対象とは著しく異なるオブジェクトを扱うには、サンプル数が少なすぎました。転移学習を使用しているため、元のデータセットには表面実装型電子部品が含まれていなかったようです。
そのため、50 倍程度の画像ではなく、少なくとも 150 〜 200 倍の画像を用意することが必要だったようです。
Success!

3度目の正直として第三試作に取り掛かりました。新しいEdge Impulseプロジェクトを作成し、最初の試みで使用した画像をインポートすることから始めました。その後、焦点が合っていない画像やズームアウトした画像を削除しました。ラベル付きの画像が少量残っていたため、この作業が完全に無駄になったわけではありません。その後、部品を取り外した基板、基板を回転させた基板、ショット間の照明レベルを調整した基板の画像をさらに多く収集しました。
第三試作で使用した149枚の画像
画像にラベルを付け、特徴量を生成する手順を繰り返しました。学習設定に加えた変更の一つは、データ拡張(画像にランダムな変換を適用する)を有効にしたことです。これにより、過剰適合を減らし、精度を向上させることができます。
その結果、F1 スコアは 97.8% と大幅に向上しました。

テストの精度もまた 96.67% と大幅に改善し、満足のいく結果を得ました。
この事を通して、データ入力の品質がパフォーマンス低下の潜在的な原因である場合、まずは入力データの調査が有効であることを学びました。

テスト結果を調べて、モデルが部品を識別できなかった箇所を確認するのも興味深い点でした(上図参照)。私たちの目には、識別できなかった箇所は、正しく識別された隣接する箇所とそれほど違いがないように思えました。いずれにせよ、追加のアドバイスとして、学習データ内の切り取られた部分(以前はラベル付けしていなかった部分)にラベルを付けるべきだという意見もいただきました。また、精度が向上するかどうかを確認するために、さらに50枚程度の画像を集めることも価値があるかもしれません。

もう一つの便利なテスト機能はLive classification(ライブ分類)機能です。これはメインメニューから利用でき、UNO Qでedge-impulse-linuxを実行することで、ブラウザ経由でリアルタイムにデータをサンプリングし、画像を分類できます。これはさらなる検証を行うのに役立ち、新しいボードサンプル、切り抜き、回転などを素早く試すことができます。
チューニングアシスタント

最後に、今回は使えなかったEON Tunerについて簡単に紹介します。EON Tunerは、様々なモデルに加え、画像サイズや色深度、モデルの学習率や学習サイクルなどのパラメータを使ったテストを自動化することで、アプリケーションに最適なパフォーマンスを発揮するインパルスを見つけるのに役立ちます。これについてはまた別の機会に取り上げましょう。
次のステップ
パート 4 では、すべてをまとめ、Arduino App Lab を使用してカスタム モデルを展開し、物理的な入力と出力を統合して利便性を高める方法について説明します。
— Andrew Back
コメント