GoogleのAutoML Visionサービスでレゴブロックを機械学習をさせて分類出来るかを試した
Contents
AutoML Visionとは
GoogleのAutoML Visionは画像を読み込ませてノンプログラミングで独自の画像認識モデルを作成できるクラウド上のサービス。
ハイパーパラメータなどの難しい設定は無しで機械学習の学習済みモデルが生成される。
現在(2019年10月27日)はβ版だが画像分類とオブジェクト検出の2つのサービスが使える様になっていたので画像分類の方を試してみた。
画像分類とは画像に写っている物体が何かを判別して推測してくれるモデル。
自分の好きな画像を読み込ませて学習させてAIに覚えさせることができる。
また作成したモデルをEdgeデバイスにデプロイする事ができるのでCoral USB Acceleratorを接続したラズパイ(RaspberryPi 3 B+)上でカメラに写ったレゴのパーツを分類(推測)する事ができるかどうかを試してみた。
ちなみに何故レゴのパーツかと言うとレゴのパーツは色違いや似たような形のものが多く、「レゴのパーツ分類が大好き」という人は少数派だと思う。
将来的にはこのレゴのパーツ分類をAIとロボットにやってもらいたいと思っているのでGoogleのAutoMLでまずは第一歩を踏み出してみることにした。
尚、記事の最後に動画を載せているので参考にしてみて欲しい。
レゴパーツの画像をAutoML Visionで読み込んで学習した後、学習済みモデルをEdgeデバイス用に出力してラズパイに読み込む。
ラズパイにカメラモジュールを接続してカメラに写ったレゴのパーツが何であるかを予測する。
尚、AutoML Visionは有料サービスなので事前に請求情報の登録が必要になる。
料金は1時間(コンピュータ使用時間)で20ドルだが無料枠もあるので詳しくはGoogleのAutoML Visionの料金ページを確認して欲しい。
ちなみにレゴの写真500枚(5種類のレゴ)を読み込ませて学習させた時の時間は20分前後だった。
学習をさせたレゴのパーツは以下の5種類。
コネクションペグ 3M 青 ラベル名:con_peg_3M | |
コネクションペグ 赤 ラベル名:con_peg_r | |
リフトアーム1✕3 ラベル名:lift_arm_1_3 | |
リフトアーム2✕4 ラベル名:lift_arm_2_4 | |
リフトアーム3✕5 ラベル名:lift_arm_3_5 |
プロジェクトの作成
AutoML Visionを使用する前にGoogle Cloud Platformでプロジェクトの作成と請求情報(カードの登録など)を済ませておく。
プロジェクトの選択から「新しいプロジェクト」をクリックする。
- プロジェクト名:AutoMLVision
- 場所:組織なし
で「作成」ボタンをクリックする。
プロジェクトが作成されたら「お支払い」メニューから支払情報を登録しておく。
※無料枠を使用するのであっても支払情報の事前登録は必要な模様。
AutoML Vision
AutoML Visionにてレゴパーツ画像を学習させる。
大まかな手順は以下の通り。
- 事前準備
- データセットの作成
- 写真の準備
- 写真のアップロード
- ラベル付け
- トレーニング
- モデルの評価の確認
- モデルのダウンロード
事前準備
新規に作成したプロジェクトを選択した状態でダッシュボードで”AutoML”で検索すると一覧が表示されるので”Vision”を選択する。
ダッシュボードで画像分類(ベータ版)の”開始”をクリックする。
「SET UP NOW」をクリックすると先程作成したプロジェクトに対して必要なAPIが追加・許可される。
ちなみに「GO TO BILLING」は請求情報の登録、ここでは事前に請求情報の登録は済んでいる前提とする。
セットアップが終了したらProject IDをプルダウンから選択して「CONTINUE」をクリックする。
プロジェクトのダッシュボードで確認すると必要なAPIが追加されている。
データセットの作成
先程のAutoML Vsionに戻ってデータセットの作成を行う。
左のメニューで”データセット”を選択して”新しいデータセット”をクリックする。
データセット名に”lego_parts_20191019″をセットして”単一ラベル分類”を選択して「データセットを作成」をクリックする。
データセットが作成されてインポートタブが表示されるので一旦ここで止めてインポート用の画像を用意する。
写真の準備
AutoML Vsionに学習させるためのレゴのパーツの画像を用意する。
ヘルプによると1つのパーツについて様々な角度からの画像を100枚程度用意するのが良いと書いてあった。
レゴパーツを角度を変えながら100枚分の写真を撮るのはちょっと骨が折れる。
ディープラーニングでは1つの画像から角度を変えたりノイズを載せたりと”水増し”と呼ばれる枚数を増やすテクニックがあるが今回はスマートフォンで動画を撮影して数フレームごとにjpgに切り出す事にした。
今回はWindows標準の”フォト”プログラムの”写真の保存”機能で手動で動画中のフレームを指定してjpg画像を切り出した。
しかしそのうち面倒になってきたので今後の為に動画を読み込んで指定したフレームごとに指定したサイズで画像(jpg)を切り出すPythonのプログラムを自作して一括して画像を作成している(今回は未使用)
プログラムの詳細については別記事で説明する。
5種類のパーツに対して約100枚、合計500枚程度の画像を用意した。
写真のアップロード
AutoML Vsionのメニューから”データセット”を選択して先程作成した”lego_parts_20191019″を選択する。
”パソコンから画像をアップロード”を選択して「ファイルを選択」ボタンをクリックする。
アップロードするファイルを複数(最大500まで選択可能)選択して「開く」をクリックする。
ここで自分は失敗したのだが5種類500枚の画像を全てアップロードした後で次のステップのラベル付けを行おうとした。
ラベル付けの時にファイル名でソートが出来ないので5種類のレゴパーツが混在して表示されるのでラベル付けに手間取った。
一方、ラベル付されている画像とされていない画像はフィルタリングができるので1種類のパーツをアップロード→ラベル付け、次の1種類の画像をアップロード→ラベル付け・・・の順番でやった方が効率的なラベル付ができると思う。
ファイルを選択したらアップロード先のフォルダーを選択する。
”BROWSE”をクリックして右側に表示されるメニューからバケットを選択して”SELECT”、元の画面に戻って”続行”をクリックするとアップロードが開始される。
尚、アップロードが終了すると該当のgmailアドレスに完了メールが飛んでくる仕様になっていたので放置しておけば勝手にアップロードしてくれる。
ラベル付け
インポートが終了したら”イメージ”タブを選択した後、”新規ラベルを追加”をクリックしてラベルを作成する。
- con_peg_3M
- con_peg_r
- lift_arm_1_3
- lift_arm_2_4
- lift_arm_3_5
の5種類のラベルを追加した。
ラベル付けとはAutoML Vsionに対して「この画像にはこれが写っている」というアノテーション(注釈)を与えてあげること。
機械学習の「教師あり学習」を行おうとしている。
同一種類のレゴパーツを複数選択して”ラベルの割り当て”をクリックして該当のラベルを割り当てる。
尚、前述したがこれは手間の掛かる失敗したやり方。
1種類の画像をアップロードする毎にラベルを割り当てて行ったほうが効率が良い。
下記の画像は”コネクションペグ 3M 青”の写真のみを選択して”ラベルの割り当て”でラベル付けしている例
トレーニング
全ての画像に対してラベル付けが終了したら「トレーニングを開始」ボタンを押す。
尚、各ラベルの右側にトレーニング、検証、テストの数が表示されている。
トレーニング
トレーニング(全体の80%)は学習する為の画像の事。
この画像を使ってAutoML Vsionはレゴパーツを学習する。
検証
検証(全体の10%)はハイパーパラメータ(学習前に設定するパラメータ)の調整とトレーニングを停止するタイミングの決定に利用される。
通常ハイパーパラメータは”人が手動”で設定するのだがAutoML Visionでは画像から自動で設定する仕様になっている模様。
この辺はGoogleのノンプログラミングへのこだわりを感じる。
テスト
そしてテスト(全体の10%)は上記データでトレーニングをした後にモデルの評価(どれぐらい分類・予測が成功するか)に使用される。
トレーニング、検証、テストはそれぞれランダムに分割されて同じ画像を使わないことによって汎用性を高めている。
※学習をした画像で予測をしたら精度が高まるのは当然なので違う画像で予測テストを行う
モデルの定義
右側にモデルの定義が表示される。
モデル名は自動的に設定されるのでEdgeを選択して「続行」ボタンをクリックする。
モデルの最適化のオプション
モデルの最適化のオプションを以下の3つから選択する。
- Higher accuracy:精度が高いが判定に360ms必要
- Best trade-off:精度は中間、判定に150ms必要
- Faster predictions:精度は低め、判定が56msと高速
用途によって使い分ける事が可能になっていた。
Best trade-offを選択して「続行」ボタンを押した。
予算
予算(ノード時間)を指定する。
この予算を超えるとトレーニングが停止される模様(未検証)
学習に思ったより時間がかかってしまい思わぬ請求を防ぐために指定するのかも。
イメージ数が1000枚以下なら実時間は2となっていたので3を指定して「トレーニング」ボタンをクリックする。
”モデルをトレーニンしています”と表示されてトレーニングが開始される。
トレーニングが完了するとメールで通知されるのでしばらく放置する。
評価の確認
トレーニングが終了したら”評価”タブで結果を確認する。
適合率、再現率ともに100%近い数値が出ている!
サンプル数が少ないのと読み込ませた画像の質が均一だったのである意味当然の結果なのかも知れない。
実際にラズパイのカメラからの映像も同様の率で正解できるとは限らないが、まずは良い数値だと思う。
ちなみに適合率とは例えばコネクションペグ3Mと予測したものがコネクションペグ3M(正解)だった時の率。
例えば1つの画像をコネクションペグ3Mと予測して正解した後、残りの全ての画像を(コネクションペグ3Mが含まれているのにも関わらず)リフトアーム1✕3と予測したとしても、コネクションペグ3Mに関しては適合率が100%になる。
1回中1回正解なので。
一方、再現率はコネクションペグ3Mをコネクションペグ3Mと予測できた率。
こちらも全ての画像をコネクションペグ3Mと予測すればコネクションペグ3Mに限れば再現率は100%になる。
適合率、再現率は基本的にはトレードオフの関係になっている。
以下は混同行列。
全て100%!
モデルのダウンロード
学習済みのモデルをラズパイに向けてダウンロードする。
データセットの”テストと使用”タブで”Coral”を選択する。
エキスポート先のGoogle Cloud Storageで”BROWSE”をクリックする。
バケットを指定したら”SELECT”をクリックする。
「EXPORT」ボタンをクリックすると指定されたGoogle Cloud Storageに出力される。
説明ではgsutilコマンドでGoogle Cloud Storageから取得すると書いてあるがラズパイにはデフォルトではgsutilはインストールされていないので手動でダウンロードしてコピーする事にした。
Google Cloud PlatformのメニューからStorageー>ブラウザを選択する。
対象のストレージを選択する。
一覧にはアップロードした画像も表示されるのでそのままではどれがExportしたモデルなのか分からない。
検索(前方一致)で”model”と入力するとmodel-exportフォルダーが絞り込まれるのでクリックする。
その後、リンクを辿ると
- dict.txt
- edgetpu_model.tflite
- tflite_metadata.json
の3つのファイルが現れるのでダウンロードしてラズパイにコピーする。
ファイルの内容
dict.txt | ラベルの一覧のテキストファイル
|
edgetpu_model.tflite | レゴパーツを学習したEdgeデバイス向けのモデル |
tflite_metadata.json | 学習時の付加情報が格納されたJSON形式のファイル(tflite_metadata.json)
|
実行環境の準備
ラズパイにカメラの接続や必要なランタイムのインストール等、実行環境を整える。
ラズパイにカメラを接続する
ラズパイにカメラを接続して設定を行う。
以前の記事の「RaspberryPi 3 Model B+でIoT監視カメラをつくる(その1ハードウェア関連)」を参照の事。
Edge TPU、TesorFlowのインストール
プログラムの実行環境を整える。
- Edge TPUランタイムのインストール
- 最大クロック周波数で動作させる為のランタイムをインストール(オプション)
- TensorFlow Liteインタープリターのインストール
を行う。
これらの設定については以前の記事の「ラズパイとCoral USB Acceleratorで機械学習による画像の分類」を参照の事。
サンプルプログラムのダウンロードと修正
プログラムはCoralのページのサンプルを利用する事にした。
ちょうどラズパイとカメラを使ったサンプル例が載っている。
まずはgit cloneコマンドでサンプルプログラム類をダウンロードする。
コマンドとダウンロード後のディレクトリ構成は以前の記事の「ラズパイのカメラに写った映像をリアルタイムでTensorFlow Liteで推測する」を参照のこと(リンク先記事中のモデルとラベルをダウンロード以降は不要)
cd examples/lite/examples/image_classification/raspberry_pi
プログラムをダウンロードしたら上記のコマンドでディレクトリを移動してプログラムの修正を行う。
修正内容についてはやはり以前の記事のプログラムの修正の項を参照のこと。
尚、この修正はCoral USB Acceleratorを使用して画像分類を高速に実行する為の修正なので仮に修正をしなくてもラズパイの性能に応じて分類は動作する。
モデルとラベルのコピー
raspberry_piディレクトリの配下にdownloadsディレクトリを作成して上記のAutoML Visionで作成した学習済みモデルとラベル類(dict.txt、edgetpu_model.tflite、tflite_metadata.json)をsshでコピーする。
その際に分かりやすくする為にファイル名に”lego_”のプリフィクスを付加した。
ディレクトリ構造は以下の通りになる。
ちなみにmetadadaファイルはプログラムの動作には不要だがわかりやすくするためにコピーをしておいた。
├─examples
│ │
│ ├─lite
│ │ │
│ │ ├──examples
│ │ │ │
│ │ │ ├──image_classification
│ │ │ │ │
│ │ │ │ ├──raspberry_pi
│ │ │ │ │ README.md
│ │ │ │ │ classify_picamera.py
│ │ │ │ │ download.sh
│ │ │ │ │ requirements.txt
│ │ │ │ │ │
│ │ │ │ │ └──downloads
│ │ │ │ │ lego_dict.txt
│ │ │ │ │ lego_edgetpu_model.tflite
│ │ │ │ │ lego_tflite_metadata.json
│ │ │ │ │
プログラムの実行
以下のコマンドでサンプルプログラムを実行する。
python3 classify_picamera.py \
--model ./downloads/lego_edgetpu_model.tflite \
--labels ./downloads/lego_dict.txt
プログラムが実行されるとラズパイのディスプレイにカメラの画像と推測されたレゴパーツのラベルが確率と処理時間と一緒に表示される。
コネクションペグ(赤)は正しく認識された。
11.5ms(ミリ秒)で約70%の確率でcon_peg_r(コネクションペグ赤)と判定された。
しかし他の画像が思わしくない。
コネクションペグ(青)がリフトアーム1✕3(67%)と判定されてしまう。
角度や撮り方を変えると正しく判定される事もあるが間違っている時も多い。
リフトアーム1✕3は正しく判定される(83%)。
というか他の画像もリフトアーム1✕3に判定されがちなのでもしかしたらどれにも当てはまらない時にリフトアーム1✕3と判定しているのかも。
リフトアーム2✕4も1✕3(81%)と判定されてしまった。
リフトアーム3✕5も正しい時もあるが1✕3と判定されてしまう事も多い。
考察
評価の好成績から比べると残念な結果だがGoogleのAutoML Visionの問題と言うよりも別の問題だと思う。
考えられる原因としては、
- 学習させた画像の問題(スマートフォンで撮影、フォトアプリで手動で切り出した)
- ラズパイ側のカメラの問題(近くを撮影するとピントが合わない)
- 上記の両方
精度を上げるにはもう少し色々と試行錯誤をしてみる必要があることが分かったので継続してやってみたい。
何かお気づきの点があればアドバイスを頂けるとありがたい。
動画
今回の記事の内容を動画にしているので参考にしてみて欲しい。
最近のコメント