Pengembang aplikasi seluler biasanya berinteraksi dengan objek yang diketik seperti bitmap atau primitif seperti bilangan bulat. Namun, penafsir LiteRT API yang menjalankan model machine learning pada perangkat menggunakan tensor dalam bentuk ByteBuffer, yang mungkin sulit untuk di-debug dan dimanipulasi. Tujuan Support Library Android LiteRT dirancang untuk membantu memproses input dan {i> output<i} model LiteRT, dan membuat penafsir LiteRT lebih mudah digunakan.
Memulai
Mengimpor 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 library LiteRT 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 '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'
}
Pelajari Ar Library Dukungan LiteRT yang dihosting di MavenCentral untuk berbagai versi Support Library.
Manipulasi dan konversi gambar dasar
LiteRT Support Library memiliki serangkaian
manipulasi gambar dasar
seperti memangkas dan mengubah ukuran. Untuk menggunakannya, buat ImagePreprocessor
dan
menambahkan operasi yang diperlukan. Untuk mengonversi gambar ke dalam format tensor
diperlukan oleh penafsir LiteRT, buat TensorImage
yang akan digunakan
sebagai input:
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
tensor dapat dibaca melalui
library ekstraktor metadata
serta informasi model lainnya.
Pemrosesan data audio dasar
LiteRT Support Library juga menentukan penggabungan class TensorAudio
beberapa metode
pemrosesan data audio dasar. Ini sebagian besar digunakan
bersamaan dengan
AudioRecord
dan merekam sampel audio dalam ring buffer.
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()
Membuat objek output dan menjalankan model
Sebelum menjalankan model, kita perlu membuat objek kontainer yang akan simpan 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 {i>
output<i} secara langsung melalui
probabilityBuffer.getFloatArray()
. Jika model menghasilkan output terkuantisasi,
ingatlah untuk
mengonversi hasilnya. Untuk model terkuantisasi MobileNet, developer
perlu membagi setiap nilai {i>output<i} dengan 255 untuk mendapatkan probabilitas mulai dari
0 (paling tidak mungkin) hingga 1 (kemungkinan besar) untuk setiap kategori.
Opsional: Memetakan hasil ke label
Developer juga dapat memetakan hasil ke label secara opsional. Pertama, salin teks file yang berisi label ke direktori aset modul. Selanjutnya, muat 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 Support Library LiteRT saat ini mencakup:
- tipe data umum (float, uint8, gambar, audio, dan array objek ini) sebagai input dan output model tflite.
- operasi gambar dasar (memangkas gambar, mengubah ukuran, dan memutar).
- normalisasi dan kuantisasi
- utilitas file
Versi mendatang akan meningkatkan dukungan untuk aplikasi terkait teks.
Arsitektur ImageProcessor
Desain ImageProcessor
memungkinkan operasi manipulasi gambar untuk
ditentukan sejak awal dan
dioptimalkan selama proses build. ImageProcessor
saat ini mendukung tiga operasi pra-pemrosesan dasar, sebagaimana dijelaskan dalam
tiga komentar dalam cuplikan kode di bawah ini:
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 detail selengkapnya di sini tentang normalisasi dan kuantisasi.
Tujuan akhir dari pustaka dukungan
adalah untuk mendukung semua
tf.image
transformasi. Ini berarti transformasinya akan sama dengan TensorFlow
dan implementasinya akan
terbebas dari sistem operasi.
Developer juga dipersilakan untuk membuat pemroses kustom. Hal tersebut penting dalam kasus-kasus ini untuk diselaraskan dengan proses pelatihan - yaitu tugas pra-pemrosesan harus diterapkan pada pelatihan dan inferensi untuk meningkatkan kemampuan reproduksi.
Kuantisasi
Saat memulai objek input atau output seperti TensorImage
atau TensorBuffer
Anda harus menentukan jenisnya 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 mengkuantisasi tensor input atau mendekuantisasi output
tensor. Misalnya, saat memproses output terkuantisasi TensorBuffer
,
developer dapat menggunakan DequantizeOp
untuk mendekuantisasi hasil ke floating point
probabilitas 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 library ekstraktor metadata.