Google is committed to advancing racial equity for Black communities. See how.
หน้านี้ได้รับการแปลโดย Cloud Translation API
Switch to English

ใช้โมเดล TensorFlow Lite ที่กำหนดเองบน Android

หากแอปของคุณใช้ โมเดล TensorFlow Lite ที่ กำหนดเองคุณสามารถใช้ Firebase ML เพื่อทำให้โมเดลของคุณใช้งานได้ ด้วยการปรับใช้โมเดลกับ Firebase คุณสามารถลดขนาดการดาวน์โหลดเริ่มต้นของแอปและอัปเดตโมเดล ML ของแอปได้โดยไม่ต้องปล่อยแอปเวอร์ชันใหม่ และด้วยการกำหนดค่าระยะไกลและการทดสอบ A / B คุณสามารถให้บริการโมเดลที่แตกต่างกันไปยังกลุ่มผู้ใช้ที่แตกต่างกันได้แบบไดนามิก

รุ่น TensorFlow Lite

รุ่น TensorFlow Lite เป็นรุ่น ML ที่ได้รับการปรับให้ทำงานบนอุปกรณ์พกพา ในการรับโมเดล TensorFlow Lite:

ก่อนที่คุณจะเริ่ม

  1. เพิ่ม Firebase ในโปรเจ็กต์ Android ของคุณ หากยังไม่ได้ ทำ
  2. ใช้ Firebase Android BoM ประกาศการอ้างอิงสำหรับไลบรารีตัวดาวน์โหลดโมเดล Firebase ML ใน ไฟล์ Gradle ของ โมดูล (ระดับแอป) (โดยทั่วไปคือ app/build.gradle )

    นอกจากนี้ในการตั้งค่าโปรแกรมดาวน์โหลดโมเดล Firebase ML คุณจะต้องเพิ่ม TensorFlow Lite SDK ลงในแอปของคุณ

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

    เมื่อใช้ Firebase Android BoM แอปของคุณจะใช้ไลบรารี Firebase Android เวอร์ชันที่เข้ากันได้เสมอ

    (ทางเลือก) ประกาศการอ้างอิงไลบรารี Firebase โดยไม่ต้อง ใช้ BoM

    หากคุณเลือกที่จะไม่ใช้ Firebase BoM คุณต้องระบุไลบรารี Firebase แต่ละเวอร์ชันในบรรทัดการอ้างอิง

    โปรดทราบว่าหากคุณใช้ไลบรารี Firebase หลาย ไลบรารีในแอปของคุณเราขอแนะนำอย่างยิ่งให้ใช้ BoM เพื่อจัดการเวอร์ชันไลบรารีซึ่งจะช่วยให้มั่นใจได้ว่าทุกเวอร์ชันจะเข้ากันได้

    dependencies {
        // Declare the dependency for the Firebase ML model downloader library
        // When NOT using the BoM, you must specify versions in Firebase library dependencies
        implementation 'com.google.firebase:firebase-ml-modeldownloader:23.0.0'
    // Also declare the dependency for the TensorFlow Lite library and specify its version implementation 'org.tensorflow:tensorflow-lite:2.3.0'
    }
  3. ในรายการแอปของคุณประกาศว่าจำเป็นต้องได้รับอนุญาตจากอินเทอร์เน็ต:
    <uses-permission android:name="android.permission.INTERNET" />

1. ปรับใช้โมเดลของคุณ

ทำให้โมเดล TensorFlow ที่กำหนดเองใช้งานได้โดยใช้คอนโซล Firebase หรือ Firebase Admin Python และ Node.js SDK ดู ปรับใช้และจัดการโมเดลที่กำหนดเอง

หลังจากที่คุณเพิ่มโมเดลที่กำหนดเองลงในโปรเจ็กต์ Firebase คุณสามารถอ้างอิงโมเดลในแอปของคุณโดยใช้ชื่อที่คุณระบุ คุณสามารถปรับใช้โมเดล TensorFlow Lite ใหม่ได้ตลอดเวลาและดาวน์โหลดโมเดลใหม่ลงในอุปกรณ์ของผู้ใช้โดยเรียกใช้ getModel() (ดูด้านล่าง)

2. ดาวน์โหลดโมเดลลงในอุปกรณ์และเริ่มต้นล่าม TensorFlow Lite

หากต้องการใช้โมเดล TensorFlow Lite ในแอปก่อนอื่นให้ใช้ Firebase ML SDK เพื่อดาวน์โหลดรุ่นล่าสุดลงในอุปกรณ์ จากนั้นสร้างอินสแตนซ์ล่าม TensorFlow Lite กับโมเดล

