Uygulamanız özel TensorFlow Lite modelleri kullanıyorsa modellerinizi dağıtmak için Firebase ML kullanabilirsiniz. Firebase ile modelleri dağıtarak uygulamanızın ilk indirme boyutunu küçültebilir ve uygulamanızın yeni bir sürümünü yayınlamadan uygulamanızın makine öğrenimi modellerini güncelleyebilirsiniz. Ayrıca Remote Config ve A/B Testing ile farklı kullanıcı gruplarına farklı modelleri dinamik olarak sunabilirsiniz.
Hem model indirme API'si hem de TensorFlow Lite yorumlayıcısına yönelik bir arayüz sağlayanÖn koşullar
MLModelDownloaderkitaplığı yalnızca Swift için kullanılabilir.- TensorFlow Lite yalnızca iOS 9 ve sonraki sürümlerin yüklü olduğu cihazlarda çalışır.
TensorFlow Lite modelleri
TensorFlow Lite modelleri, mobil cihazlarda çalışacak şekilde optimize edilmiş makine öğrenimi modelleridir. TensorFlow Lite modeli edinmek için:
- Resmi TensorFlow Lite modellerinden biri gibi önceden oluşturulmuş bir model kullanın.
- TensorFlow modelini, Keras modelini veya somut işlevi TensorFlow Lite'a dönüştürün.
Başlamadan önce
TensorFlowLite'ı Firebase ile kullanmak için CocoaPods'u kullanmanız gerekir. Çünkü TensorFlowLite şu anda Swift Package Manager ile yüklemeyi desteklememektedir. MLModelDownloader yükleme talimatları için CocoaPods yükleme kılavuzuna bakın.
Yüklendikten sonra Firebase ve TensorFlowLite'ı kullanmak için bunları içe aktarın.
Swift
import FirebaseMLModelDownloader
import TensorFlowLite
1. Modelinizi dağıtma
Özel TensorFlow modellerinizi Firebase konsolunu veya Firebase Admin Python ve Node.js SDK'larını kullanarak dağıtın. Özel modelleri dağıtma ve yönetme başlıklı makaleyi inceleyin.
Firebase projenize özel bir model ekledikten sonra, belirttiğiniz adı kullanarak uygulamalarınızdaki modele referansta bulunabilirsiniz. İstediğiniz zaman yeni bir TensorFlow Lite modeli dağıtabilir ve getModel() işlevini çağırarak yeni modeli kullanıcıların cihazlarına indirebilirsiniz (aşağıya bakın).
2. Modeli cihaza indirin ve TensorFlow Lite yorumlayıcısını başlatın
TensorFlow Lite modelinizi uygulamanızda kullanmak için önce Firebase ML SDK'sını kullanarak modelin en son sürümünü cihaza indirin.Model indirme işlemini başlatmak için model indiricinin getModel() yöntemini çağırın. Bu yöntemi çağırırken modeli yüklediğinizde atadığınız adı, her zaman en son modeli indirmek isteyip istemediğinizi ve indirmeye izin vermek istediğiniz koşulları belirtin.
Üç indirme davranışından birini seçebilirsiniz:
| İndirme türü | Açıklama |
|---|---|
localModel
|
Cihazdan yerel modeli alın.
Yerel model yoksa bu işlev latestModel gibi çalışır. Model güncellemelerini kontrol etmekle ilgilenmiyorsanız bu indirme türünü kullanın. Örneğin, model adlarını almak için Remote Config'i kullanıyorsunuz ve modelleri her zaman yeni adlarla yüklüyorsunuz (önerilir). |
localModelUpdateInBackground
|
Cihazdan yerel modeli alın ve modeli arka planda güncellemeye başlayın.
Yerel model yoksa bu işlev latestModel gibi çalışır. |
latestModel
|
En yeni modeli edinin. Yerel model en son sürümse yerel modeli döndürür. Aksi takdirde en son modeli indirin. Bu davranış, en son sürüm indirilene kadar engellenir (önerilmez). Bu davranışı yalnızca en son sürüme açıkça ihtiyaç duyduğunuz durumlarda kullanın. |
Modelin indirildiğini onaylayana kadar modelle ilgili işlevleri devre dışı bırakmanız gerekir. Örneğin, kullanıcı arayüzünüzün bir bölümünü grileştirebilir veya gizleyebilirsiniz.
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)
}
}
Birçok uygulama, başlatma kodunda indirme görevini başlatır ancak modeli kullanmanız gerekmeden önce istediğiniz zaman bu işlemi yapabilirsiniz.
3. Giriş verileri üzerinde çıkarım yapma
Modelinizin giriş ve çıkış şekillerini alma
TensorFlow Lite model yorumlayıcısı, giriş olarak bir veya daha fazla çok boyutlu dizi alır ve çıkış olarak bunları üretir. Bu diziler byte, int, long veya float değerlerini içerir. Bir modele veri aktarabilmeniz veya modelin sonucunu kullanabilmeniz için modelinizin kullandığı dizilerin sayısını ve boyutlarını ("şekil") bilmeniz gerekir.
Modeli kendiniz oluşturduysanız veya modelin giriş ve çıkış biçimi belgelendirilmişse bu bilgilere zaten sahip olabilirsiniz. Modelinizin giriş ve çıkışının şeklini ve veri türünü bilmiyorsanız modelinizi incelemek için TensorFlow Lite yorumlayıcısını kullanabilirsiniz. Örneğin:
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']))
Örnek çıkış:
1 input(s): [ 1 224 224 3] <class 'numpy.float32'> 1 output(s): [1 1000] <class 'numpy.float32'>
Çevirmeni çalıştırma
Modelinizin giriş ve çıkış biçimini belirledikten sonra giriş verilerinizi alın ve modeliniz için doğru şekilli bir giriş elde etmek üzere verilerde gerekli dönüşümleri gerçekleştirin.Örneğin, modeliniz görüntüleri işliyorsa ve modelinizin giriş boyutları [1, 224, 224, 3] kayan nokta değeriyse görüntünün renk değerlerini aşağıdaki örnekte olduğu gibi kayan nokta aralığına ölçeklendirmeniz gerekebilir:
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)
}
}
Ardından, girişinizi NSData çevirmene kopyalayıp uygulayın:
Swift
try interpreter.allocateTensors()
try interpreter.copy(inputData, toInputAt: 0)
try interpreter.invoke()
Yorumlayıcının output(at:) yöntemini çağırarak modelin çıkışını alabilirsiniz.
Çıkışı nasıl kullanacağınız, kullandığınız modele bağlıdır.
Örneğin, sınıflandırma yapıyorsanız bir sonraki adım olarak sonucun dizinlerini temsil ettikleri etiketlerle eşleyebilirsiniz:
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])")
}
Ek: Model güvenliği
TensorFlow Lite modellerinizi Firebase ML'a nasıl sunduğunuzdan bağımsız olarak, Firebase ML bunları yerel depolama alanında standart serileştirilmiş protobuf biçiminde depolar.
Bu, teorik olarak herkesin modelinizi kopyalayabileceği anlamına gelir. Ancak uygulamada, çoğu model uygulamaya özel ve optimizasyonlarla karartılmış olduğundan risk, rakiplerin kodunuzu söküp yeniden kullanmasıyla aynıdır. Bununla birlikte, uygulamanızda özel bir model kullanmadan önce bu riskin farkında olmanız gerekir.