หากแอปใช้โมเดล TensorFlow Lite ที่กำหนดเอง คุณจะใช้ Firebase ML เพื่อติดตั้งใช้งานโมเดลได้ การ ติดตั้งใช้งานโมเดลด้วย Firebase จะช่วยลดขนาดการดาวน์โหลดเริ่มต้นของ แอปและอัปเดตโมเดล ML ของแอปได้โดยไม่ต้องเผยแพร่แอปเวอร์ชันใหม่ นอกจากนี้ Remote Config และ A/B Testing ยังช่วยให้คุณแสดงโมเดลที่แตกต่างกันต่อผู้ใช้กลุ่มต่างๆ ได้แบบไดนามิก
ข้อกำหนดเบื้องต้น
MLModelDownloaderไลบรารีพร้อมใช้งานสำหรับ Swift เท่านั้น- TensorFlow Lite ทำงานได้บนอุปกรณ์ที่ใช้ iOS 9 ขึ้นไปเท่านั้น
โมเดล TensorFlow Lite
โมเดล TensorFlow Lite คือโมเดล ML ที่ได้รับการเพิ่มประสิทธิภาพให้ทำงานบนอุปกรณ์เคลื่อนที่ ได้ วิธีรับโมเดล TensorFlow Lite
- ใช้โมเดลที่สร้างไว้ล่วงหน้า เช่น โมเดลใดโมเดลหนึ่งในโมเดล TensorFlow Lite อย่างเป็นทางการ
- แปลง โมเดล TensorFlow, โมเดล Keras หรือฟังก์ชันที่เฉพาะเจาะจงเป็น TensorFlow Lite
ก่อนเริ่มต้น
หากต้องการใช้ TensorFlow Lite กับ Firebase คุณต้องใช้ CocoaPods เนื่องจาก TensorFlow Lite
ไม่รองรับการติดตั้งด้วย Swift Package Manager ในขณะนี้ ดูวิธีการติดตั้ง MLModelDownloader ได้ในคู่มือการติดตั้ง CocoaPods
เมื่อติดตั้งแล้ว ให้นำเข้า Firebase และ TensorFlow Lite เพื่อใช้งาน
Swift
import FirebaseMLModelDownloader
import TensorFlowLite
1. ทำให้โมเดลใช้งานได้
ติดตั้งใช้งานโมเดล TensorFlow ที่กำหนดเองโดยใช้คอนโซล Firebase หรือ Firebase Admin SDK สำหรับ Python และ Node.js ดูติดตั้งใช้งานและจัดการโมเดลที่กำหนดเอง
หลังจากเพิ่มโมเดลที่กำหนดเองลงในโปรเจ็กต์ Firebase แล้ว คุณจะอ้างอิงโมเดลในแอปโดยใช้ชื่อที่ระบุได้ คุณสามารถติดตั้งใช้งานโมเดล TensorFlow Lite ใหม่และดาวน์โหลดโมเดลใหม่ลงในอุปกรณ์ของผู้ใช้ได้ทุกเมื่อโดยการเรียกใช้ getModel() (ดูด้านล่าง)
2. ดาวน์โหลดโมเดลลงในอุปกรณ์และเริ่มต้นตัวแปล TensorFlow Lite
หากต้องการใช้โมเดล TensorFlow Lite ในแอป ให้ใช้ Firebase MLSDK เพื่อดาวน์โหลดโมเดลเวอร์ชันล่าสุดลงในอุปกรณ์ก่อนหากต้องการเริ่มดาวน์โหลดโมเดล ให้เรียกใช้เมธอด getModel() ของโปรแกรมดาวน์โหลดโมเดล
โดยระบุชื่อที่คุณกำหนดให้กับโมเดลเมื่ออัปโหลด รวมถึงระบุว่าคุณ
ต้องการดาวน์โหลดโมเดลล่าสุดเสมอหรือไม่ และเงื่อนไขที่คุณ
ต้องการอนุญาตให้ดาวน์โหลด
คุณเลือกลักษณะการดาวน์โหลดได้ 3 แบบ ดังนี้
| ประเภทการดาวน์โหลด | คำอธิบาย |
|---|---|
localModel
|
รับโมเดลในเครื่องจากอุปกรณ์
หากไม่มีโมเดลในเครื่อง ฟีเจอร์นี้จะทำงานเหมือน latestModel ใช้
ประเภทการดาวน์โหลดนี้หากคุณไม่สนใจ
ตรวจสอบการอัปเดตโมเดล เช่น
คุณใช้การกำหนดค่าระยะไกลเพื่อดึงข้อมูล
ชื่อโมเดล และอัปโหลดโมเดล
ภายใต้ชื่อใหม่เสมอ (แนะนํา) |
localModelUpdateInBackground
|
รับโมเดลในเครื่องจากอุปกรณ์และ
เริ่มอัปเดตโมเดลในเบื้องหลัง
หากไม่มีโมเดลในเครื่อง ฟีเจอร์นี้จะทำงานเหมือน latestModel |
latestModel
|
รับรุ่นล่าสุด หากโมเดลในเครื่องเป็นเวอร์ชันล่าสุด ระบบจะแสดงโมเดลในเครื่อง ไม่เช่นนั้น ให้ดาวน์โหลดโมเดลล่าสุด ลักษณะการทำงานนี้จะบล็อกจนกว่าจะดาวน์โหลด เวอร์ชันล่าสุด (ไม่ แนะนํา) ใช้ลักษณะการทำงานนี้เฉพาะในกรณีที่คุณต้องการเวอร์ชันล่าสุดอย่างชัดเจนเท่านั้น |
คุณควรปิดใช้ฟังก์ชันที่เกี่ยวข้องกับโมเดล เช่น ทำให้เป็นสีเทาหรือซ่อนส่วนหนึ่งของ UI จนกว่าจะยืนยันว่าดาวน์โหลดโมเดลแล้ว
Swift
let conditions = ModelDownloadConditions(allowsCellularAccess: false)
ModelDownloader.modelDownloader()
.getModel(name: "your_model",
downloadType: .localModelUpdateInBackground,
conditions: conditions) { result in
switch (result) {
case .success(let customModel):
do {
// 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.
let interpreter = try Interpreter(modelPath: customModel.path)
} catch {
// Error. Bad model file?
}
case .failure(let error):
// Download was unsuccessful. Don't enable ML features.
print(error)
}
}
แอปจำนวนมากจะเริ่มงานดาวน์โหลดในโค้ดการเริ่มต้น แต่คุณสามารถทำได้ทุกเมื่อก่อนที่จะต้องใช้โมเดล
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]ค่าจุดลอยตัว คุณอาจต้องปรับขนาดค่าสีของรูปภาพให้เป็นช่วงจุดลอยตัวดังตัวอย่างต่อไปนี้
Swift
let image: CGImage = // Your input image
guard let context = CGContext(
data: nil,
width: image.width, height: image.height,
bitsPerComponent: 8, bytesPerRow: image.width * 4,
space: CGColorSpaceCreateDeviceRGB(),
bitmapInfo: CGImageAlphaInfo.noneSkipFirst.rawValue
) else {
return false
}
context.draw(image, in: CGRect(x: 0, y: 0, width: image.width, height: image.height))
guard let imageData = context.data else { return false }
var inputData = Data()
for row in 0 ..< 224 {
for col in 0 ..< 224 {
let offset = 4 * (row * context.width + col)
// (Ignore offset 0, the unused alpha channel)
let red = imageData.load(fromByteOffset: offset+1, as: UInt8.self)
let green = imageData.load(fromByteOffset: offset+2, as: UInt8.self)
let blue = imageData.load(fromByteOffset: offset+3, as: UInt8.self)
// Normalize channel values to [0.0, 1.0]. This requirement varies
// by model. For example, some models might require values to be
// normalized to the range [-1.0, 1.0] instead, and others might
// require fixed-point values or the original bytes.
var normalizedRed = Float32(red) / 255.0
var normalizedGreen = Float32(green) / 255.0
var normalizedBlue = Float32(blue) / 255.0
// Append normalized values to Data object in RGB order.
let elementSize = MemoryLayout.size(ofValue: normalizedRed)
var bytes = [UInt8](repeating: 0, count: elementSize)
memcpy(&bytes, &normalizedRed, elementSize)
inputData.append(&bytes, count: elementSize)
memcpy(&bytes, &normalizedGreen, elementSize)
inputData.append(&bytes, count: elementSize)
memcpy(&ammp;bytes, &normalizedBlue, elementSize)
inputData.append(&bytes, count: elementSize)
}
}
จากนั้นคัดลอกอินพุต NSData ไปยังล่ามแล้วดำเนินการ
Swift
try interpreter.allocateTensors()
try interpreter.copy(inputData, toInputAt: 0)
try interpreter.invoke()
คุณรับเอาต์พุตของโมเดลได้โดยเรียกใช้เมธอด output(at:) ของอินเทอร์พรีเตอร์
วิธีใช้เอาต์พุตจะขึ้นอยู่กับโมเดลที่คุณใช้
ตัวอย่างเช่น หากคุณทำการแยกประเภท ขั้นตอนถัดไปอาจเป็นการ แมปดัชนีของผลลัพธ์กับป้ายกำกับที่แสดง
Swift
let output = try interpreter.output(at: 0)
let probabilities =
UnsafeMutableBufferPointer<Float32>.allocate(capacity: 1000)
output.data.copyBytes(to: probabilities)
guard let labelPath = Bundle.main.path(forResource: "retrained_labels", ofType: "txt") else { return }
let fileContents = try? String(contentsOfFile: labelPath)
guard let labels = fileContents?.components(separatedBy: "\n") else { return }
for i in labels.indices {
print("\(labels[i]): \(probabilities[i])")
}
ภาคผนวก: ความปลอดภัยของโมเดล
ไม่ว่าคุณจะทำให้โมเดล TensorFlow Lite พร้อมใช้งานสำหรับ Firebase ML อย่างไร Firebase ML จะจัดเก็บโมเดลในรูปแบบ protobuf ที่ซีเรียลไลซ์มาตรฐานในที่เก็บข้อมูลในเครื่อง
ในทางทฤษฎีแล้ว หมายความว่าทุกคนสามารถคัดลอกโมเดลของคุณได้ อย่างไรก็ตาม ในทางปฏิบัติ โมเดลส่วนใหญ่มีความเฉพาะเจาะจงกับแอปพลิเคชันและมีการปกปิดโดยการเพิ่มประสิทธิภาพ ซึ่งทำให้ความเสี่ยงคล้ายกับที่คู่แข่งถอดแยกชิ้นส่วนและนำโค้ดของคุณกลับมาใช้ใหม่ อย่างไรก็ตาม คุณควรทราบถึงความเสี่ยงนี้ก่อนใช้ โมเดลที่กำหนดเองในแอป