ในการเริ่มการดาวน์โหลดโมเดลให้เรียกใช้ getModel() ของผู้ดาวน์โหลดโมเดลโดยระบุชื่อที่คุณกำหนดโมเดลเมื่อคุณอัปโหลดไม่ว่าคุณต้องการดาวน์โหลดโมเดลล่าสุดเสมอหรือไม่และเงื่อนไขที่คุณต้องการอนุญาตให้ดาวน์โหลด

คุณสามารถเลือกพฤติกรรมการดาวน์โหลดได้สามแบบ:

ประเภทการดาวน์โหลด คำอธิบาย
LOCAL_MODEL รับโมเดลท้องถิ่นจากอุปกรณ์ หากไม่มีโมเดลในเครื่องจะทำงานเหมือน LATEST_MODEL ใช้ประเภทการดาวน์โหลดนี้หากคุณไม่สนใจที่จะตรวจสอบการอัปเดตโมเดล ตัวอย่างเช่นคุณกำลังใช้การกำหนดค่าระยะไกลเพื่อดึงชื่อรุ่นและคุณอัปโหลดโมเดลภายใต้ชื่อใหม่เสมอ (แนะนำ)
LOCAL_MODEL_UPDATE_IN_BACKGROUND รับโมเดลในเครื่องจากอุปกรณ์และเริ่มอัปเดตโมเดลในพื้นหลัง หากไม่มีโมเดลในเครื่องจะทำงานเหมือน LATEST_MODEL
LATEST_MODEL รับรุ่นใหม่ล่าสุด หากโมเดลโลคัลเป็นเวอร์ชันล่าสุดให้ส่งคืนโมเดลโลคัล มิฉะนั้นให้ดาวน์โหลดรุ่นล่าสุด ลักษณะการทำงานนี้จะบล็อกจนกว่าจะดาวน์โหลดเวอร์ชันล่าสุด (ไม่แนะนำ) ใช้ลักษณะการทำงานนี้เฉพาะในกรณีที่คุณต้องการเวอร์ชันล่าสุดอย่างชัดเจน

คุณควรปิดใช้งานฟังก์ชันที่เกี่ยวข้องกับโมเดลตัวอย่างเช่นเป็นสีเทาหรือซ่อนบางส่วนของ UI ของคุณจนกว่าคุณจะยืนยันว่ามีการดาวน์โหลดโมเดลแล้ว

Java

CustomModelDownloadConditions conditions = new CustomModelDownloadConditions.Builder()
    .requireWifi()  // Also possible: .requireCharging() and .requireDeviceIdle()
    .build();
FirebaseModelDownloader.getInstance()
    .getModel("your_model", DownloadType.LOCAL_MODEL_UPDATE_IN_BACKGROUND, conditions)
    .addOnSuccessListener(new OnSuccessListener<CustomModel>() {
      @Override
      public void onSuccess(CustomModel model) {
        // Download complete. Depending on your app, you could enable the ML
        // feature, or switch from the local model to the remote model, etc.

        // The CustomModel object contains the local path of the model file,
        // which you can use to instantiate a TensorFlow Lite interpreter.
        File modelFile = model.getFile();
        if (modelFile != null) {
            interpreter = new Interpreter(modelFile);
        }
      }
    });

โคตรลิน + KTX

val conditions = CustomModelDownloadConditions.Builder()
        .requireWifi()  // Also possible: .requireCharging() and .requireDeviceIdle()
        .build()
