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 küçültebilir ve uygulamanızın yeni bir sürümünü yayınlamadan uygulamanızın ML modellerini güncelleyebilirsiniz. Ayrıca Remote Config ve A/B Testing ile farklı modelleri farklı kullanıcı gruplarına dinamik olarak sunabilirsiniz.

Önkoşullar

  • MLModelDownloader kitaplığı yalnızca Swift için kullanılabilir.
  • 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. Bir TensorFlow Lite modeli almak için:

Sen başlamadan önce

TensorFlowLite'ı Firebase ile kullanmak için CocoaPod'ları kullanmanız gerekir, çünkü TensorFlowLite şu anda Swift Paket Yöneticisi ile kurulumu desteklememektedir. MLModelDownloader'ın nasıl kurulacağına ilişkin talimatlar için MLModelDownloader 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. Özel modelleri dağıtma ve yönetme konusuna bakın.

Firebase projenize özel bir model ekledikten sonra, belirttiğiniz adı kullanarak uygulamalarınızda modele başvurabilirsiniz. İstediğiniz zaman yeni bir TensorFlow Lite modelini dağıtabilir ve yeni modeli getModel() çağırarak kullanıcıların cihazlarına indirebilirsiniz (aşağıya bakın).

2. Modeli cihaza indirin ve bir TensorFlow Lite yorumlayıcısını başlatın

TensorFlow Lite modelinizi uygulamanızda kullanmak için öncelikle modelin en son sürümünü cihaza indirmek için Firebase ML SDK'yı kullanın.

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

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

İndirme türü Tanım
localModel Cihazdan yerel modeli 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 kullanıyorsunuz ve modelleri her zaman yeni adlar altında yüklüyorsunuz (önerilir).
localModelUpdateInBackground Cihazdan yerel modeli alın ve arka planda modeli 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 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ırakmalısınız (örneğin, kullanıcı arayüzünüzün gri renkte görünmesi veya bir kısmını gizleme).

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

Birçok uygulama indirme görevini başlatma kodunda başlatır, ancak bunu modeli kullanmanız gerekmeden önce herhangi bir noktada yapabilirsiniz.

3. Girdi verileri üzerinde çıkarım gerçekleştirin

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ğerler içerir. Bir modele veri aktarmadan veya sonucunu kullanmadan önce, modelinizin kullandığı dizilerin sayısını ve boyutlarını ("şekil") bilmeniz gerekir.

Modeli kendiniz oluşturduysanız veya modelin giriş ve çıkış biçimi belgelenmiş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:

piton

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 girdi ve çıktısının biçimini belirledikten sonra, girdi verilerinizi alın ve modeliniz için doğru şekle sahip bir girdi elde etmek için gerekli olan tüm dönüşümleri veriler üzerinde gerçekleştirin.

Örneğin, modeliniz görüntüleri işliyorsa ve modelinizin girdi boyutları [1, 224, 224, 3] kayan nokta değerlerine sahipse, görüntünün renk değerlerini aşağıdaki örnekte olduğu gibi bir 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, giriş NSData yorumlayıcıya kopyalayın ve çalıştırın:

Süratli

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

Modelin çıktısını, yorumlayıcının output(at:) yöntemini çağırarak alabilirsiniz. Çıktıyı nasıl kullandığınız, kullandığınız modele bağlıdır.

Örneğin, sınıflandırma yapıyorsanız, sonraki adım olarak sonucun dizinlerini temsil ettikleri etiketlerle eşleyebilirsiniz:

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 için nasıl kullanılabilir hale getirdiğinizden bağımsız olarak, Firebase ML bunları yerel depolamada standart serileştirilmiş protobuf biçiminde saklar.

Teoride bu, herkesin modelinizi kopyalayabileceği anlamına gelir. Bununla birlikte, pratikte, çoğu model uygulamaya o kadar özeldir ve optimizasyonlarla karıştırılmıştır ki, risk rakiplerinizin kodunuzu söküp yeniden kullanma riskine benzer. Yine de, uygulamanızda özel bir model kullanmadan önce bu riskin farkında olmalısınız.