Google I / O là một kết quả hoàn hảo! Cập nhật các phiên TensorFlow Xem phiên

Xử lý dữ liệu đầu vào và đầu ra với Thư viện hỗ trợ TensorFlow Lite

Các nhà phát triển ứng dụng dành cho thiết bị di động thường tương tác với các đối tượng đã nhập như bitmap hoặc nguyên thủy như số nguyên. Tuy nhiên, API thông dịch TensorFlow Lite chạy mô hình học máy trên thiết bị sử dụng các tensor ở dạng ByteBuffer, có thể khó gỡ lỗi và thao tác. Thư viện hỗ trợ TensorFlow Lite Android được thiết kế để giúp xử lý đầu vào và đầu ra của các mô hình TensorFlow Lite và làm cho trình thông dịch TensorFlow Lite dễ sử dụng hơn.

Bắt đầu

Nhập sự phụ thuộc của Gradle và các cài đặt khác

Sao chép tệp mô hình .tflite vào thư mục nội dung của mô-đun Android nơi mô hình sẽ được chạy. Chỉ định rằng không nên nén tệp và thêm thư viện TensorFlow Lite vào tệp build.gradle của mô-đun:

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

Khám phá Thư viện hỗ trợ TensorFlow Lite AAR được lưu trữ tại MavenCentral để biết các phiên bản khác nhau của Thư viện hỗ trợ.

Thao tác và chuyển đổi hình ảnh cơ bản

Thư viện hỗ trợ TensorFlow Lite có một bộ các phương pháp thao tác hình ảnh cơ bản như cắt và thay đổi kích thước. Để sử dụng nó, hãy tạo một ImagePreprocessor và thêm các thao tác cần thiết. Để chuyển đổi hình ảnh sang định dạng tensor theo yêu cầu của trình thông dịch TensorFlow Lite, hãy tạo TensorImage để sử dụng làm đầu vào:

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 của tensor có thể được đọc thông qua thư viện trích xuất siêu dữ liệu cũng như thông tin mô hình khác.

Xử lý dữ liệu âm thanh cơ bản

Thư viện hỗ trợ TensorFlow Lite cũng định nghĩa một lớp TensorAudio gói một số phương pháp xử lý dữ liệu âm thanh cơ bản. Nó chủ yếu được sử dụng cùng với AudioRecord và ghi lại các mẫu âm thanh trong bộ đệm chuông.

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

Tạo các đối tượng đầu ra và chạy mô hình

Trước khi chạy mô hình, chúng ta cần tạo các đối tượng vùng chứa sẽ lưu trữ kết quả:

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

Đang tải mô hình và chạy suy luận:

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

Truy cập kết quả

Các nhà phát triển có thể truy cập đầu ra trực tiếp thông qua probabilityBuffer.getFloatArray() . Nếu mô hình tạo ra một đầu ra lượng tử hóa, hãy nhớ chuyển đổi kết quả. Đối với mô hình lượng tử hóa MobileNet, nhà phát triển cần chia mỗi giá trị đầu ra cho 255 để có được xác suất nằm trong khoảng từ 0 (ít khả năng nhất) đến 1 (nhiều khả năng nhất) cho mỗi danh mục.

Tùy chọn: Ánh xạ kết quả với nhãn

Các nhà phát triển cũng có thể tùy chọn ánh xạ kết quả vào nhãn. Đầu tiên, sao chép tệp văn bản có chứa nhãn vào thư mục nội dung của mô-đun. Tiếp theo, tải tệp nhãn bằng mã sau:

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

Đoạn mã sau đây trình bày cách liên kết các xác suất với các nhãn danh mục:

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

Phạm vi trường hợp sử dụng hiện tại

Phiên bản hiện tại của Thư viện hỗ trợ TensorFlow Lite bao gồm:

  • các kiểu dữ liệu phổ biến (float, uint8, hình ảnh, âm thanh và mảng của các đối tượng này) làm đầu vào và đầu ra của mô hình tflite.
  • các thao tác hình ảnh cơ bản (cắt hình ảnh, thay đổi kích thước và xoay).
  • chuẩn hóa và lượng tử hóa
  • tập tin utils

Các phiên bản trong tương lai sẽ cải thiện hỗ trợ cho các ứng dụng liên quan đến văn bản.

Kiến trúc bộ xử lý hình ảnh

Thiết kế của ImageProcessor cho phép các hoạt động xử lý hình ảnh được xác định trước và tối ưu hóa trong quá trình xây dựng. ImageProcessor hiện hỗ trợ ba hoạt động tiền xử lý cơ bản, như được mô tả trong ba nhận xét trong đoạn mã bên dưới:

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

Xem thêm chi tiết tại đây về chuẩn hóa và lượng tử hóa.

Mục tiêu cuối cùng của thư viện hỗ trợ là hỗ trợ tất cả các phép biến đổi tf.image . Điều này có nghĩa là quá trình chuyển đổi sẽ giống như TensorFlow và việc triển khai sẽ độc lập với hệ điều hành.

Các nhà phát triển cũng được hoan nghênh tạo ra các bộ xử lý tùy chỉnh. Trong những trường hợp này, điều quan trọng là phải phù hợp với quá trình đào tạo - tức là cùng một quá trình xử lý trước phải áp dụng cho cả đào tạo và suy luận để tăng khả năng tái lập.

Lượng tử hóa

Khi khởi tạo các đối tượng đầu vào hoặc đầu ra như TensorImage hoặc TensorBuffer , bạn cần chỉ định loại của chúng là DataType.UINT8 hoặc DataType.FLOAT32 .

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

TensorProcessor có thể được sử dụng để lượng tử hóa các tensor đầu vào hoặc dequantize tensors đầu ra. Ví dụ: khi xử lý TensorBuffer đầu ra được lượng tử hóa, nhà phát triển có thể sử dụng DequantizeOp để loại bỏ kết quả thành xác suất dấu phẩy động giữa 0 và 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);

Các tham số lượng tử hóa của tensor có thể được đọc thông qua thư viện trích xuất siêu dữ liệu .