หากแอปใช้โมเดล 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.19.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 แต่ละรายการ ในบรรทัดทรัพยากร Dependency
โปรดทราบว่าหากคุณใช้ไลบรารี 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.1.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 ML SDK เพื่อดาวน์โหลดโมเดลเวอร์ชันล่าสุดลงในอุปกรณ์ก่อน จากนั้นสร้างอินสแตนซ์ของ ล่าม 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 Interpreter เพื่อตรวจสอบโมเดลได้ เช่น
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,
คุณอาจเลือกยกเว้นไดเรกทอรีนี้