FirebaseModelDownloader.getInstance()
        .getModel("your_model", DownloadType.LOCAL_MODEL_UPDATE_IN_BACKGROUND,
            conditions)
        .addOnSuccessListener { customModel ->
            // Download complete. Depending on your app, you could enable the ML
            // feature, or switch from the local model to the remote model, etc.

            // The CustomModel object contains the local path of the model file,
            // which you can use to instantiate a TensorFlow Lite interpreter.
            .addOnSuccessListener { model: CustomModel? ->
                val modelFile = model?.file
                if (modelFile != null) {
                    interpreter = Interpreter(modelFile)
                }
        }

แอพจำนวนมากเริ่มงานดาวน์โหลดในรหัสเริ่มต้น แต่คุณสามารถทำได้เมื่อใดก็ได้ก่อนที่คุณจะต้องใช้โมเดล

3. ทำการอนุมานข้อมูลอินพุต

รับรูปทรงอินพุตและเอาต์พุตของโมเดลของคุณ

ตัวแปลโมเดล TensorFlow Lite ใช้เป็นอินพุตและสร้างเป็นเอาต์พุตอาร์เรย์หลายมิติอย่างน้อยหนึ่งอาร์เรย์ อาร์เรย์เหล่านี้ประกอบด้วยค่า byte , int , long หรือ float ก่อนที่คุณจะสามารถส่งผ่านข้อมูลไปยังโมเดลหรือใช้ผลลัพธ์ได้คุณต้องทราบจำนวนและขนาด ("รูปร่าง") ของอาร์เรย์ที่โมเดลของคุณใช้

หากคุณสร้างโมเดลด้วยตัวเองหรือหากรูปแบบอินพุตและเอาต์พุตของโมเดลเป็นเอกสารแสดงว่าคุณอาจมีข้อมูลนี้อยู่แล้ว หากคุณไม่ทราบรูปร่างและประเภทข้อมูลของอินพุตและเอาต์พุตของโมเดลคุณสามารถใช้ตัวแปล TensorFlow Lite เพื่อตรวจสอบโมเดลของคุณ ตัวอย่างเช่น:

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']))

ตัวอย่างผลลัพธ์:

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

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

เรียกใช้ล่าม

หลังจากที่คุณกำหนดรูปแบบของอินพุตและเอาต์พุตของโมเดลของคุณแล้วให้รับข้อมูลอินพุตของคุณและทำการแปลงใด ๆ กับข้อมูลที่จำเป็นเพื่อให้ได้อินพุตที่มีรูปร่างที่เหมาะสมสำหรับโมเดลของคุณ

ตัวอย่างเช่นหากคุณมีรูปแบบการจัดหมวดหมู่รูปภาพที่มีรูปร่างอินพุตเป็น [1 224 224 3] ค่าทศนิยมคุณสามารถสร้าง ByteBuffer อินพุตจากอ็อบเจ็กต์ Bitmap ดังที่แสดงในตัวอย่างต่อไปนี้:

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

โคตรลิน + 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)
    }
}

จากนั้นจัดสรร ByteBuffer ใหญ่พอที่จะมีเอาต์พุตของโมเดลและส่งบัฟเฟอร์อินพุตและบัฟเฟอร์เอาต์พุตไปยังเมธอด run() ของล่าม TensorFlow Lite ตัวอย่างเช่นสำหรับรูปร่างผลลัพธ์ของค่าทศนิยม [1 1000] :

Java

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

โคตรลิน + KTX

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

วิธีใช้เอาต์พุตขึ้นอยู่กับรุ่นที่คุณใช้

ตัวอย่างเช่นหากคุณกำลังดำเนินการจัดหมวดหมู่ในขั้นตอนต่อไปคุณอาจจับคู่ดัชนีของผลลัพธ์กับป้ายกำกับที่แสดง:

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

โคตรลิน + 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?
}

ภาคผนวก: ความปลอดภัยของโมเดล

ไม่ว่าคุณจะทำให้โมเดล TensorFlow Lite พร้อมใช้งานกับ Firebase ML อย่างไร Firebase ML จะจัดเก็บโมเดลเหล่านี้ไว้ในรูปแบบ protobuf แบบอนุกรมมาตรฐานในพื้นที่จัดเก็บในตัวเครื่อง

ตามทฤษฎีหมายความว่าใคร ๆ ก็ลอกแบบของคุณได้ อย่างไรก็ตามในทางปฏิบัติโมเดลส่วนใหญ่มีลักษณะเฉพาะของแอปพลิเคชันและถูกทำให้สับสนโดยการปรับให้เหมาะสมซึ่งความเสี่ยงจะคล้ายกับของคู่แข่งที่ถอดชิ้นส่วนและนำโค้ดของคุณกลับมาใช้ใหม่ อย่างไรก็ตามคุณควรตระหนักถึงความเสี่ยงนี้ก่อนที่จะใช้โมเดลที่กำหนดเองในแอปของคุณ

ใน Android API ระดับ 21 (Lollipop) และใหม่กว่าโมเดลจะถูกดาวน์โหลดไปยังไดเร็กทอรีที่ ไม่รวม อยู่ใน การสำรองข้อมูลอัตโนมัติ

ใน Android API ระดับ 20 ขึ้นไปโมเดลจะดาวน์โหลดไปยังไดเร็กทอรีชื่อ com.google.firebase.ml.custom.models ในที่จัดเก็บข้อมูลภายในส่วนตัวของแอป หากคุณเปิดใช้งานการสำรองไฟล์โดยใช้ BackupAgent คุณอาจเลือกที่จะไม่รวมไดเร็กทอรีนี้