Jika aplikasi Anda menggunakan model TensorFlow Lite kustom, Anda dapat menggunakan Firebase ML untuk menerapkan model Anda. Dengan menerapkan model dengan Firebase, Anda dapat mengurangi ukuran unduhan awal aplikasi Anda dan memperbarui model ML aplikasi Anda tanpa merilis versi baru aplikasi Anda. Dan, dengan Remote Config dan Pengujian A/B, Anda dapat menyajikan model yang berbeda secara dinamis ke kumpulan pengguna yang berbeda.
Prasyarat
- Pustaka
MLModelDownloader
hanya tersedia untuk Swift. - TensorFlow Lite hanya berjalan di perangkat yang menggunakan iOS 9 dan yang lebih baru.
Model TensorFlow Lite
Model TensorFlow Lite adalah model ML yang dioptimalkan untuk berjalan di perangkat seluler. Untuk mendapatkan model TensorFlow Lite:
- Gunakan model bawaan, seperti salah satu model resmi TensorFlow Lite .
- Mengonversi model TensorFlow, model Keras, atau fungsi konkret ke TensorFlow Lite.
Sebelum kamu memulai
Untuk menggunakan TensorFlowLite dengan Firebase, Anda harus menggunakan CocoaPods karena TensorFlowLite saat ini tidak mendukung penginstalan dengan Swift Package Manager. Lihat panduan instalasi CocoaPods untuk instruksi tentang cara menginstal MLModelDownloader
.
Setelah terinstal, impor Firebase dan TensorFlowLite untuk menggunakannya.
Cepat
import FirebaseMLModelDownloader
import TensorFlowLite
1. Terapkan model Anda
Deploy model TensorFlow kustom Anda menggunakan Firebase console atau Firebase Admin Python dan Node.js SDK. Lihat Menerapkan dan mengelola model khusus .
Setelah menambahkan model kustom ke proyek Firebase, Anda dapat mereferensikan model di aplikasi menggunakan nama yang Anda tentukan. Kapan saja, Anda dapat menerapkan model TensorFlow Lite baru dan mengunduh model baru ke perangkat pengguna dengan memanggil getModel()
(lihat di bawah).
2. Unduh model ke perangkat dan inisialisasi penerjemah TensorFlow Lite
Untuk menggunakan model TensorFlow Lite di aplikasi Anda, pertama-tama gunakan Firebase ML SDK untuk mendownload model versi terbaru ke perangkat. Untuk memulai pengunduhan model, panggil metode getModel()
pengunduh model, tentukan nama yang Anda tetapkan untuk model saat Anda mengunggahnya, apakah Anda ingin selalu mengunduh model terbaru, dan kondisi di mana Anda ingin mengizinkan pengunduhan.
Anda dapat memilih dari tiga perilaku unduhan:
Jenis unduhan | Keterangan |
---|---|
localModel | Dapatkan model lokal dari perangkat. Jika tidak ada model lokal yang tersedia, ini berperilaku seperti latestModel . Gunakan jenis unduhan ini jika Anda tidak tertarik untuk memeriksa pembaruan model. Misalnya, Anda menggunakan Remote Config untuk mengambil nama model dan Anda selalu mengunggah model dengan nama baru (disarankan). |
localModelUpdateInBackground | Dapatkan model lokal dari perangkat dan mulai perbarui model di latar belakang. Jika tidak ada model lokal yang tersedia, ini berperilaku seperti latestModel . |
latestModel | Dapatkan model terbaru. Jika model lokal adalah versi terbaru, kembalikan model lokal. Jika tidak, unduh model terbaru. Perilaku ini akan diblokir hingga versi terbaru diunduh (tidak disarankan). Gunakan perilaku ini hanya jika Anda secara eksplisit membutuhkan versi terbaru. |
Anda harus menonaktifkan fungsionalitas terkait model—misalnya, menghilangkan atau menyembunyikan sebagian UI—sampai Anda mengonfirmasi bahwa model telah diunduh.
Cepat
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)
}
}
Banyak aplikasi memulai tugas pengunduhan dalam kode inisialisasinya, tetapi Anda dapat melakukannya kapan saja sebelum Anda perlu menggunakan model tersebut.
3. Lakukan inferensi pada input data
Dapatkan bentuk input dan output model Anda
Penerjemah model TensorFlow Lite mengambil sebagai input dan menghasilkan satu atau beberapa array multidimensi sebagai output. Array ini berisi nilai byte
, int
, long
, atau float
. Sebelum Anda dapat meneruskan data ke model atau menggunakan hasilnya, Anda harus mengetahui jumlah dan dimensi ("bentuk") dari larik yang digunakan model Anda.
Jika Anda membuat model sendiri, atau jika format input dan output model didokumentasikan, Anda mungkin sudah memiliki informasi ini. Jika Anda tidak mengetahui bentuk dan tipe data dari input dan output model Anda, Anda dapat menggunakan interpreter TensorFlow Lite untuk memeriksa model Anda. Sebagai contoh:
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']))
Contoh keluaran:
1 input(s): [ 1 224 224 3] <class 'numpy.float32'> 1 output(s): [1 1000] <class 'numpy.float32'>
Jalankan penerjemah
Setelah Anda menentukan format input dan output model Anda, dapatkan data input Anda dan lakukan transformasi apa pun pada data yang diperlukan untuk mendapatkan input dengan bentuk yang tepat untuk model Anda. Misalnya, jika model Anda memproses gambar, dan model Anda memiliki dimensi input nilai titik-mengambang [1, 224, 224, 3]
, Anda mungkin harus menskalakan nilai warna gambar ke rentang titik-mengambang seperti dalam contoh berikut :
Cepat
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)
}
}
Kemudian, salin NSData
input Anda ke penerjemah dan jalankan:
Cepat
try interpreter.allocateTensors()
try interpreter.copy(inputData, toInputAt: 0)
try interpreter.invoke()
Anda bisa mendapatkan output model dengan memanggil metode output(at:)
interpreter. Bagaimana Anda menggunakan output tergantung pada model yang Anda gunakan.
Misalnya, jika Anda melakukan klasifikasi, sebagai langkah berikutnya, Anda dapat memetakan indeks hasil ke label yang diwakilinya:
Cepat
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])")
}
Lampiran: Keamanan model
Terlepas dari cara Anda membuat model TensorFlow Lite tersedia untuk Firebase ML, Firebase ML menyimpannya dalam format protobuf serial standar di penyimpanan lokal.
Secara teori, ini berarti siapa pun dapat menyalin model Anda. Namun, dalam praktiknya, sebagian besar model sangat spesifik untuk aplikasi dan dikaburkan oleh pengoptimalan sehingga risikonya mirip dengan risiko pembongkaran dan penggunaan kembali kode pesaing Anda. Namun demikian, Anda harus menyadari risiko ini sebelum menggunakan model khusus di aplikasi Anda.