Android のクイックスタート

このチュートリアルでは、TensorFlow Liteを使用してAndroidアプリを構築し、最小限のコードを使用して、ライブカメラフィードを分析し、機械学習モデルを使用してオブジェクトを特定する方法を示します。既存のプロジェクトを更新する場合は、コードサンプルを参照として使用し、プロジェクトを変更するための手順に進んでください。

機械学習による物体検出

物体検出アニメーションデモこのチュートリアルの機械学習モデルは、オブジェクト検出を実行します。オブジェクト検出モデルは、特定の形式の画像データを取得して分析し、画像内のアイテムを、認識できるようにトレーニングされた一連の既知のクラスの1つとして分類しようとします。モデルが既知のオブジェクト(オブジェクトの予測または推論と呼ばれる)を識別できる速度は、通常、ミリ秒単位で測定されます。実際には、推論速度は、モデルをホストしているハードウェア、処理されているデータのサイズ、および機械学習モデルのサイズによって異なります。

セットアップと実行の例

このチュートリアルの最初の部分では、GitHubからサンプルをダウンロードし、 AndroidStudioを使用して実行します。このチュートリアルの次のセクションでは、コード例の関連セクションについて説明し、独自のAndroidアプリに適用できるようにします。これらのツールの次のバージョンをインストールする必要があります。

  • AndroidStudio4.2.2以降
  • AndroidSDKバージョン31以降

サンプルコードを入手する

サンプルコードのローカルコピーを作成します。このコードを使用して、Android Studioでプロジェクトを作成し、サンプルアプリケーションを実行します。

サンプルコードのクローンを作成して設定するには:

  1. gitリポジトリのクローンを作成します
    git clone https://github.com/android/camera-samples.git
    
  2. スパースチェックアウトを使用するようにgitインスタンスを構成して、オブジェクト検出サンプルアプリのファイルのみを用意します。

    cd camera-samples
    git sparse-checkout init --cone
    git sparse-checkout set CameraXAdvanced
    

プロジェクトをインポートして実行します

ダウンロードしたサンプルコードからプロジェクトを作成し、プロジェクトをビルドして実行します。

サンプルコードプロジェクトをインポートしてビルドするには:

  1. AndroidStudioを起動します。
  2. Android Studioのウェルカムページから、[プロジェクトのインポート]を選択するか、[ファイル]>[新規]>[プロジェクトのインポート]を選択します。
  3. build.gradleファイル( .../android/camera-samples/CameraXAdvanced/build.gradle )を含むサンプルコードディレクトリに移動し、そのディレクトリを選択します。

正しいディレクトリを選択すると、AndroidStudioは新しいプロジェクトを作成してビルドします。コンピューターの速度や、他のプロジェクトでAndroid Studioを使用したことがあるかどうかによっては、このプロセスに数分かかる場合があります。ビルドが完了すると、 BUILD SUCCESSFULの[ビルド出力]ステータスパネルに[ビルド成功]メッセージが表示されます。

オプション: Androidプラグインのバージョンを更新してビルドエラーを修正するには:

  1. プロジェクトディレクトリにあるbuild.gradleファイルを開きます。
  2. Androidツールのバージョンを次のように変更します。

    // from:
    classpath 'com.android.tools.build:gradle:4.2.2'
    // to:
    classpath 'com.android.tools.build:gradle:4.1.2'
    
  3. [ファイル]>[プロジェクトをGradleファイルと同期]を選択して、プロジェクトを同期します。

プロジェクトを実行するには:

  1. Android Studioから、[実行] > [実行... ]と[CameraActivity]を選択して、プロジェクトを実行します。
  2. カメラ付きの接続されたAndroidデバイスを選択して、アプリをテストします。

次のセクションでは、このサンプルアプリを参照ポイントとして使用して、この機能を独自のアプリに追加するために既存のプロジェクトに加える必要のある変更を示します。

プロジェクトの依存関係を追加する

独自のアプリケーションでは、特定のプロジェクトの依存関係を追加してTensorFlow Lite機械学習モデルを実行し、画像などのデータを使用しているモデルで処理できるテンソルデータ形式に変換するユーティリティ関数にアクセスする必要があります。

サンプルアプリは、いくつかのTensorFlow Liteライブラリを使用して、オブジェクト検出機械学習モデルの実行を可能にします。

  • TensorFlow Liteメインライブラリ-必要なデータ入力クラス、機械学習モデルの実行、およびモデル処理からの出力結果を提供します。
  • TensorFlow Liteサポートライブラリ-このライブラリは、カメラからの画像を機械学習モデルで処理できるTensorImageデータオブジェクトに変換するためのヘルパークラスを提供します。
  • TensorFlow Lite GPUライブラリ-このライブラリは、デバイスでGPUプロセッサが利用可能な場合、それらを使用してモデルの実行を高速化するためのサポートを提供します。

