หากแอปของคุณใช้ โมเดล TensorFlow Lite ที่ กำหนดเองคุณสามารถใช้ Firebase ML เพื่อทำให้โมเดลของคุณใช้งานได้ ด้วยการปรับใช้โมเดลกับ Firebase คุณสามารถลดขนาดการดาวน์โหลดเริ่มต้นของแอปและอัปเดตโมเดล ML ของแอปได้โดยไม่ต้องปล่อยแอปเวอร์ชันใหม่ และด้วยการกำหนดค่าระยะไกลและการทดสอบ A / B คุณสามารถให้บริการโมเดลที่แตกต่างกันไปยังกลุ่มผู้ใช้ที่แตกต่างกันได้แบบไดนามิก
รุ่น TensorFlow Lite
รุ่น TensorFlow Lite เป็นรุ่น ML ที่ได้รับการปรับให้ทำงานบนอุปกรณ์พกพา ในการรับโมเดล TensorFlow Lite:
- ใช้โมเดลที่สร้างไว้ล่วงหน้าเช่นรุ่น TensorFlow Lite อย่างเป็นทางการ
- แปลงโมเดล TensorFlow โมเดล Keras หรือฟังก์ชันคอนกรีตเป็น TensorFlow Lite
ก่อนที่คุณจะเริ่ม
- เพิ่ม Firebase ในโปรเจ็กต์ Android ของคุณ หากยังไม่ได้ ทำ
- ใช้ 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' } - ในรายการแอปของคุณประกาศว่าจำเป็นต้องได้รับอนุญาตจากอินเทอร์เน็ต:
<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
คุณอาจเลือกที่จะไม่รวมไดเร็กทอรีนี้