Google cam kết thúc đẩy công bằng chủng tộc cho Cộng đồng người da đen. Xem cách thực hiện.
Trang này được dịch bởi Cloud Translation API.
Switch to English

Sử dụng mô hình TensorFlow Lite tùy chỉnh trên Android

Nếu ứng dụng của bạn sử dụng các mô hình TensorFlow Lite tùy chỉnh, bạn có thể sử dụng Firebase ML để triển khai các mô hình của mình. Bằng cách triển khai các mô hình với Firebase, bạn có thể giảm kích thước tải xuống ban đầu của ứng dụng và cập nhật các mô hình ML của ứng dụng mà không cần phát hành phiên bản mới của ứng dụng. Và, với Cấu hình từ xa và Kiểm tra A / B, bạn có thể phân phối động các mô hình khác nhau cho các nhóm người dùng khác nhau.

Mô hình TensorFlow Lite

Mô hình TensorFlow Lite là mô hình ML được tối ưu hóa để chạy trên thiết bị di động. Để có được mô hình TensorFlow Lite:

Trước khi bắt đầu

  1. Nếu bạn chưa có, hãy thêm Firebase vào dự án Android của bạn .
  2. Sử dụng Firebase Android BoM , khai báo phần phụ thuộc cho thư viện Mô hình tùy chỉnh Firebase ML Android trong tệp Gradle mô-đun (cấp ứng dụng) của bạn (thường là app/build.gradle ).

    Ngoài ra, là một phần của việc thiết lập Mô hình tùy chỉnh Firebase ML, bạn cần thêm TensorFlow Lite SDK vào ứng dụng của mình.

    dependencies {
        // Import the BoM for the Firebase platform
        implementation platform('com.google.firebase:firebase-bom:26.3.0')
    
        // Declare the dependency for the Firebase ML Custom Models library
        // When using the BoM, you don't specify versions in Firebase library dependencies
        implementation 'com.google.firebase:firebase-ml-model-interpreter'
    // Also declare the dependency for the TensorFlow Lite library and specify its version implementation 'org.tensorflow:tensorflow-lite:2.3.0'
    }

    Bằng cách sử dụng Firebase Android BoM , ứng dụng của bạn sẽ luôn sử dụng các phiên bản tương thích của thư viện Firebase Android.

    (Thay thế) Khai báo các phụ thuộc thư viện Firebase mà không cần sử dụng BoM

    Nếu bạn chọn không sử dụng Firebase BoM, bạn phải chỉ định từng phiên bản thư viện Firebase trong dòng phụ thuộc của nó.

    Lưu ý rằng nếu bạn sử dụng nhiều thư viện Firebase trong ứng dụng của mình, chúng tôi thực sự khuyên bạn nên sử dụng BoM để quản lý các phiên bản thư viện, điều này đảm bảo rằng tất cả các phiên bản đều tương thích.

    dependencies {
        // Declare the dependency for the Firebase ML Custom Models library
        // When NOT using the BoM, you must specify versions in Firebase library dependencies
        implementation 'com.google.firebase:firebase-ml-model-interpreter:22.0.4'
    // Also declare the dependency for the TensorFlow Lite library and specify its version implementation 'org.tensorflow:tensorflow-lite:2.3.0'
    }
  3. Trong tệp kê khai ứng dụng của bạn, hãy khai báo rằng cần có quyền INTERNET:
    <uses-permission android:name="android.permission.INTERNET" />

1. Triển khai mô hình của bạn

Triển khai các mô hình TensorFlow tùy chỉnh của bạn bằng cách sử dụng bảng điều khiển Firebase hoặc SDK Python và Node.js dành cho quản trị viên Firebase. Xem Triển khai và quản lý các mô hình tùy chỉnh .

Sau khi thêm mô hình tùy chỉnh vào dự án Firebase, bạn có thể tham chiếu mô hình trong ứng dụng của mình bằng tên bạn đã chỉ định. Bất kỳ lúc nào, bạn cũng có thể tải lên mô hình TensorFlow Lite mới và ứng dụng của bạn sẽ tải xuống mô hình mới và bắt đầu sử dụng khi ứng dụng khởi động lại lần sau. Bạn có thể xác định các điều kiện thiết bị cần thiết để ứng dụng của bạn cố gắng cập nhật mô hình (xem bên dưới).

2. Tải mô hình xuống thiết bị

Để sử dụng mô hình TensorFlow Lite trong ứng dụng của bạn, trước tiên, hãy sử dụng SDK Firebase ML để tải phiên bản mới nhất của mô hình xuống thiết bị.

