Hari Komunitas ML adalah 9 November! Bergabung dengan kami untuk update dari TensorFlow, JAX, dan lebih Pelajari lebih lanjut

Memproses data masukan dan keluaran dengan Pustaka Dukungan TensorFlow Lite

Pengembang aplikasi seluler biasanya berinteraksi dengan objek yang diketik seperti bitmap atau primitif seperti bilangan bulat. Namun, TensorFlow Lite Interpreter yang menjalankan model machine learning di perangkat menggunakan tensor dalam bentuk ByteBuffer, yang mungkin sulit untuk di-debug dan dimanipulasi. Library Dukungan Android TensorFlow Lite dirancang untuk membantu memproses input dan output model TensorFlow Lite, dan membuat interpreter TensorFlow Lite lebih mudah digunakan.

Mulai

Impor dependensi Gradle dan setelan lainnya

Salin file model .tflite ke direktori aset modul Android tempat model akan dijalankan. Tentukan bahwa file tidak boleh dikompresi, dan tambahkan pustaka TensorFlow Lite ke file build.gradle modul:

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 'org.tensorflow:tensorflow-lite-gpu:0.0.0-nightly-SNAPSHOT'
    implementation 'org.tensorflow:tensorflow-lite-support:0.0.0-nightly-SNAPSHOT'
}

Jelajahi Pustaka Dukungan TensorFlow Lite AAR yang dihosting di MavenCentral untuk berbagai versi Pustaka Dukungan.

Manipulasi dan konversi gambar dasar

Pustaka Dukungan TensorFlow Lite memiliki rangkaian metode manipulasi gambar dasar seperti pangkas dan ubah ukuran. Untuk menggunakannya, buat ImagePreprocessor dan tambahkan operasi yang diperlukan. Untuk mengonversi gambar menjadi format tensor yang diperlukan oleh interpreter TensorFlow Lite, buat TensorImage untuk digunakan sebagai input:

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 TensorFlow Lite interpreter needs.
TensorImage tensorImage = new TensorImage(DataType.UINT8);

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

DataType suatu tensor dapat dibaca melalui pustaka exractor metadata serta informasi model lainnya.

Pemrosesan data audio Baisc

Pustaka Dukungan TensorFlow Lite juga menentukan kelas TensorAudio yang TensorAudio beberapa metode pemrosesan data audio dasar. Ini sebagian besar digunakan bersama dengan AudioRecord dan menangkap sampel audio dalam buffer cincin.

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()

Buat objek keluaran dan jalankan model

Sebelum menjalankan model, kita perlu membuat objek kontainer yang akan menyimpan hasilnya:

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);

Memuat model dan menjalankan inferensi:

import org.tensorflow.lite.support.model.Model;

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

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

Mengakses hasilnya

Pengembang bisa mengakses output secara langsung melalui probabilityBuffer.getFloatArray() . Jika model menghasilkan keluaran terkuantisasi, ingatlah untuk mengonversi hasilnya. Untuk model terkuantisasi MobileNet, pengembang perlu membagi setiap nilai keluaran dengan 255 untuk mendapatkan probabilitas yang berkisar dari 0 (paling tidak mungkin) hingga 1 (kemungkinan besar) untuk setiap kategori.

Opsional: Memetakan hasil ke label

Pengembang juga dapat secara opsional memetakan hasil ke label. Pertama, salin file teks yang berisi label ke dalam direktori aset modul. Selanjutnya, muat file label menggunakan kode berikut:

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);
}

Cuplikan berikut menunjukkan cara mengaitkan probabilitas dengan label kategori:

import org.tensorflow.lite.support.common.TensorProcessor;
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();
}

Cakupan kasus penggunaan saat ini

Versi terbaru Pustaka Dukungan TensorFlow Lite mencakup:

  • tipe data umum (float, uint8, gambar, audio, dan larik objek ini) sebagai input dan output model tflite.
  • operasi gambar dasar (potong gambar, ubah ukuran dan putar).
  • normalisasi dan kuantisasi
  • utilitas file

Versi mendatang akan meningkatkan dukungan untuk aplikasi yang berhubungan dengan teks.

Arsitektur ImageProcessor

Desain ImageProcessor memungkinkan operasi manipulasi gambar ditentukan sebelumnya dan dioptimalkan selama proses pembuatan. ImageProcessor saat ini mendukung tiga operasi prapemrosesan dasar:

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();

Lihat lebih detail di sini tentang normalisasi dan kuantisasi.

Tujuan akhir dari pustaka dukungan adalah untuk mendukung semua transformasi tf.image . Artinya, transformasinya akan sama dengan TensorFlow dan implementasinya tidak bergantung pada sistem operasi.

Pengembang juga dipersilakan untuk membuat prosesor khusus. Dalam kasus ini, penting untuk diselaraskan dengan proses pelatihan - yaitu, pemrosesan awal yang sama harus diterapkan pada pelatihan dan kesimpulan untuk meningkatkan reproduktifitas.

Kuantisasi

Saat memulai objek input atau output seperti TensorImage atau TensorBuffer Anda perlu menentukan tipenya menjadi DataType.UINT8 atau DataType.FLOAT32 .

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

TensorProcessor dapat digunakan untuk mengukur tensor input atau menghapus tensor output. Misalnya, saat memproses TensorBuffer keluaran terkuantisasi, developer dapat menggunakan DequantizeOp untuk DequantizeOp hasil menjadi probabilitas floating point antara 0 dan 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);

Parameter kuantisasi tensor dapat dibaca melalui pustaka exractor metadata .