Mobil uygulama geliştiricileri genellikle bit eşlemler gibi yazılan nesnelerle veya tamsayılar gibi temel öğelerle etkileşime girer. Ancak cihaz içi makine öğrenimi modelini çalıştıran TensorFlow Lite yorumlayıcı API'si, ByteBuffer formundaki tensörleri kullanır ve bunların hatalarını ayıklamak ve değiştirmek zor olabilir. TensorFlow Lite Android Destek Kitaplığı, TensorFlow Lite modellerinin giriş ve çıkışlarının işlenmesine yardımcı olmak ve TensorFlow Lite yorumlayıcısının kullanımını kolaylaştırmak için tasarlanmıştır.
Başlarken
Gradle bağımlılığını ve diğer ayarları içe aktar
.tflite
model dosyasını, modelin çalıştırılacağı Android modülünün asset 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)'nı keşfedin.
Temel görüntü işleme ve dönüştürme
TensorFlow Lite Destek Kütüphanesi, kırpma ve yeniden boyutlandırma gibi temel görüntü işleme yöntemlerinden oluşan bir pakete sahiptir. Kullanmak 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 formatına dönüştürmek için girdi 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
, diğer model bilgilerinin yanı sıra meta veri çıkarıcı kitaplığı aracılığıyla da okunabilir.
Temel ses verisi işleme
TensorFlow Lite Destek Kitaplığı ayrıca bazı temel ses verisi işleme yöntemlerini kapsayan bir TensorAudio
sınıfını da tanımlar. Çoğunlukla AudioRecord ile birlikte kullanılır ve ses örneklerini bir halka arabelleğinde yakalar.
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()
Çıktı nesneleri oluşturun ve modeli çalıştırın
Modeli çalıştırmadan önce sonucu saklayacak konteyner nesnelerini oluşturmamız gerekiyor:
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);
Modeli 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 çıktıya doğrudan probabilityBuffer.getFloatArray()
aracılığıyla erişebilirler. Model nicelenmiş bir çıktı üretiyorsa sonucu dönüştürmeyi unutmayın. MobileNet kuantize edilmiş modeli için geliştiricinin, her kategori için 0 (en düşük olasılık) ile 1 (en olası) arasında değişen olasılığı elde etmek için her çıktı değerini 255'e bölmesi gerekir.
İsteğe bağlı: Sonuçları etiketlerle eşleme
Geliştiriciler ayrıca isteğe bağlı olarak sonuçları etiketlerle eşleyebilir. Öncelikle etiketleri içeren metin dosyasını modülün varlıklar dizinine kopyalayın. Daha sonra aşağıdaki kodu kullanarak etiket dosyasını 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 kod parçası 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 senaryosu kapsamı
TensorFlow Lite Destek Kitaplığının güncel sürümü şunları kapsar:
- Tflite modellerinin giriş ve çıkışları olarak ortak veri türleri (float, uint8, resimler, ses ve bu nesnelerin dizisi).
- temel görüntü işlemleri (görüntüyü kırpma, yeniden boyutlandırma ve döndürme).
- normalizasyon ve nicemleme
- dosya araçları
Gelecek sürümler metinle ilgili uygulamalara yönelik desteği geliştirecektir.
Görüntü İşlemci Mimarisi
ImageProcessor
tasarımı, görüntü işleme işlemlerinin önceden tanımlanmasına ve oluşturma süreci sırasında optimize edilmesine olanak sağladı. ImageProcessor
şu anda aşağıdaki kod parçacığında yer alan üç yorumda açıklandığı gibi üç 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();
Normalizasyon ve nicemleme hakkında daha fazla ayrıntıyı burada bulabilirsiniz.
Destek kütüphanesinin 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 ayrıca özel işlemciler oluşturabilirler. Bu durumlarda eğitim süreciyle uyumlu hale getirilmesi önemlidir; yani aynı ön işleme, tekrarlanabilirliği artırmak için hem eğitime hem de çıkarıma uygulanmalıdır.
Niceleme
TensorImage
veya TensorBuffer
gibi giriş veya çıkış nesnelerini başlatırken, bunların türlerini DataType.UINT8
veya DataType.FLOAT32
olacak şekilde belirtmeniz gerekir.
TensorImage tensorImage = new TensorImage(DataType.UINT8);
TensorBuffer probabilityBuffer =
TensorBuffer.createFixedSize(new int[]{1, 1001}, DataType.UINT8);
TensorProcessor
giriş tensörlerini nicelemek veya çıkış tensörlerini nicelemek için kullanılabilir. Örneğin, nicelenmiş bir çıktı TensorBuffer
işlerken geliştirici, sonucu 0 ile 1 arasında bir kayan nokta olasılığına göre nicemlemek için DequantizeOp
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 niceleme parametreleri meta veri çıkarıcı kütüphanesi aracılığıyla okunabilir.