Để bắt đầu tải xuống mô hình, hãy gọi phương thức download() của trình quản lý mô hình, chỉ định tên mà bạn đã gán cho mô hình khi tải lên và các điều kiện mà bạn muốn cho phép tải xuống. Nếu mô hình không có trên thiết bị hoặc nếu có phiên bản mới hơn của mô hình, tác vụ sẽ tải xuống mô hình từ Firebase một cách không đồng bộ.

Bạn nên tắt chức năng liên quan đến mô hình — ví dụ: chuyển sang màu xám hoặc ẩn một phần giao diện người dùng — cho đến khi bạn xác nhận rằng mô hình đã được tải xuống.

Java

FirebaseCustomRemoteModel remoteModel =
      new FirebaseCustomRemoteModel.Builder("your_model").build();
FirebaseModelDownloadConditions conditions = new FirebaseModelDownloadConditions.Builder()
        .requireWifi()
        .build();
FirebaseModelManager.getInstance().download(remoteModel, conditions)
        .addOnSuccessListener(new OnSuccessListener<Void>() {
            @Override
            public void onSuccess(Void v) {
              // Download complete. Depending on your app, you could enable
              // the ML feature, or switch from the local model to the remote
              // model, etc.
            }
        });

Kotlin + KTX

val remoteModel = FirebaseCustomRemoteModel.Builder("your_model").build()
val conditions = FirebaseModelDownloadConditions.Builder()
    .requireWifi()
    .build()
FirebaseModelManager.getInstance().download(remoteModel, conditions)
    .addOnCompleteListener {
        // Download complete. Depending on your app, you could enable the ML
        // feature, or switch from the local model to the remote model, etc.
    }

Nhiều ứng dụng bắt đầu tác vụ tải xuống trong mã khởi tạo của chúng, nhưng bạn có thể làm như vậy bất kỳ lúc nào trước khi cần sử dụng mô hình.

3. Khởi tạo trình thông dịch TensorFlow Lite

Sau khi tải mô hình xuống thiết bị, bạn có thể lấy vị trí tệp mô hình bằng cách gọi phương thức getLatestModelFile() của trình quản lý mô hình. Sử dụng giá trị này để khởi tạo trình thông dịch TensorFlow Lite:

Java

FirebaseCustomRemoteModel remoteModel = new FirebaseCustomRemoteModel.Builder("your_model").build();
FirebaseModelManager.getInstance().getLatestModelFile(remoteModel)
        .addOnCompleteListener(new OnCompleteListener<File>() {
            @Override
            public void onComplete(@NonNull Task<File> task) {
                File modelFile = task.getResult();
                if (modelFile != null) {
                    interpreter = new Interpreter(modelFile);
                }
            }
        });

Kotlin + KTX

val remoteModel = FirebaseCustomRemoteModel.Builder("your_model").build()
FirebaseModelManager.getInstance().getLatestModelFile(remoteModel)
    .addOnCompleteListener { task ->
        val modelFile = task.result
        if (modelFile != null) {
            interpreter = Interpreter(modelFile)
        }
    }

4. Thực hiện suy luận trên dữ liệu đầu vào

Nhận hình dạng đầu vào và đầu ra của mô hình của bạn

Trình thông dịch mô hình TensorFlow Lite nhận làm đầu vào và tạo ra dưới dạng đầu ra một hoặc nhiều mảng đa chiều. Các mảng này chứa các giá trị byte , int , long hoặc float . Trước khi bạn có thể truyền dữ liệu vào một mô hình hoặc sử dụng kết quả của nó, bạn phải biết số lượng và kích thước ("hình dạng") của các mảng mà mô hình của bạn sử dụng.

Nếu bạn tự xây dựng mô hình hoặc nếu định dạng đầu vào và đầu ra của mô hình được ghi lại, bạn có thể đã có thông tin này. Nếu bạn không biết hình dạng và kiểu dữ liệu của đầu vào và đầu ra của mô hình, bạn có thể sử dụng trình thông dịch TensorFlow Lite để kiểm tra mô hình của mình. Ví dụ:

Python

import tensorflow as tf

interpreter = tf.lite.Interpreter(model_path="your_model.tflite")
interpreter.allocate_tensors()

# Print input shape and type
inputs = interpreter.get_input_details()
print('{} input(s):'.format(len(inputs)))
for i in range(0, len(inputs)):
    print('{} {}'.format(inputs[i]['shape'], inputs[i]['dtype']))

# Print output shape and type
outputs = interpreter.get_output_details()
print('\n{} output(s):'.format(len(outputs)))
for i in range(0, len(outputs)):
    print('{} {}'.format(outputs[i]['shape'], outputs[i]['dtype']))

