หากแอปของคุณใช้ โมเดล TensorFlow Lite ที่กำหนดเอง คุณสามารถใช้ Firebase ML เพื่อทำให้โมเดลใช้งานได้ การนำโมเดลไปใช้งานด้วย Firebase ทำให้คุณลดขนาดการดาวน์โหลดเริ่มต้นของแอปและอัปเดตโมเดล ML ของแอปได้โดยไม่ต้องเปิดตัวแอปเวอร์ชันใหม่ และด้วยการกำหนดค่าระยะไกลและการทดสอบ A/B คุณสามารถให้บริการโมเดลต่างๆ แบบไดนามิกแก่ผู้ใช้กลุ่มต่างๆ
ข้อกำหนดเบื้องต้น
- ไลบรารี
MLModelDownloader
พร้อมใช้งานสำหรับ Swift เท่านั้น - TensorFlow Lite ทำงานบนอุปกรณ์ที่ใช้ iOS 9 ขึ้นไปเท่านั้น
รุ่น TensorFlow Lite
รุ่น TensorFlow Lite เป็นรุ่น ML ที่ได้รับการปรับแต่งให้ทำงานบนอุปกรณ์เคลื่อนที่ ในการรับรุ่น TensorFlow Lite:
- ใช้โมเดลที่สร้างไว้ล่วงหน้า เช่นหนึ่งใน รุ่น TensorFlow Lite ที่เป็นทางการ
- แปลงโมเดล TensorFlow, โมเดล Keras หรือฟังก์ชันที่เป็นรูปธรรมเป็น TensorFlow Lite
ก่อนจะเริ่ม
หากต้องการใช้ TensorFlowLite กับ Firebase คุณต้องใช้ CocoaPods เนื่องจาก TensorFlowLite ไม่รองรับการติดตั้งด้วย Swift Package Manager ในขณะนี้ ดู คู่มือการติดตั้ง CocoaPods สำหรับคำแนะนำในการติดตั้ง MLModelDownloader
เมื่อติดตั้งแล้ว ให้นำเข้า Firebase และ TensorFlowLite เพื่อใช้งาน
Swift
import FirebaseMLModelDownloader
import TensorFlowLite
1. ปรับใช้โมเดลของคุณ
ทำให้โมเดล TensorFlow ที่กำหนดเองใช้งานได้โดยใช้คอนโซล Firebase หรือ Firebase Admin Python และ Node.js SDK ดู ปรับใช้และจัดการโมเดลที่กำหนดเอง
หลังจากเพิ่มโมเดลที่กำหนดเองลงในโปรเจ็กต์ Firebase แล้ว คุณจะอ้างอิงโมเดลในแอปได้โดยใช้ชื่อที่คุณระบุ คุณสามารถปรับใช้โมเดล TensorFlow Lite ใหม่ได้ทุกเมื่อ และดาวน์โหลดโมเดลใหม่ลงในอุปกรณ์ของผู้ใช้โดยเรียก getModel()
(ดูด้านล่าง)
2. ดาวน์โหลดรุ่นไปยังอุปกรณ์และเริ่มต้นล่าม TensorFlow Lite
หากต้องการใช้โมเดล TensorFlow Lite ในแอป ขั้นแรกให้ใช้ Firebase ML SDK เพื่อดาวน์โหลดเวอร์ชันล่าสุดลงในอุปกรณ์ ในการเริ่มต้นการดาวน์โหลดโมเดล ให้เรียก getModel()
ของโปรแกรมดาวน์โหลดโมเดล โดยระบุชื่อที่คุณกำหนดโมเดลเมื่อคุณอัปโหลด ไม่ว่าคุณจะต้องการดาวน์โหลดโมเดลล่าสุดเสมอหรือไม่ และเงื่อนไขที่คุณต้องการอนุญาตให้ดาวน์โหลด
คุณสามารถเลือกพฤติกรรมการดาวน์โหลดได้สามแบบ:
ดาวน์โหลดประเภท | คำอธิบาย |
---|---|
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 ใช้เป็นอินพุตและสร้างอาร์เรย์หลายมิติเป็นเอาต์พุต อาร์เรย์เหล่านี้มีค่า 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 จะจัดเก็บโมเดลเหล่านี้ไว้ในรูปแบบโปรโตบัฟแบบอนุกรมมาตรฐานในที่จัดเก็บในเครื่อง
ตามทฤษฎีแล้ว นี่หมายความว่าใครๆ ก็เลียนแบบโมเดลของคุณได้ อย่างไรก็ตาม ในทางปฏิบัติ โมเดลส่วนใหญ่มีความเฉพาะเจาะจงกับแอปพลิเคชันและทำให้สับสนโดยการปรับให้เหมาะสม ซึ่งความเสี่ยงนั้นใกล้เคียงกับของคู่แข่งในการถอดแยกชิ้นส่วนและนำโค้ดของคุณกลับมาใช้ใหม่ อย่างไรก็ตาม คุณควรตระหนักถึงความเสี่ยงนี้ก่อนที่คุณจะใช้โมเดลที่กำหนดเองในแอปของคุณ