airpocket が 2024年01月29日07時35分30秒 に編集
初版
タイトルの変更
ゆでたまご判定AI
タグの変更
SPRESENSE
NNC
たまご
メイン画像の変更
記事種類の変更
製作品
ライセンスの変更
(MIT) The MIT License
本文の変更
# はじめに たまごをテーブルの上で回してみると、ゆでたまごだと回り続け、生たまごはうまく回りません。 ゆでたまごの場合は白身や黄身に運動エネルギーが伝わるため大きなエネルギーを受け取ってまわり続けますが、生たまごは中身が流動してエネルギーが伝わらずエネルギー減衰も大きためすぐに停止します。 この現象を利用し、モーターを使ってたまごに回転加速度を与えた際の消費電力を測定することでたまごの内部状態を推定することを狙いました。 閾値を使った判定も可能ですが、自分だけしか持っていないAIモデルを作ってみたかったためNeural Network Consoleをつかって[生たまご][ゆてたまご]のクラス分類を行うモデルを制作しました。 判定用のデータには、回転時の電流値を用いています。ステッピングモータでたまごを加減速しながら回転させた際の電流値を1024回サンプリングしてFFTし、512次元のベクトルデータとしてクラス分類を試みました。 # いきなり完成 実際にこの装置を使って10個の生たまごと10個のゆでたまごの分類を行ったところ正答率は100%でした。 @[twitter](https://twitter.com/AirpocketRobot/status/1751607371452010956) 2次目標として温泉たまごの検出をこころみましたが、これには失敗しています。採取したデータを見ると分類可能な情報は内包しているように見えるため、AIの学習を工夫すれば分類できる可能性も十分あるのではないかと考えています。 ## 構成  装置の構成は図の通りです。 ステッピングモーターで卵を回し、その際の電流変化を電流センサで読み取っています。 タイマーを使用せずそれなりに一定タイミングで動作させるため、メインコアでセンシング、サブ1コアでモーター制御しています。 ## 装置外観 装置はディスプレイを含む本体の上にたまごホルダーが載ってい構造です。 たまごホルダーはnema17 ステッピングモーターで回転させています。 装置の筐体とたまごホルダーは3Dプリンタで制作しました。当初の設計では保護用のクッションを介してたまごをホールドしていましたが、クッションの弾性がデータ測定のノイズとなったためリジットな固定に変更しました。 ## 動作している様子 モーターは、加速度が任意の周期の正弦波に一致する様加減速制御を行っています。一方で今回使用したステッピングモーターは、1stepごとにも短周期の加減速を繰り返しています。 @[twitter](https://twitter.com/AirpocketRobot/status/1751607371452010956) この動画では生たまごを使ってたまごの状態を推定しています。 グラフには、測定した電流値をFFT解析した結果を表示しています。 # 学習用データ この装置にはデータ採取用モードと推論実行用モードがあり、現状ではそれぞれ別コードに書き換えて実行します。 データ採取モードでは規定の周波数でモーターを回転させつつ電流値を測定します。得られた電流データはFFT処理を行いmicroSDに保存します。 データ測定はゆでたまご10個、生卵10個、温泉たまご4個を用い、それぞれ100回ずつ合計2400回行いました。 次の図は、実際に測定した電流の変化をグラフ化したものです。値は正規化しています。  大きな正弦波にステッピングモータのステップ動作の小さな波が重畳しているのが見えます。 次にゆでたまご、生たまご、温泉たまごのそれぞれで測定した電流値をFFT処理し、周波数特性を可視化しました。  大きな特徴としては、生たまごでは120Hz付近に存在する特徴的なピークがゆでたまごでは100Hz付近にシフトし、温泉たまごでは100~120Hzに幅広く存在しつつ全体的にピークが小さくなっています。 詳しく調査できていませんが、生卵は白身が液状のため硬い卵殻を中心とする固有振動数が120Hz付近に存在して共鳴、ゆで卵は固まった白身の弾性により低周波側にピークシフト、温泉たまごはゲル状の白身が緩衝材となって共鳴振動自体を緩和させた、、、のかもしれません。 # 学習について 得られたデータはSony Neural Network Consoleで512次元のベクトルデータとして学習させました。初期のモデルは以下の様な構造でしたが、自動探索機能を使用してより精度の高いモデルへ変更しています。 データの6割を学習用、残りをバリデーション用に用いています。 データサイズが小さいため、200世代の学習に必要な時間はCPUで10秒程度でした。 初期と最終的に生成されたモデルは次の通りです。   # 最後に 生たまごとゆでたまごの分類は成功しましたが、残念ながら温泉たまごの分類できませんでした。 人並みの判断はできたけれど人以上にはなれなかった、というのも人間っぽさの様で面白いかと思います。 データ採取の過程でモーターの回転数を高くした方が内部の情報が多く抽出できている様に見受けられたのですが、温泉卵を高速回転すると半生状態の白身構造が破壊されてしまい生たまごとの差が見えなくなってしまうという現象も発生しました。 データ採取行為自体が測定対象の状態を変化させてしまうというのはありがちなことでもあり、面白く感じました。 自分オリジナルのAIを作ってみたくて立ち上げたプロジェクトですが、なんとか基本機能は満足できました。生たまごとゆでたまごを判別するAIを持っているのは世界でも私ひとりだけかもしれないと思うと愉快な気分です。 # おまけの苦労話 今回の開発では、ゆでたまごと生たまごの特徴を含んだ学習用データを採取するのにもっとも苦労しました。初期の実験ではどの周波数帯に特徴が現れるのかがわからず条件出しに苦労し、得られたデータに含まれる特徴が少ない、また、実験開始直後には明らかに判別可能なデータが得られているにも関わらず、データの連続採取時になると特徴が消えるなどの減少に悩まされました。 