Ví dụ đầu ra:

1 input(s):
[  1 224 224   3] <class 'numpy.float32'>

1 output(s):
[1 1000] <class 'numpy.float32'>

Chạy thông dịch viên

Sau khi bạn đã xác định định dạng của đầu vào và đầu ra của mô hình, hãy lấy dữ liệu đầu vào của bạn và thực hiện bất kỳ biến đổi nào trên dữ liệu cần thiết để có được đầu vào có hình dạng phù hợp cho mô hình của bạn.

Ví dụ: nếu bạn có mô hình phân loại hình ảnh với hình dạng đầu vào là [1 224 224 3] giá trị dấu phẩy động, bạn có thể tạo ByteBuffer đầu vào từ một đối tượng Bitmap như được hiển thị trong ví dụ sau:

Java

Bitmap bitmap = Bitmap.createScaledBitmap(yourInputImage, 224, 224, true);
ByteBuffer input = ByteBuffer.allocateDirect(224 * 224 * 3 * 4).order(ByteOrder.nativeOrder());
for (int y = 0; y < 224; y++) {
    for (int x = 0; x < 224; x++) {
        int px = bitmap.getPixel(x, y);

        // Get channel values from the pixel value.
        int r = Color.red(px);
        int g = Color.green(px);
        int b = Color.blue(px);

        // Normalize channel values to [-1.0, 1.0]. This requirement depends
        // on the model. For example, some models might require values to be
        // normalized to the range [0.0, 1.0] instead.
        float rf = (r - 127) / 255.0f;
        float gf = (g - 127) / 255.0f;
        float bf = (b - 127) / 255.0f;

        input.putFloat(rf);
        input.putFloat(gf);
        input.putFloat(bf);
    }
}

Kotlin + KTX

val bitmap = Bitmap.createScaledBitmap(yourInputImage, 224, 224, true)
val input = ByteBuffer.allocateDirect(224*224*3*4).order(ByteOrder.nativeOrder())
for (y in 0 until 224) {
    for (x in 0 until 224) {
        val px = bitmap.getPixel(x, y)

        // Get channel values from the pixel value.
        val r = Color.red(px)
        val g = Color.green(px)
        val b = Color.blue(px)

        // Normalize channel values to [-1.0, 1.0]. This requirement depends on the model.
        // For example, some models might require values to be normalized to the range
        // [0.0, 1.0] instead.
        val rf = (r - 127) / 255f
        val gf = (g - 127) / 255f
        val bf = (b - 127) / 255f

        input.putFloat(rf)
        input.putFloat(gf)
        input.putFloat(bf)
    }
}

Sau đó, phân bổ một ByteBuffer đủ lớn để chứa đầu ra của mô hình và chuyển bộ đệm đầu vào và bộ đệm đầu ra cho phương thức run() của trình thông dịch TensorFlow Lite. Ví dụ: đối với hình dạng đầu ra của [1 1000] giá trị dấu phẩy động:

Java

int bufferSize = 1000 * java.lang.Float.SIZE / java.lang.Byte.SIZE;
ByteBuffer modelOutput = ByteBuffer.allocateDirect(bufferSize).order(ByteOrder.nativeOrder());
interpreter.run(input, modelOutput);

Kotlin + KTX

val bufferSize = 1000 * java.lang.Float.SIZE / java.lang.Byte.SIZE
val modelOutput = ByteBuffer.allocateDirect(bufferSize).order(ByteOrder.nativeOrder())
interpreter?.run(input, modelOutput)

Cách bạn sử dụng đầu ra phụ thuộc vào kiểu máy bạn đang sử dụng.

Ví dụ: nếu bạn đang thực hiện phân loại, là bước tiếp theo, bạn có thể ánh xạ các chỉ mục của kết quả với các nhãn mà chúng đại diện:

Java

modelOutput.rewind();
FloatBuffer probabilities = modelOutput.asFloatBuffer();
try {
    BufferedReader reader = new BufferedReader(
            new InputStreamReader(getAssets().open("custom_labels.txt")));
    for (int i = 0; i < probabilities.capacity(); i++) {
        String label = reader.readLine();
        float probability = probabilities.get(i);
        Log.i(TAG, String.format("%s: %1.4f", label, probability));
    }
} catch (IOException e) {
    // File not found?
}

Kotlin + KTX