次の手順では、必要なプロジェクトとモジュールの依存関係を独自のAndroidアプリプロジェクトに追加する方法について説明します。

モジュールの依存関係を追加するには:

  1. TensorFlow Liteを使用するモジュールで、モジュールのbuild.gradleファイルを更新して、次の依存関係を含めます。サンプルコードでは、このファイルは次の場所にあります: .../android/camera-samples/CameraXAdvanced/tflite/build.gradleコードリファレンス

    ...
    dependencies {
    ...
        // Tensorflow lite dependencies
        implementation 'org.tensorflow:tensorflow-lite:2.8.0'
        implementation 'org.tensorflow:tensorflow-lite-gpu:2.8.0'
        implementation 'org.tensorflow:tensorflow-lite-support:2.8.0'
    ...
    }
    
  2. Android Studioで、 [ファイル]> [プロジェクトをGradleファイルと同期]を選択して、プロジェクトの依存関係を同期します。

MLモデルインタープリターを初期化します

Androidアプリでは、モデルで予測を実行する前に、TensorFlowLite機械学習モデルインタープリターをパラメーターで初期化する必要があります。これらの初期化パラメータは、使用しているモデルによって異なり、予測の最小精度しきい値や識別されたオブジェクトクラスのラベルなどの設定を含めることができます。

TensorFlow Liteモデルには、モデルコードを含む.tfliteファイルが含まれ、モデルによって予測されたクラスの名前を含むラベルファイルが含まれることがよくあります。オブジェクト検出の場合、クラスは人、犬、猫、車などのオブジェクトです。モデルは通常、コード例のように、プライマリモジュールのsrc/main/assetsディレクトリに保存されます。

  • CameraXAdvanced / tflite / src / main / assets / coco_ssd_mobilenet_v1_1.0_quant.tflite
  • CameraXAdvanced / tflite / src / main / assets / coco_ssd_mobilenet_v1_1.0_labels.txt

利便性とコードの可読性のために、この例では、モデルの設定を定義するコンパニオンオブジェクトを宣言しています。

