หากแอปใช้โมเดล TensorFlow Lite ที่กำหนดเอง คุณจะใช้ Firebase ML เพื่อติดตั้งใช้งานโมเดลได้ การ ติดตั้งใช้งานโมเดลด้วย Firebase จะช่วยลดขนาดการดาวน์โหลดเริ่มต้นของ แอปและอัปเดตโมเดล ML ของแอปได้โดยไม่ต้องเผยแพร่แอปเวอร์ชันใหม่ นอกจากนี้ Remote Config และ A/B Testing ยังช่วยให้คุณแสดงโมเดลที่แตกต่างกันต่อผู้ใช้กลุ่มต่างๆ ได้แบบไดนามิก
โมเดล TensorFlow Lite
โมเดล TensorFlow Lite คือโมเดล ML ที่ได้รับการเพิ่มประสิทธิภาพให้ทำงานบนอุปกรณ์เคลื่อนที่ ได้ วิธีรับโมเดล TensorFlow Lite
- ใช้โมเดลที่สร้างไว้ล่วงหน้า เช่น โมเดลใดโมเดลหนึ่งในโมเดล TensorFlow Lite อย่างเป็นทางการ
 - แปลง โมเดล TensorFlow, โมเดล Keras หรือฟังก์ชันที่เฉพาะเจาะจงเป็น TensorFlow Lite
 
ก่อนเริ่มต้น
- เพิ่ม Firebase ลงในโปรเจ็กต์ Android หากยังไม่ได้เพิ่ม
 - 
    
    
    
    
    
    
    
    
    
    
    
    
ในไฟล์ Gradle ของโมดูล (ระดับแอป)
(โดยมากจะเป็น 
<project>/<app-module>/build.gradle.ktsหรือ<project>/<app-module>/build.gradle) ให้เพิ่มทรัพยากร Dependency สำหรับFirebase MLคลังตัวดาวน์โหลดโมเดลสำหรับ Android เราขอแนะนำให้ใช้ Firebase Android BoM เพื่อควบคุมการควบคุมเวอร์ชันของไลบรารีนอกจากนี้ คุณต้องเพิ่ม TensorFlow Lite SDK ลงในแอปด้วย ซึ่งเป็นส่วนหนึ่งของการตั้งค่าFirebase MLโปรแกรมดาวน์โหลดโมเดล
dependencies { // Import the BoM for the Firebase platform implementation(platform("com.google.firebase:firebase-bom:34.5.0")) // Add 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 add 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 { // Add 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:26.0.1")
// Also add the dependency for the TensorFlow Lite library and specify its version implementation("org.tensorflow:tensorflow-lite:2.3.0") } - ในไฟล์ Manifest ของแอป ให้ประกาศว่าต้องมีสิทธิ์ INTERNET
    
<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 MLSDK เพื่อดาวน์โหลดโมเดลเวอร์ชันล่าสุดลงในอุปกรณ์ก่อน จากนั้นสร้างอินสแตนซ์ของ ล่าม TensorFlow Lite ด้วยโมเดลหากต้องการเริ่มดาวน์โหลดโมเดล ให้เรียกใช้เมธอด getModel() ของโปรแกรมดาวน์โหลดโมเดล
โดยระบุชื่อที่คุณกำหนดให้กับโมเดลเมื่ออัปโหลด รวมถึงระบุว่าคุณ
ต้องการดาวน์โหลดโมเดลล่าสุดเสมอหรือไม่ และเงื่อนไขที่คุณ
ต้องการอนุญาตให้ดาวน์โหลด
คุณเลือกลักษณะการดาวน์โหลดได้ 3 แบบ ดังนี้
| ประเภทการดาวน์โหลด | คำอธิบาย | 
|---|---|
| LOCAL_MODEL | รับโมเดลในเครื่องจากอุปกรณ์
หากไม่มีโมเดลในเครื่อง ฟีเจอร์นี้จะทำงานเหมือน LATEST_MODEL ใช้
ประเภทการดาวน์โหลดนี้หากคุณไม่สนใจ
ตรวจสอบการอัปเดตโมเดล เช่น
คุณใช้การกำหนดค่าระยะไกลเพื่อดึงข้อมูล
ชื่อโมเดล และอัปโหลดโมเดล
ภายใต้ชื่อใหม่เสมอ (แนะนํา) | 
| LOCAL_MODEL_UPDATE_IN_BACKGROUND | รับโมเดลในเครื่องจากอุปกรณ์และ
เริ่มอัปเดตโมเดลในเบื้องหลัง
หากไม่มีโมเดลในเครื่อง ฟีเจอร์นี้จะทำงานเหมือน LATEST_MODEL | 
| LATEST_MODEL | รับรุ่นล่าสุด หากโมเดลในเครื่องเป็น เวอร์ชันล่าสุด ระบบจะแสดงโมเดล ในเครื่อง ไม่เช่นนั้น ให้ดาวน์โหลดโมเดลล่าสุด ลักษณะการทำงานนี้จะบล็อกจนกว่าจะดาวน์โหลด เวอร์ชันล่าสุด (ไม่ แนะนํา) ใช้ลักษณะการทำงานนี้เฉพาะในกรณีที่คุณต้องการเวอร์ชันล่าสุดอย่างชัดเจนเท่านั้น | 
คุณควรปิดใช้ฟังก์ชันที่เกี่ยวข้องกับโมเดล เช่น ทำให้เป็นสีเทาหรือซ่อนส่วนหนึ่งของ UI จนกว่าจะยืนยันว่าดาวน์โหลดโมเดลแล้ว
Kotlin
val conditions = CustomModelDownloadConditions.Builder()
        .requireWifi()  // Also possible: .requireCharging() and .requireDeviceIdle()
        .build()
FirebaseModelDownloader.getInstance()
        .getModel("your_model", DownloadType.LOCAL_MODEL_UPDATE_IN_BACKGROUND,
            conditions)
        .addOnSuccessListener { model: 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.
            val modelFile = model?.file
            if (modelFile != null) {
                interpreter = Interpreter(modelFile)
            }
        }
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);
        }
      }
    });