modelOutput.rewind()
val probabilities = modelOutput.asFloatBuffer()
try {
    val reader = BufferedReader(
            InputStreamReader(assets.open("custom_labels.txt")))
    for (i in probabilities.capacity()) {
        val label: String = reader.readLine()
        val probability = probabilities.get(i)
        println("$label: $probability")
    }
} catch (e: IOException) {
    // File not found?
}

Phụ lục: Quay lại mô hình gói cục bộ

Khi bạn lưu trữ mô hình của mình bằng Firebase, mọi chức năng liên quan đến mô hình sẽ không khả dụng cho đến khi ứng dụng của bạn tải xuống mô hình lần đầu tiên. Đối với một số ứng dụng, điều này có thể ổn, nhưng nếu mô hình của bạn bật chức năng cốt lõi, bạn có thể muốn nhóm một phiên bản của mô hình với ứng dụng của mình và sử dụng phiên bản tốt nhất hiện có. Làm như vậy, bạn có thể đảm bảo các tính năng ML của ứng dụng hoạt động khi mô hình được lưu trữ trên Firebase không khả dụng.

Để kết hợp mô hình TensorFlow Lite với ứng dụng của bạn:

  1. Sao chép tệp mô hình (thường kết thúc bằng .tflite hoặc .lite ) vào thư mục assets/ ứng dụng của bạn. (Bạn có thể cần tạo thư mục trước bằng cách nhấp chuột phải vào app/ thư mục, sau đó nhấp vào Mới> Thư mục> Thư mục tài sản .)

  2. Thêm phần sau vào tệp build.gradle của ứng dụng để đảm bảo Gradle không nén các mô hình khi xây dựng ứng dụng:

    android {
    
        // ...
    
        aaptOptions {
            noCompress "tflite", "lite"
        }
    }
    

Sau đó, sử dụng mô hình gói cục bộ khi mô hình được lưu trữ không khả dụng:

Java

FirebaseCustomRemoteModel remoteModel =
        new FirebaseCustomRemoteModel.Builder("your_model").build();
FirebaseModelManager.getInstance().getLatestModelFile(remoteModel)
        .addOnCompleteListener(new OnCompleteListener<File>() {
            @Override
            public void onComplete(@NonNull Task<File> task) {
                File modelFile = task.getResult();
                if (modelFile != null) {
                    interpreter = new Interpreter(modelFile);
                } else {
                    try {
                        InputStream inputStream = getAssets().open("your_fallback_model.tflite");
                        byte[] model = new byte[inputStream.available()];
                        inputStream.read(model);
                        ByteBuffer buffer = ByteBuffer.allocateDirect(model.length)
                                .order(ByteOrder.nativeOrder());
                        buffer.put(model);
                        interpreter = new Interpreter(buffer);
                    } catch (IOException e) {
                        // File not found?
                    }
                }
            }
        });

Kotlin + KTX

val remoteModel = FirebaseCustomRemoteModel.Builder("your_model").build()
FirebaseModelManager.getInstance().getLatestModelFile(remoteModel)
    .addOnCompleteListener { task ->
        val modelFile = task.result
        if (modelFile != null) {
            interpreter = Interpreter(modelFile)
        } else {
            val model = assets.open("your_fallback_model.tflite").readBytes()
            val buffer = ByteBuffer.allocateDirect(model.size).order(ByteOrder.nativeOrder())
            buffer.put(model)
            interpreter = Interpreter(buffer)
        }
    }

Phụ lục: Bảo mật mô hình

Bất kể cách bạn cung cấp các mô hình TensorFlow Lite của mình cho Firebase ML, Firebase ML lưu trữ chúng ở định dạng protobuf tuần tự tiêu chuẩn trong bộ nhớ cục bộ.

Về lý thuyết, điều này có nghĩa là bất kỳ ai cũng có thể sao chép mô hình của bạn. Tuy nhiên, trên thực tế, hầu hết các mô hình đều dành riêng cho ứng dụng và bị xáo trộn bởi các tối ưu hóa đến mức rủi ro tương tự như rủi ro đối thủ cạnh tranh khi tháo gỡ và sử dụng lại mã của bạn. Tuy nhiên, bạn nên biết về rủi ro này trước khi sử dụng mô hình tùy chỉnh trong ứng dụng của mình.

Trên API Android cấp 21 (Lollipop) và mới hơn, mô hình được tải xuống một thư mục được loại trừ khỏi tính năng sao lưu tự động .

Trên Android API cấp 20 trở lên, mô hình được tải xuống thư mục có tên com.google.firebase.ml.custom.models trong bộ nhớ trong ứng dụng riêng tư. Nếu bạn đã bật tính năng sao lưu tệp bằng BackupAgent , bạn có thể chọn loại trừ thư mục này.