TensorFlow Lite Destek Kitaplığı ile giriş ve çıkış verilerini işleyin

Mobil uygulama geliştiricileri genellikle bit eşlem gibi yazılan nesnelerle veya tamsayılar gibi temel öğelerle etkileşim kurar. Ancak, cihaz üzerinde makine öğrenimi modelini çalıştıran TensorFlow Lite Lighting API'si, hata ayıklaması ve değiştirilmesi zor olabilen ByteBuffer biçiminde tensörler kullanır. TensorFlow Lite Android Destek Kitaplığı, TensorFlow Lite modellerinin giriş ve çıkışlarını işlemeye yardımcı olmak ve TensorFlow Lite yorumlayıcısının daha kolay kullanılmasını sağlamak için tasarlanmıştır.

Başlarken

Gradle bağımlılığını ve diğer ayarları içe aktarma

.tflite model dosyasını, modelin çalıştırılacağı Android modülünün öğe dizinine kopyalayın. Dosyanın sıkıştırılmaması gerektiğini belirtin ve TensorFlow Lite kitaplığını modülün build.gradle dosyasına ekleyin:

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'
}

Destek Kitaplığı'nın farklı sürümleri için MavenCentral'da barındırılan TensorFlow Lite Destek Kitaplığı AAR'sini keşfedin.

Temel görüntü işleme ve dönüştürme

TensorFlow Lite Destek Kitaplığı'nda, kırpma ve yeniden boyutlandırma gibi temel resim işleme yöntemleri bulunur. Kullanabilmek için bir ImagePreprocessor oluşturun ve gerekli işlemleri ekleyin. Görüntüyü TensorFlow Lite yorumlayıcısının gerektirdiği tensör biçimine dönüştürmek için giriş olarak kullanılacak bir TensorImage oluşturun:

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

Bir tensörün DataType değeri, diğer model bilgilerinin yanı sıra meta veri ayıklayıcı kitaplığı üzerinden okunabilir.

Temel ses verilerini işleme

TensorFlow Lite Destek Kitaplığı, bazı temel ses verisi işleme yöntemlerini sarmalayan bir TensorAudio sınıfı da tanımlar. Çoğunlukla AudioRecord ile birlikte kullanılır ve ses örneklerini bir halka arabelleğinde kaydeder.

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

Çıkış nesneleri oluşturma ve modeli çalıştırma

Modeli çalıştırmadan önce sonucu depolayacak container nesnelerini oluşturmamız gerekir:

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

Model yükleme ve çıkarımı çalıştırma:

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

Sonuca erişme

Geliştiriciler çıkışa doğrudan probabilityBuffer.getFloatArray() üzerinden erişebilirler. Model ölçülmüş bir çıktı üretirse sonucu dönüştürmeyi unutmayın. MobileNet sayısallaştırılmış modelde, geliştiricinin her bir kategori için 0 (en az olası) ile 1 (en olası) aralığındaki olasılığı elde etmek üzere her çıktı değerini 255'e bölmesi gerekir.

İsteğe bağlı: Sonuçları etiketlerle eşleme

Geliştiriciler, isteğe bağlı olarak sonuçları etiketlerle de eşleyebilir. Öncelikle, etiketleri içeren metin dosyasını modülün assets dizinine kopyalayın. Ardından, etiket dosyasını aşağıdaki kodu kullanarak yükleyin:

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

Aşağıdaki snippet, olasılıkların kategori etiketleriyle nasıl ilişkilendirileceğini gösterir:

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

Mevcut kullanım alanı kapsamı

TensorFlow Lite Destek Kitaplığı'nın güncel sürümü şunları kapsar:

  • yaygın veri türlerinin (float, uint8, resimler, ses ve bu nesnelerin dizisi) tflite modellerinin girdileri ve çıkışları olarak sunulur.
  • temel resim işlemleri (resmi kırpma, yeniden boyutlandırma ve döndürme) sağlar.
  • normalleştirme ve niceleme
  • dosya yardımcı programları

Gelecekteki sürümler, metinle ilgili uygulamalara yönelik desteği geliştirecektir.

ImageProcessor Mimarisi

ImageProcessor tasarımı, görüntü işleme işlemlerinin önceden tanımlanmasını ve derleme süreci sırasında optimize edilmesini sağladı. ImageProcessor, aşağıdaki kod snippet'indeki üç yorumda da açıklandığı gibi, şu anda üç temel ön işleme işlemini desteklemektedir:

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

Normalleştirme ve niceleme hakkında daha fazla bilgiyi burada bulabilirsiniz.

Destek kitaplığının nihai hedefi tüm tf.image dönüşümlerini desteklemektir. Bu, dönüşümün TensorFlow ile aynı olacağı ve uygulamanın, işletim sisteminden bağımsız olacağı anlamına gelir.

Geliştiriciler özel işlemciler de oluşturabilirler. Bu durumlarda, eğitim süreciyle uyum sağlamak önemlidir. Yani, yeniden oluşturulabilirliği artırmak için hem eğitim hem de çıkarım için aynı ön işleme uygulanmalıdır.

Nicelleştirme

TensorImage veya TensorBuffer gibi giriş ya da çıkış nesnelerini başlatırken bunların türlerini DataType.UINT8 veya DataType.FLOAT32 olarak belirtmeniz gerekir.

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

TensorProcessor, giriş tensörlerinin miktarını belirlemek veya çıkış tensörlerinin miktarını azaltmak için kullanılabilir. Örneğin, nicelenmiş bir çıkışı (TensorBuffer) işlerken geliştirici, sonucu 0 ile 1 arasında bir kayan nokta olasılığına dönüştürmek için DequantizeOp özelliğini kullanabilir:

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

Bir tensörün nicelik parametreleri, meta veri ayıklayıcı kitaplığı üzerinden okunabilir.