Bantuan melindungi Great Barrier Reef dengan TensorFlow pada Kaggle Bergabung Tantangan

Memproses data input dan output dengan Pustaka Dukungan TensorFlow Lite

Pengembang aplikasi seluler biasanya berinteraksi dengan objek yang diketik seperti bitmap atau primitif seperti bilangan bulat. Namun, API penerjemah TensorFlow Lite yang menjalankan model pembelajaran mesin di perangkat menggunakan tensor dalam bentuk ByteBuffer, yang mungkin sulit untuk di-debug dan dimanipulasi. The TensorFlow Lite Android Dukungan Perpustakaan dirancang untuk membantu proses input dan output dari model TensorFlow Lite, dan membuat TensorFlow Lite interpreter lebih mudah untuk digunakan.

Mulai

Impor ketergantungan Gradle dan pengaturan lainnya

Salin .tflite file model ke direktori aset modul Android di mana model akan dijalankan. Menentukan bahwa file tersebut tidak harus dikompresi, dan menambahkan perpustakaan TensorFlow Lite untuk modul build.gradle berkas:

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 TensorFlow Lite Dukungan Perpustakaan AAR host di MavenCentral untuk versi yang berbeda dari Perpustakaan Support.

Manipulasi dan konversi gambar dasar

Pustaka Dukungan TensorFlow Lite memiliki serangkaian metode manipulasi gambar dasar seperti memotong dan mengubah ukuran. Untuk menggunakannya, membuat ImagePreprocessor dan menambahkan operasi yang diperlukan. Untuk mengkonversi gambar ke dalam format tensor diperlukan oleh interpreter TensorFlow Lite, membuat TensorImage untuk digunakan sebagai masukan:

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 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 dari tensor dapat dibaca melalui exractor perpustakaan metadata serta informasi model lainnya.

Pemrosesan data audio dasar

The TensorFlow Lite Dukungan Perpustakaan juga mendefinisikan TensorAudio kelas membungkus beberapa data audio dasar pengolahan metode. Itu sebagian besar digunakan bersama-sama dengan AudioRecord dan menangkap audio sampel dalam buffer cincin.

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

Buat objek keluaran dan jalankan model

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

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

Memuat model dan menjalankan inferensi:

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

Mengakses hasil

Pengembang dapat mengakses output 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 mulai dari 0 (paling tidak mungkin) hingga 1 (paling mungkin) 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 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 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();
}

Cakupan kasus penggunaan saat ini

Versi Pustaka Dukungan TensorFlow Lite saat ini mencakup:

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

Versi mendatang akan meningkatkan dukungan untuk aplikasi terkait teks.

Arsitektur Prosesor Gambar

Desain ImageProcessor memungkinkan operasi manipulasi gambar yang akan ditetapkan di depan dan dioptimalkan selama proses membangun. The ImageProcessor saat ini mendukung tiga operasi preprocessing dasar, seperti yang dijelaskan dalam tiga komentar dalam potongan kode di bawah:

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

Lihat lebih detail di sini tentang normalisasi dan kuantisasi.

Tujuan akhir dari perpustakaan dukungan adalah untuk mendukung semua tf.image transformasi. Ini berarti transformasi 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 pra-pemrosesan yang sama harus diterapkan pada pelatihan dan inferensi untuk meningkatkan reproduktifitas.

kuantisasi

Ketika memulai input atau output objek seperti TensorImage atau TensorBuffer Anda perlu menentukan jenis mereka untuk menjadi DataType.UINT8 atau DataType.FLOAT32 .

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

The TensorProcessor dapat digunakan untuk quantize tensor input atau dequantize tensor output. Sebagai contoh, ketika memproses terkuantisasi keluaran TensorBuffer , pengembang dapat menggunakan DequantizeOp untuk dequantize hasilnya ke titik probabilitas floating 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 dari tensor dapat dibaca melalui perpustakaan metadata exractor .