前回は、練習としてAndroidで物体認識アプリを作ってみました。
その結果、動きはそれっぽくなりましたが、Fashion Goods, Home Goodsなどの抽象的な2パターンの結果しか表示されませんでした。
そこで、今回は任意の画像を学習し、その結果に基づいて識別する方法を試してみました。
使用した開発環境
Android Studio 2024.3.2 Patch1
検証したスマートフォン
Nothing Phone 3a
- 1. 画像を学習する方法:Google Teachable Machine
- 2. 作成した学習モデルを.tslite形式ファイルとしてエクスポートする
- 3. Android Studioでコードを書く
- 4. 動作確認と気づいたこと
- 5. おわりに
1. 画像を学習する方法:Google Teachable Machine
画像を学習する方法はいろいろありますが、今回はGoogle Teachable Machine (GTM) を使ってみました。
GTMは機械学習モデルを作成できるWebサイトです。Googleによって無料提供されています。
teachablemachine.withgoogle.com
画像、音声、ポーズ (人の動き) の3つの学習モデルを作成できます。今回は画像について作成しました。
GTMの使い方はこちらのサイトに詳しく掲載されており、参考にさせていただきました。
2. 作成した学習モデルを.tslite形式ファイルとしてエクスポートする
先ほどのサイトで学習モデルを作成し、画面右側の「モデルをエクスポートする」を選択します。
すると、このような画面が表示されます。TensorflowLite、量子化済み、を選んでからエクスポートを開始します。
10枚程度の画像だと数分かかりますが、model.tfliteファイルが入ったzipファイルがダウンロードできるようになります。
浮動小数点を選択すると「model_unquant.tflite」が取得できます。まだ理由を調べられていませんが、model_unquant.tfliteファイルではAndroid側でうまく読み込めませんでした。
モデルのエクスポートについては、こちらのサイトを参考にさせていただきました。 qiita.com
3. Android Studioでコードを書く
新しいAndroid Studioプロジェクトを作り、Empty Activityを選択しました。新規追加または変更したファイルは以下の赤枠の通りです。
◾️AndroidManifest.xml
permissionを追記しました。
◾️ImageClassifier.kt
物体認識の処理はこちらで実施しています。Google Teachable Machineから取得したzipには、labels.txtとmodel.tfliteがあります。この2つをapp/assetsフォルダ (Android app viewで見た場合) に格納しています。
フォルダ構成ではapp/src/main/assetsです。
◾️MainActivity.kt
(長いので別ファイルのリンクをご確認ください)
MainActivity_objreco.kt · GitHub
ここではGUIの表示、カメラ読み込み、撮影など、物体認識以外の主な処理を担当しています。
◾️activity_main.xml
画面のレイアウトです。res/layoutフォルダで右クリック、 New > Layout Resource Fileを選択すると、このような画面が表示されます。
これはAndroid Studio についているLayout Editorです。
このようなGUI画面の中で編集することもできますし、画面部品をxml形式で記述することもできます。
Code と書いたボタンを押すとxml表記に切り替わります。もう一度Designと書いたボタンを押すとGUI画面に戻ります。
◾️string.xml
アプリ名を書いています。AndroidManifest.xmlで使われています。
◾️build.gradle
プロジェクトの中でどのようなモジュールを読み込むのかを定義しています。ここが書いていないと、.ktファイル側で文法が合っていてもエラーメッセージが出ます。
今回は学習モデルを読み込むためのTensorFlowLite、撮影した画像から認識するためのML Kitをインポート対象にしました。
4. 動作確認と気づいたこと
Androidスマートフォンで動かす前に、まずはTensorflowLiteのモデルの結果を確認しました。
GTMで学習が完了すると、Webブラウザ上で動作確認ができます。以下は気づき事項です。
・数枚の学習でも認識はできる。ただし、似たような色の物体が入ると精度が低下する
・動画を撮りながら画像にしていくと、大量の画像を簡単に集められる (GTMの基本機能)。しかし、画像が多くても精度が高いとは限らなかった (=過学習)
・ぬいぐるみ2種類を識別するためClassを2種類にした。すると、Class1、Class2の区別はついたが、全く関係ないものも全部Class2と表示された
たとえばこの例では2種類のぬいぐるみを学習の対象にしています。
しかし、赤色の皿、部屋の床、鞄など、全く関係ないものもすべて"Class2"のぬいぐるみと識別されてしまいました。
3つめのクラスを作って、関係ない画像を追加しておくと、誤判定はかなり減りました。
この例では、3つめの「その他未分類」というクラスでは、部屋にある本、布団、床、机などを適当に撮影した画像を入れました。
動作確認で布団を写すと、2つめのぬいぐるみである「ブローハイ」の確率を少し示しつつも、「その他未分類」と識別できました。
メインターゲットが写っているときは、きちんと認識されました。
しかし、うまくいかない例も多かったです。
たとえば、こちらは白い壁を写しているのに「ペリー」と判定されています。
こちらでは、床を写しているのに「ブローハイ」と判定されています。
一方、床が正しく「その他未分類」と判定されることもあります。
この辺りはかなり微細な調整が必要になりそうとわかりました。調整方法については、またタイミング合うときに調べたいと思います。
なお、このサイトから「量子化済み」を選択してmodel.tflite、labels.txtを取得し、Android Studioでassetsフォルダに入れます。
すると、Androidアプリで認識できるようになります。
これは認識がうまくいっている例ですが、使っている学習モデルは同じなので、床や壁などで「ブローハイ」と認識されることがあるのは同じでした。
5. おわりに
機械学習についてあまり試したことがなかったので、学習の手順や認識率の雰囲気などがいろいろとわかって勉強になりました。
次回はまた別のことを調べてみる予定です。