作業内容
このチュートリアルでは、AutoML Vision Edge を使用して作成した、エクスポートされたカスタム TensorFlow Lite モデルをダウンロードします。モデルを使用して花の画像を識別する既製の Android アプリを実行します。
目標
この入門用のエンドツーエンドのチュートリアルでは、コードを使用して次のことを行います。
- TFLite インタープリタを使用して、Android アプリで事前トレーニング済みモデルを実行します。
始める前に
AutoML Vision Edge からモデルをトレーニングする
Edge デバイスにモデルをデプロイする前に、Edge デバイスモデルのクイックスタートに沿って AutoML Vision Edge から TF Lite モデルをトレーニングしてエクスポートする必要があります。
クイックスタートを完了すると、以下のようにトレーニング済みのモデルファイル(TF Lite ファイル、ラベルファイル、メタデータ ファイル)がエクスポートされます。
TensorFlow をインストールする
チュートリアルを開始する前に、次のソフトウェアをインストールする必要があります。
- tensorflow バージョン 1.7 をインストールする
- PILLOW をインストールする
Python がすでに動作している場合は、次のコマンドを実行して、このソフトウェアをダウンロードします。
pip install --upgrade "tensorflow==1.7.*" pip install PILLOW
このプロセスで問題が発生した場合は、TensorFlow の公式ドキュメントをご覧ください。
Git リポジトリのクローンを作成する
コマンドラインを使用して、次のコマンドで Git リポジトリのクローンを作成します。
git clone https://github.com/googlecodelabs/tensorflow-for-poets-2
リポジトリのローカル クローンのディレクトリ(tensorflow-for-poets-2
ディレクトリ)に移動します。このディレクトリから次のコードサンプルをすべて実行します。
cd tensorflow-for-poets-2
Android
アプリを設定するAndroid Studio をインストールする
必要に応じて、Android Studio 3.0 以降をインストールします。
Android Studio でプロジェクトを開く
Android Studio でプロジェクトを開くには、次の操作を行います。
Android Studio を開きます。読み込まれたら、このポップアップから [Open an existing Android Studio project] を選択します。
ファイル選択画面で、作業ディレクトリから
tensorflow-for-poets-2/android/tflite
を選択します。初めてプロジェクトを開く場合、Gradle ラッパーの使用について尋ねる [Gradle Sync] ポップアップが表示されます。[OK] を選択します。
アプリのテストを行う
アプリは、実際の Android デバイスか Android Studio Emulator で実行できます。
Android デバイスを設定する
デベロッパー モードと USB デバッグを有効にしないと、アプリを Android Studio からスマートフォンに読み込めません。
一回限りの設定手順を完了するには、こちらの手順に従ってください。
カメラアクセスでエミュレータを設定する(省略可)。
実際の Android デバイスではなくエミュレータを使用する場合、エミュレータの設定は Android Studio で簡単にできます。
このアプリはカメラを使用します。そのため、デフォルトのテストパターンではなくパソコンのカメラを使用するようにエミュレータのカメラを設定します。
エミュレータのカメラを設定するには、Android Virtual Device Manager で新しいデバイスを作成する必要があります。Android Virtual Device Manager には、このボタン からアクセスできます。メインの AVDM ページで [Create Virtual Device] を選択します。
次に、仮想デバイスの設定の最後のページ [Verify Configuration] ページで [Show Advanced Settings] を選択します。
詳細設定で、ホスト コンピュータのウェブカメラを使用するように両方のカメラソースを設定できます。
オリジナル アプリを実行する
アプリに変更を加える前に、リポジトリに付属のバージョンを実行します。
ビルドとインストールのプロセスを開始するには、Gradle 同期を実行します。
Gradle 同期を実行したら、再生 を選択します。
再生ボタンを選択したら、次のポップアップからデバイスを選択します。
デバイスを選択したら、TensorFlow デモにカメラとファイルへのアクセスを許可する必要があります。
アプリがインストールされたら、アプリアイコン をクリックして起動します。このバージョンのアプリは、1,000 個の ImageNet カテゴリでトレーニング済みの、標準の MobileNet を使用しています。
次のようになります。
カスタマイズしたアプリを実行する
デフォルトのアプリ設定では、標準の MobileNet を使用して、再トレーニングをせずに 1,000 個の ImageNet クラスのいずれか 1 つに画像を分類します。
ここで、アプリが AutoML Vision Edge で作成したモデルをカスタムの画像カテゴリに使用するように変更します。
モデルファイルをプロジェクトに追加する
デモ プロジェクトは android/tflite/app/src/main/assets/
ディレクトリの graph.lite
と labels.txt
ファイルを検索するように構成されています。
次のコマンドを使用して、2 つのオリジナル ファイルを自身のバージョンに置き換えます。
cp [Downloads]/model.tflite android/tflite/app/src/main/assets/graph.lite cp [Downloads]/dict.txt android/tflite/app/src/main/assets/labels.txt
アプリに変更を加える
このアプリは浮動小数点モデルを使用していますが、AutoML Vision Edge で作成されたモデルは量子化されています。コードを変更して、アプリでこのモデルを使用できるようにします。
クラスメンバー定義と ImageClassifier
イニシャライザで、labelProbArray
と filterLabelProbArray
のデータ型を float から byte に変更します。
private byte[][] labelProbArray = null;
private byte[][] filterLabelProbArray = null;
labelProbArray = new byte[1][labelList.size()];
filterLabelProbArray = new byte[FILTER_STAGES][labelList.size()];
ImageClassifier
イニシャライザで、int8 型に基づいて imgData
を割り当てます。
imgData =
ByteBuffer.allocateDirect(
DIM_BATCH_SIZE * DIM_IMG_SIZE_X * DIM_IMG_SIZE_Y * DIM_PIXEL_SIZE);
printTopKLabels()
で、int8 から float へ labelProbArray
データ型をキャストします。
private String printTopKLabels() {
for (int i = 0; i < labelList.size(); ++i) {
sortedLabels.add(
new AbstractMap.SimpleEntry<>(labelList.get(i), (float)labelProbArray[0][i]));
if (sortedLabels.size() > RESULTS_TO_SHOW) {
sortedLabels.poll();
}
}
String textToShow = "";
final int size = sortedLabels.size();
for (int i = 0; i < size; ++i) {
Map.Entry<String, Float> label = sortedLabels.poll();
textToShow = String.format("\n%s: %4.2f",label.getKey(),label.getValue()) + textToShow;
}
return textToShow;
}
アプリを実行する
Android Studio で Gradle 同期を実行して、ビルドシステムがファイルを検出できるようにします。
Gradle 同期を実行したあと再生 を選択し、ビルドとインストールのプロセスを開始します。
次のようになります。
電源ボタンと音量小ボタンを同時に押し続けることで、スクリーンショットを撮影できます。
さまざまな花の写真にカメラを向けて画像が正しく分類されるかを確認することで、更新したアプリをテストします。
仕組み
これでアプリケーションを実行できたので、TensorFlow Lite 固有のコードを調べてみましょう。
TensorFlow-Android AAR
このアプリはコンパイル済みの TFLite Android Archive(AAR)を使用しています。この AAR は jcenter でホストされます。
モジュールの build.gradle
ファイル内の以下の行には、プロジェクトの TensorFlow bintray Maven リポジトリからの最新バージョンの AAR が含められます。
repositories { maven { url 'https://google.bintray.com/tensorflow' } } dependencies { // ... compile 'org.tensorflow:tensorflow-lite:+' }
次のブロックを使用して、.lite
アセットや .tflite
アセットを圧縮しないように Android Asset Packaging Tool に指示します。.lite
ファイルはメモリマップされて、ファイルが圧縮されている場合は機能しないため、これは重要になります。
android { aaptOptions { noCompress "tflite" noCompress "lite" } }
TFLite Java API の使用
TFLite に連結されたコードはすべて ImageClassifier.java
に含まれます。
設定
まず注目すべきブロックは、ImageClassifier
のコンストラクタです。
ImageClassifier(Activity activity) throws IOException { tflite = new Interpreter(loadModelFile(activity)); labelList = loadLabelList(activity); imgData = ByteBuffer.allocateDirect( 4 * DIM_BATCH_SIZE * DIM_IMG_SIZE_X * DIM_IMG_SIZE_Y * DIM_PIXEL_SIZE); imgData.order(ByteOrder.nativeOrder()); labelProbArray = new float[1][labelList.size()]; Log.d(TAG, "Created a Tensorflow Lite Image Classifier."); }
特に注目すべき行がいくつかあります。
次の行は、TFLite インタープリタを作成します。
tflite = new Interpreter(loadModelFile(activity));
この行は、TFLite インタープリタをインスタンス化します。このインタープリタは tf.Session
と同様に機能します(TFLite 以外の TensorFlow に詳しい方向け)。モデルを含む MappedByteBuffer
をインタープリタに渡します。ローカル関数 loadModelFile
は、アクティビティの graph.lite
アセット ファイルを含む MappedByteBuffer
を作成します。
次の行は、入力データバッファを作成します。
imgData = ByteBuffer.allocateDirect( 4 * DIM_BATCH_SIZE * DIM_IMG_SIZE_X * DIM_IMG_SIZE_Y * DIM_PIXEL_SIZE);
このバイトバッファは、float に変換された画像データを格納できるサイズになっています。float 配列を入力として直接受け入れることができますが、インタープリタで余分なコピー抑えられるため、ByteBuffer
のほうが効率的です。
次の行は、ラベルリストを読み込んで出力バッファを作成します。
labelList = loadLabelList(activity); //... labelProbArray = new float[1][labelList.size()];
出力バッファは、モデルが出力確率を書き込むラベルごとに 1 つの要素を持つ float 配列です。
モデルを実行する
次に注目すべきブロックは、classifyFrame
メソッドです。このメソッドは入力として Bitmap
を受け取り、モデルを実行し、アプリで印刷するテキストを返します。
String classifyFrame(Bitmap bitmap) { // ... convertBitmapToByteBuffer(bitmap); // ... tflite.run(imgData, labelProbArray); // ... String textToShow = printTopKLabels(); // ... }
このメソッドは 3 つのことを行います。まず、このメソッドはモデルへの入力用に、入力 Bitmap
を imgData
ByteBuffer
に変換してコピーします。次に、このメソッドによりインタープリタの run メソッドが呼び出され、入力バッファと出力配列が引数として渡されます。インタープリタは出力配列の値をクラスごとに計算された確率に設定します。入力ノードと出力ノードは、以前に .lite
モデルファイルを作成した toco
コンバージョン ステップへの引数によって定義されます。
次のステップ
これで、Edge モデルを使った Android 花の分類アプリのチュートリアルを完了しました。画像分類アプリを変更してから、サンプルの注釈を取得する前に、画像分類アプリをテストしました。次に、TensorFlow Lite 固有のコードを調べて基本的な機能を理解しました。
- TFLite の詳細については、公式ドキュメントとコード リポジトリを参照してください。
- 小さなパッケージでより強力なモデルを作成するには、このデモアプリの量子化バージョンをお試しください。
- 音声ホットワード検出ツールやスマート リプライのデバイス バージョンなど、他の TFLite 対応モデルをお試しください。
- TensorFlow の概要については、TensorFlow のスタートガイドのドキュメントをご覧ください。