Apple platformlarında özel bir TensorFlow Lite modeli kullanın

Uygulamanız özel TensorFlow Lite modelleri kullanıyorsa modellerinizi dağıtmak için Firebase ML'yi kullanabilirsiniz. Modelleri Firebase ile dağıtarak uygulamanızın ilk indirme boyutunu azaltabilir ve uygulamanızın yeni bir sürümünü yayınlamadan uygulamanızın makine öğrenimi modellerini güncelleyebilirsiniz. Uzaktan Yapılandırma ve A/B Testi ile farklı modelleri farklı kullanıcı gruplarına dinamik olarak sunabilirsiniz.

Önkoşullar

  • MLModelDownloader kütüphanesi yalnızca Swift için mevcuttur.
  • TensorFlow Lite yalnızca iOS 9 ve daha yenisini kullanan cihazlarda çalışır.

TensorFlow Lite modelleri

TensorFlow Lite modelleri, mobil cihazlarda çalışacak şekilde optimize edilmiş ML modelleridir. TensorFlow Lite modelini edinmek için:

Sen başlamadan önce

TensorFlowLite'ı Firebase ile kullanmak için CocoaPods kullanmanız gerekir çünkü TensorFlowLite şu anda Swift Paket Yöneticisi ile kurulumu desteklememektedir. MLModelDownloader nasıl kurulacağına ilişkin talimatlar için CocoaPods kurulum kılavuzuna bakın.

Kurulduktan sonra kullanmak için Firebase ve TensorFlowLite'ı içe aktarın.

Süratli

import FirebaseMLModelDownloader
import TensorFlowLite

1. Modelinizi dağıtın

Firebase konsolunu veya Firebase Admin Python ve Node.js SDK'larını kullanarak özel TensorFlow modellerinizi dağıtın. Bkz. Özel modelleri dağıtma ve yönetme .

Firebase projenize özel bir model ekledikten sonra, belirttiğiniz adı kullanarak uygulamalarınızda modele referans verebilirsiniz. İstediğiniz zaman yeni bir TensorFlow Lite modelini dağıtabilir ve getModel() öğesini ç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 öncelikle Firebase ML SDK'yı kullanarak modelin en son sürümünü cihaza indirin.

Model indirmeyi başlatmak için, modeli yüklediğinizde modele atadığınız adı, her zaman en son modeli indirmek isteyip istemediğinizi ve hangi koşullar altında indirmeye izin vermek istediğinizi belirterek, model indiricisinin getModel() yöntemini çağırın.

Üç indirme davranışından birini seçebilirsiniz:

İndirme türü Tanım
localModel Yerel modeli cihazdan alın. Kullanılabilir yerel model yoksa bu, latestModel gibi davranı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 adlar altında yüklüyorsunuz (önerilen).
localModelUpdateInBackground Yerel modeli cihazdan alın ve modeli arka planda güncellemeye başlayın. Kullanılabilir yerel model yoksa bu, latestModel gibi davranır.
latestModel En son modeli alın. 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 engellenecektir (ö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 (örneğin, kullanıcı arayüzünüzün grileştirilmesi veya bir kısmının gizlenmesi) devre dışı bırakmalısınız.

Süratli

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)
        }
}

Çoğu uygulama, indirme görevini kendi başlatma kodunda başlatır, ancak bunu, modeli kullanmanız gerekmeden önce herhangi bir noktada yapabilirsiniz.

3. Giriş verileri üzerinde çıkarım yapın

Modelinizin giriş ve çıkış şekillerini alın

TensorFlow Lite model yorumlayıcısı girdi olarak alır ve çıktı olarak bir veya daha fazla çok boyutlu dizi üretir. Bu diziler byte , int , long veya float değerlerini içerir. Bir modele veri aktarmadan veya sonucunu kullanmadan önce, modelinizin kullandığı dizilerin sayısını ve boyutlarını ("şekli") bilmeniz gerekir.

Modeli kendiniz oluşturduysanız veya modelin giriş ve çıkış formatı belgelenmişse bu bilgiye 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 çıktı:

1 input(s):
[  1 224 224   3] <class 'numpy.float32'>

1 output(s):
[1 1000] <class 'numpy.float32'>

Tercümanı çalıştırın

Modelinizin giriş ve çıkış formatını belirledikten sonra giriş verilerinizi alın ve modeliniz için doğru şekle sahip bir giriş elde etmek için veriler üzerinde gerekli tüm 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ğerlerine sahipse, aşağıdaki örnekte olduğu gibi görüntünün renk değerlerini kayan nokta aralığına ölçeklendirmeniz gerekebilir. :

Süratli

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 ..&lt; 224 {
  for col in 0 ..&lt; 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(&amp;bytes, &amp;normalizedRed, elementSize)
    inputData.append(&amp;bytes, count: elementSize)
    memcpy(&amp;bytes, &amp;normalizedGreen, elementSize)
    inputData.append(&amp;bytes, count: elementSize)
    memcpy(&ammp;bytes, &amp;normalizedBlue, elementSize)
    inputData.append(&amp;bytes, count: elementSize)
  }
}

Ardından, NSData girişinizi yorumlayıcıya kopyalayın ve çalıştırın:

Süratli

try interpreter.allocateTensors()
try interpreter.copy(inputData, toInputAt: 0)
try interpreter.invoke()

Yorumlayıcının output(at:) yöntemini çağırarak modelin çıktısını alabilirsiniz. Çıktıyı 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 indekslerini temsil ettikleri etiketlerle eşleştirebilirsiniz:

Süratli

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'de nasıl kullanılabilir hale getirdiğinizden bağımsız olarak, Firebase ML bunları yerel depolamada standart serileştirilmiş protobuf formatında saklar.

Teorik olarak bu, herkesin modelinizi kopyalayabileceği anlamına gelir. Ancak uygulamada çoğu model, uygulamaya o kadar özeldir ve optimizasyonlar nedeniyle karartılmıştır ki, risk, rakiplerinizin kodunuzu parçalara ayırıp yeniden kullanması ile benzerdir. Ancak uygulamanızda özel bir model kullanmadan önce bu riskin farkında olmalısınız.