LiteRT サポート ライブラリを使用して入出力データを処理する

モバイルアプリのデベロッパーは通常、型付きオブジェクト( 整数などのプリミティブ型に変換できますただし、LiteRT インタープリタは オンデバイスの ML モデルを実行する API では、次の形式のテンソルが使用されます。 ByteBuffer には、デバッグや操作が難しいことがあります。「 LiteRT Android サポート ライブラリ LiteRT モデルの入力と出力の処理を支援するように設計されています。 LiteRT インタープリタを使いやすくします。

スタートガイド

Gradle 依存関係とその他の設定をインポートする

.tflite モデルファイルを Android モジュールのアセット ディレクトリにコピーします。 モデルを実行する場所を指定しますファイルを圧縮しないように指定する。 LiteRT ライブラリをモジュールの build.gradle ファイルに追加します。

android {
    // Other settings

    // Specify tflite file should not be compressed for the app apk
    aaptOptions {
        noCompress "tflite"
    }

}

dependencies {
    // Other dependencies

    // Import tflite dependencies
    implementation 'org.tensorflow:tensorflow-lite:0.0.0-nightly-SNAPSHOT'
    // The GPU delegate library is optional. Depend on it as needed.
    implementation 'com.google.ai.edge.litert:litert-gpu:0.0.0-nightly-SNAPSHOT'
    implementation 'com.google.ai.edge.litert:litert-support:0.0.0-nightly-SNAPSHOT'
}

詳しくは、 MavenCentral でホストされる LiteRT サポート ライブラリ AAR サポート ライブラリのバージョンごとに確認できます。

基本的な画像操作と変換

LiteRT サポート ライブラリには、基本的な画像操作のスイートが用意されています。 メソッド(切り抜きやサイズ変更など)があります。これを使用するには、ImagePreprocessor を作成して、 必要なオペレーションを追加します。画像をテンソル形式に変換すること (LiteRT インタープリタに必要な場合)は、使用する TensorImage を作成します。 :

import org.tensorflow.lite.DataType;
import org.tensorflow.lite.support.image.ImageProcessor;
import org.tensorflow.lite.support.image.TensorImage;
import org.tensorflow.lite.support.image.ops.ResizeOp;

// Initialization code
// Create an ImageProcessor with all ops required. For more ops, please
// refer to the ImageProcessor Architecture section in this README.
ImageProcessor imageProcessor =
    new ImageProcessor.Builder()
        .add(new ResizeOp(224, 224, ResizeOp.ResizeMethod.BILINEAR))
        .build();

// Create a TensorImage object. This creates the tensor of the corresponding
// tensor type (uint8 in this case) that the LiteRT interpreter needs.
TensorImage tensorImage = new TensorImage(DataType.UINT8);

// Analysis code for every frame
// Preprocess the image
tensorImage.load(bitmap);
tensorImage = imageProcessor.process(tensorImage);

テンソルの DataType は、 メタデータ エクストラクタ ライブラリ その他のモデル情報が含まれます。

基本的な音声データ処理

LiteRT サポート ライブラリでは、TensorAudio クラスのラッピングも定義されています。 いくつか紹介します。通常は AudioRecord リングバッファに格納されます

import android.media.AudioRecord;
import org.tensorflow.lite.support.audio.TensorAudio;

// Create an `AudioRecord` instance.
AudioRecord record = AudioRecord(...)

// Create a `TensorAudio` object from Android AudioFormat.
TensorAudio tensorAudio = new TensorAudio(record.getFormat(), size)

// Load all audio samples available in the AudioRecord without blocking.
tensorAudio.load(record)

// Get the `TensorBuffer` for inference.
TensorBuffer buffer = tensorAudio.getTensorBuffer()

出力オブジェクトを作成してモデルを実行する

モデルを実行する前に、モデルを実行するコンテナ オブジェクトを作成する必要があります。 結果を保存します。

import org.tensorflow.lite.DataType;
import org.tensorflow.lite.support.tensorbuffer.TensorBuffer;

// Create a container for the result and specify that this is a quantized model.
// Hence, the 'DataType' is defined as UINT8 (8-bit unsigned integer)
TensorBuffer probabilityBuffer =
    TensorBuffer.createFixedSize(new int[]{1, 1001}, DataType.UINT8);

モデルを読み込んで推論を実行する:

import java.nio.MappedByteBuffer;
import org.tensorflow.lite.InterpreterFactory;
import org.tensorflow.lite.InterpreterApi;

// Initialise the model
try{
    MappedByteBuffer tfliteModel
        = FileUtil.loadMappedFile(activity,
            "mobilenet_v1_1.0_224_quant.tflite");
    InterpreterApi tflite = new InterpreterFactory().create(
        tfliteModel, new InterpreterApi.Options());
} catch (IOException e){
    Log.e("tfliteSupport", "Error reading model", e);
}

// Running inference
if(null != tflite) {
    tflite.run(tImage.getBuffer(), probabilityBuffer.getBuffer());
}

結果へのアクセス

デベロッパーは probabilityBuffer.getFloatArray()。モデルが量子化出力を生成する場合、 結果の変換を忘れないでください。MobileNet の量子化モデルでは、開発者は それぞれの出力値を 255 で割って、 カテゴリごとに 0(最も低い)~ 1(最も可能性が高い)です。

省略可: 結果をラベルにマッピングする

必要に応じて、結果をラベルにマッピングすることもできます。まず、このファイルのテキストを モジュールの assets ディレクトリにコピーします。次に、ラベルを読み込みます。 次のコードを使用します。

import org.tensorflow.lite.support.common.FileUtil;

final String ASSOCIATED_AXIS_LABELS = "labels.txt";
List<String> associatedAxisLabels = null;

try {
    associatedAxisLabels = FileUtil.loadLabels(this, ASSOCIATED_AXIS_LABELS);
} catch (IOException e) {
    Log.e("tfliteSupport", "Error reading label file", e);
}

次のスニペットは、確率を結合する方法を示しています。 カテゴリラベル:

import java.util.Map;
import org.tensorflow.lite.support.common.TensorProcessor;
import org.tensorflow.lite.support.common.ops.NormalizeOp;
import org.tensorflow.lite.support.label.TensorLabel;

// Post-processor which dequantize the result
TensorProcessor probabilityProcessor =
    new TensorProcessor.Builder().add(new NormalizeOp(0, 255)).build();

if (null != associatedAxisLabels) {
    // Map of labels and their corresponding probability
    TensorLabel labels = new TensorLabel(associatedAxisLabels,
        probabilityProcessor.process(probabilityBuffer));

    // Create a map to access the result based on label
    Map<String, Float> floatMap = labels.getMapWithFloatValue();
}

現在のユースケースの適用範囲

LiteRT サポート ライブラリの現行バージョンは、以下の機能をサポートしています。

  • 一般的なデータ型(float、uint8、images、audio、これらのオブジェクトの配列) 入力と出力として使用できます。
  • 基本的な画像操作(画像の切り抜き、サイズ変更、回転)。
  • 正規化と量子化
  • ファイル ユーティリティ

今後のバージョンでは、テキスト関連アプリケーションのサポートを改善する予定です。

ImageProcessor のアーキテクチャ

ImageProcessor の設計により、画像操作オペレーションで次のことが可能になりました。 事前に定義してビルドプロセス中に最適化できますImageProcessor 現在、3 つの基本的な前処理オペレーションをサポートしています。 次のコード スニペットに 3 つのコメントが含まれています。

import org.tensorflow.lite.support.common.ops.NormalizeOp;
import org.tensorflow.lite.support.common.ops.QuantizeOp;
import org.tensorflow.lite.support.image.ops.ResizeOp;
import org.tensorflow.lite.support.image.ops.ResizeWithCropOrPadOp;
import org.tensorflow.lite.support.image.ops.Rot90Op;

int width = bitmap.getWidth();
int height = bitmap.getHeight();

int size = height > width ? width : height;

ImageProcessor imageProcessor =
    new ImageProcessor.Builder()
        // Center crop the image to the largest square possible
        .add(new ResizeWithCropOrPadOp(size, size))
        // Resize using Bilinear or Nearest neighbour
        .add(new ResizeOp(224, 224, ResizeOp.ResizeMethod.BILINEAR));
        // Rotation counter-clockwise in 90 degree increments
        .add(new Rot90Op(rotateDegrees / 90))
        .add(new NormalizeOp(127.5, 127.5))
        .add(new QuantizeOp(128.0, 1/128.0))
        .build();

詳細を表示 こちら 正規化と量子化です

サポート ライブラリの最終的な目標は、 tf.image 必要があります。つまり、変換は TensorFlow と同じになります。 実装はオペレーティングシステムに依存しません

開発者はカスタム プロセッサを作成することもできます。これは、 トレーニング プロセスに合わせて調整する必要があります。つまり、 トレーニングと推論の両方に前処理を適用して、 実現できます。

量子化

TensorImageTensorBuffer などの入力オブジェクトや出力オブジェクトを開始する場合 型を DataType.UINT8 または DataType.FLOAT32 に指定する必要があります。

TensorImage tensorImage = new TensorImage(DataType.UINT8);
TensorBuffer probabilityBuffer =
    TensorBuffer.createFixedSize(new int[]{1, 1001}, DataType.UINT8);

TensorProcessor を使用して、入力テンソルを量子化したり、出力を逆量子化したりできます。 テンソルです。たとえば、量子化された出力 TensorBuffer を処理する場合、 デベロッパーは DequantizeOp を使用して、結果を浮動小数点数に逆量子化できる 0 と 1 の間の確率:

import org.tensorflow.lite.support.common.TensorProcessor;

// Post-processor which dequantize the result
TensorProcessor probabilityProcessor =
    new TensorProcessor.Builder().add(new DequantizeOp(0, 1/255.0)).build();
TensorBuffer dequantizedBuffer = probabilityProcessor.process(probabilityBuffer);

テンソルの量子化パラメータは、 メタデータ エクストラクタ ライブラリ