アプリでモデルを初期化するには:

  1. モデルの設定を定義するコンパニオンオブジェクトを作成します:(コードリファレンス

    companion object {
       private val TAG = CameraActivity::class.java.simpleName
    
       private const val ACCURACY_THRESHOLD = 0.5f
       private const val MODEL_PATH = "coco_ssd_mobilenet_v1_1.0_quant.tflite"
       private const val LABELS_PATH = "coco_ssd_mobilenet_v1_1.0_labels.txt"
    }
    
  2. このオブジェクトの設定を使用して、モデルを含むTensorFlow Liteインタープリターオブジェクトを構築します:(コードリファレンス

    private val tflite by lazy {
       Interpreter(
           FileUtil.loadMappedFile(this, MODEL_PATH),
           Interpreter.Options().addDelegate(nnApiDelegate))
    }
    

ハードウェアアクセラレータを構成する

アプリケーションでTensorFlowLiteモデルを初期化する場合、ハードウェアアクセラレーション機能を使用して、モデルの予測計算を高速化できます。上記のコード例では、NNAPIデリゲートを使用して、モデル実行のハードウェアアクセラレーションを処理します。

Interpreter.Options().addDelegate(nnApiDelegate)

TensorFlow Liteデリゲートは、GPU、TPU、DSPなどのモバイルデバイス上の特殊な処理ハードウェアを使用して機械学習モデルの実行を加速するソフトウェアモジュールです。 TensorFlow Liteモデルを実行するためにデリゲートを使用することをお勧めしますが、必須ではありません。

TensorFlow Liteでデリゲートを使用する方法の詳細については、「 TensorFlowLiteデリゲート」を参照してください。

モデルにデータを提供する

Androidアプリでは、コードは、画像などの既存のデータをモデルで処理できるTensorデータ形式に変換することにより、解釈のためにモデルにデータを提供します。テンソルのデータは、モデルのトレーニングに使用されるデータの形式と一致する特定の次元または形状を持っている必要があります。

モデルに必要なテンソル形状を決定するには:

  • 以下のコードスニペットに示すように、初期化されたインタープリターオブジェクトを使用して、モデルで使用されるテンソルの形状を決定します。(コードリファレンス

    private val tfInputSize by lazy {
       val inputIndex = 0
       val inputShape = tflite.getInputTensor(inputIndex).shape()
       Size(inputShape[2], inputShape[1]) // Order of axis is: {1, height, width, 3}
    }
    

サンプルコードで使用されているオブジェクト検出モデルは、300x300ピクセルのサイズの正方形の画像を想定しています。

カメラから画像を提供する前に、アプリで画像を取得し、予想されるサイズに合わせて回転を調整し、画像データを正規化する必要があります。 TensorFlow Liteモデルで画像を処理する場合、以下に示すように、TensorFlow LiteサポートライブラリImageProcessorクラスを使用して、このデータの前処理を処理できます。

モデルの画像データを変換するには:

  1. サポートライブラリImageProcessorを使用して、画像データをモデルが予測の実行に使用できる形式に変換するためのオブジェクトを作成します:(コードリファレンス

    private val tfImageProcessor by lazy {
       val cropSize = minOf(bitmapBuffer.width, bitmapBuffer.height)
       ImageProcessor.Builder()
           .add(ResizeWithCropOrPadOp(cropSize, cropSize))
           .add(ResizeOp(
               tfInputSize.height, tfInputSize.width, ResizeOp.ResizeMethod.NEAREST_NEIGHBOR))
           .add(Rot90Op(-imageRotationDegrees / 90))
           .add(NormalizeOp(0f, 1f))
           .build()
    }
    
  2. Androidカメラシステムから画像データをコピーし、 ImageProcessorオブジェクトで分析する準備をします:(コードリファレンス

    // Copy out RGB bits to the shared buffer
    image.use { bitmapBuffer.copyPixelsFromBuffer(image.planes[0].buffer)  }
    
    // Process the image in Tensorflow
    val tfImage =  tfImageProcessor.process(tfImageBuffer.apply { load(bitmapBuffer) })
    

予測を実行する

Androidアプリでは、正しい形式の画像データを使用してTensorImageオブジェクトを作成したら、そのデータに対してモデルを実行して、予測または推論を生成できます。このチュートリアルのサンプルコードでは、このコードをpredict predict()メソッドにカプセル化するObjectDetectionHelperクラスを使用しています。

画像データのセットに対して予測を実行するには:

  1. 画像データを予測関数に渡して予測を実行します:(コードリファレンス

    // Perform the object detection for the current frame
    val predictions = detector.predict(tfImage)
    
  2. 画像データを使用してtfliteオブジェクトインスタンスのrunメソッドを呼び出し、予測を生成します:(コードリファレンス

    fun predict(image: TensorImage): List<ObjectPrediction> {
       tflite.runForMultipleInputsOutputs(arrayOf(image.buffer), outputBuffer)
       return predictions
    }
    

TensorFlow Liteインタープリターオブジェクトはこのデータを受信し、モデルに対して実行して、予測のリストを生成します。モデルによるデータの継続的な処理の場合は、 runForMultipleInputsOutputs()メソッドを使用して、予測の実行ごとにインタープリターオブジェクトが作成され、システムによって削除されないようにします。

モデル出力の処理

Androidアプリでは、オブジェクト検出モデルに対して画像データを実行すると、追加のビジネスロジックを実行したり、ユーザーに結果を表示したり、その他のアクションを実行したりして、アプリコードが処理する必要のある予測のリストが生成されます。

特定のTensorFlowLiteモデルの出力は、生成する予測の数(1つまたは複数)、および各予測の説明情報によって異なります。オブジェクト検出モデルの場合、予測には通常、画像内のオブジェクトが検出された場所を示すバウンディングボックスのデータが含まれます。サンプルコードでは、返されるデータは、以下に示すようにObjectPredictionオブジェクトのリストとしてフォーマットされます。(コードリファレンス

val predictions get() = (0 until OBJECT_COUNT).map {
   ObjectPrediction(

       // The locations are an array of [0, 1] floats for [top, left, bottom, right]
       location = locations[0][it].let {
           RectF(it[1], it[0], it[3], it[2])
       },

       // SSD Mobilenet V1 Model assumes class 0 is background class
       // in label file and class labels start from 1 to number_of_classes + 1,
       // while outputClasses correspond to class index from 0 to number_of_classes
       label = labels[1 + labelIndices[0][it].toInt()],

       // Score is a single value of [0, 1]
       score = scores[0][it]
   )
}

オブジェクト検出のスクリーンショットこの例で使用されているモデルの場合、各予測には、オブジェクトのバウンディングボックスの場所、オブジェクトのラベル、および予測の信頼度を表すフロートとして0〜1の予測スコアが含まれます。1が最高の信頼度です。 。一般に、スコアが50%(0.5)未満の予測は決定的ではないと見なされます。ただし、価値の低い予測結果をどのように処理するかは、ユーザーとアプリケーションのニーズに依存します。

モデルが予測結果を返すと、アプリケーションは、結果をユーザーに提示するか、追加のロジックを実行することで、その予測に基づいて行動できます。サンプルコードの場合、アプリケーションは識別されたオブジェクトの周囲に境界ボックスを描画し、画面にクラス名を表示します。詳細については、サンプルコードのCameraActivity.reportPrediction()関数を確認してください。

次のステップ

  • でTensorFlowLiteのさまざまな使用法を探ります。
  • モデルセクションで、TensorFlowLiteで機械学習モデルを使用する方法の詳細をご覧ください。
  • TensorFlow Lite開発者ガイドで、モバイルアプリケーションに機械学習を実装する方法の詳細をご覧ください。