แอปจำนวนมากจะเริ่มงานดาวน์โหลดในโค้ดการเริ่มต้น แต่คุณสามารถทำได้ทุกเมื่อก่อนที่จะต้องใช้โมเดล
3. ทำการอนุมานในข้อมูลอินพุต
รับรูปร่างอินพุตและเอาต์พุตของโมเดล
ตัวแปลโมเดล TensorFlow Lite รับอาร์เรย์หลายมิติอย่างน้อย 1 รายการเป็นอินพุตและสร้างเป็นเอาต์พุต
 อาร์เรย์เหล่านี้มีค่า 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 ได้ดังตัวอย่างต่อไปนี้
Kotlin
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)
    }
}
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);
    }
}
จากนั้นจัดสรร ByteBuffer ให้มีขนาดใหญ่พอที่จะเก็บเอาต์พุตของโมเดล และ
ส่งบัฟเฟอร์อินพุตและบัฟเฟอร์เอาต์พุตไปยังเมธอด run() ของตัวแปล TensorFlow Lite เช่น สำหรับรูปร่างเอาต์พุตของค่า[1 1000]แบบลอย
Kotlin
val bufferSize = 1000 * java.lang.Float.SIZE / java.lang.Byte.SIZE
val modelOutput = ByteBuffer.allocateDirect(bufferSize).order(ByteOrder.nativeOrder())
interpreter?.run(input, modelOutput)
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
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?
}
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?
}
ภาคผนวก: ความปลอดภัยของโมเดล
ไม่ว่าคุณจะทำให้โมเดล TensorFlow Lite พร้อมใช้งานสำหรับ Firebase ML อย่างไรก็ตาม Firebase ML จะจัดเก็บโมเดลในรูปแบบ protobuf ที่ซีเรียลไลซ์มาตรฐานในที่เก็บข้อมูลในเครื่อง
ในทางทฤษฎี หมายความว่าทุกคนสามารถคัดลอกโมเดลของคุณได้ อย่างไรก็ตาม ในทางปฏิบัติ โมเดลส่วนใหญ่มีความเฉพาะเจาะจงกับแอปพลิเคชันและมีการปกปิดโดยการเพิ่มประสิทธิภาพ ซึ่งทำให้ความเสี่ยงคล้ายกับที่คู่แข่งถอดแยกชิ้นส่วนและนำโค้ดของคุณกลับมาใช้ใหม่ อย่างไรก็ตาม คุณควรทราบถึงความเสี่ยงนี้ก่อนใช้ โมเดลที่กำหนดเองในแอป
ใน Android API ระดับ 21 (Lollipop) ขึ้นไป ระบบจะดาวน์โหลดโมเดลไปยังไดเรกทอรีที่ ยกเว้นจากการสำรองข้อมูลอัตโนมัติ
ใน Android API ระดับ 20 และเก่ากว่า ระบบจะดาวน์โหลดโมเดลไปยังไดเรกทอรี
  ชื่อ com.google.firebase.ml.custom.models ในที่เก็บข้อมูลภายในแบบส่วนตัวของแอป
 หากเปิดใช้การสำรองข้อมูลไฟล์โดยใช้ BackupAgent
  คุณอาจเลือกที่จะยกเว้นไดเรกทอรีนี้