Apple platformlarında özel TensorFlow Lite modeli kullanma

Uygulamanızda TensorFlow Basit modeller kullanıyorsanız modellerinizi dağıtmak için Firebase ML kullanabilirsiniz. Ölçüt Firebase ile modelleri dağıttığınızda, uygulamanızın başlangıçtaki indirme boyutunu uygulamanızı ve uygulamanızın makine öğrenimi modellerini en iyi şekilde yararlanabilirsiniz. Ayrıca Remote Config ve A/B Testing ile, reklamlarınızı farklı kullanıcı gruplarına farklı modeller sunar.

Ön koşullar

  • MLModelDownloader kitaplığı yalnızca Swift'te kullanılabilir.
  • TensorFlow Lite yalnızca iOS 9 ve sonraki sürümleri kullanan cihazlarda çalışır.

TensorFlow Lite modelleri

TensorFlow Lite modelleri, mobil cihazlarda çalışmak için optimize edilmiş makine öğrenimi modelleridir cihazlar. TensorFlow Lite modeli edinmek için:

Başlamadan önce

TensorFlowLite'ı Firebase ile kullanmak için CocoaPods'u TensorFlowLite olarak kullanmanız gerekir şu anda Swift Package Manager ile yüklemeyi desteklemiyor. Bkz. CocoaPods kurulum kılavuzu: MLModelDownloader yükleme talimatları.

Yüklendikten sonra, kullanmak için Firebase ve TensorFlowLite'ı içe aktarın.

Swift

import FirebaseMLModelDownloader
import TensorFlowLite

1. Modelinizi dağıtma

Özel TensorFlow modellerinizi Firebase konsolunu ya da Firebase Admin Python ve Node.js SDK'ları. Görüntüleyin Özel modelleri dağıtın ve yönetin.

Firebase projenize özel model ekledikten sonra, modeliniz olmalıdır. İstediğiniz zaman dağıtabilirsiniz yeni bir TensorFlow Lite modeli kullanıyor ve yeni modeli kullanıcıların cihazları getModel() aranıyor (aşağıya bakın).

2. Modeli cihaza indirin ve TensorFlow Lite çevirmenini başlatın

Uygulamanızda TensorFlow Lite modelinizi kullanmak için önce Firebase ML SDK'sını kullanın modelin en son sürümünü cihaza indirin.

Model indirme işlemini başlatmak için model indirme aracının getModel() yöntemini çağırın. ister modelinizi isterken, modeli yüklerken atadığınız adı, almak istediğiniz her zaman en son modeli ve bu modele indirmeye izin vermek istiyorsunuz.

Üç indirme davranışı arasından seçim yapabilirsiniz:

İndirme türü Açıklama
localModel Cihazdan yerel modeli alın. Yerel model yoksa latestModel gibi davranır. Bunu kullan ilginizi çekmiyorsa indirme türü model güncellemeleri kontrol ediliyor. Örneğin, geri almak için Remote Config’i ve modelleri her zaman (önerilir).
localModelUpdateInBackground Cihazdan yerel modeli alın ve modeli arka planda güncellemeye başlayın. Yerel model yoksa latestModel gibi davranır.
latestModel En son modeli edinin. Yerel model en son sürüm, yerel modeli. Aksi durumda en yeni modeli. Bu davranış, en son sürüm indirildiğinde (yalnızca önerilir). Bu davranışı yalnızca sahip olmanız gereken en güncel sürümünü değil.

Modelle ilgili işlevleri (ör. devre dışı bırakma veya devre dışı bırakma) kullanıcı arayüzünüzün bir kısmını gizleyin (modelin indirildiğini onaylayana kadar).

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, indirme görevini başlatma kodunda başlatır ancak Bu nedenle, herhangi bir noktada modeli kullanmanız gerekir.

3. Giriş verilerinde çıkarım yap

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

TensorFlow Lite model yorumlayıcısı girdi olarak alır ve çıktı olarak üretir çok boyutlu diziyi inceleyebilirsiniz. Bu diziler byte, int, long veya float değerler. Bir modele veri iletmeden veya sonucunu kullanmadan önce şunları bilmeniz gerekir: modelinizin kullandığı dizilerin sayısı ve boyutları ("şekil")

Modeli kendiniz oluşturduysanız veya modelin giriş ve çıkış biçimi veya dokümanlara aşina değilseniz bu bilgilere zaten sahip olabilirsiniz. şeklini ve veri türünü öğrenmek için Modelinizi incelemek için TensorFlow Lite yorumlayıcısı. Ö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ışının biçimini belirledikten sonra ve gerekli tüm veriler üzerinde dönüşüm gerçekleştirebilirsiniz. modeliniz için doğru şekli sağlayan bir giriştir.

Örneğin, modeliniz görüntüleri işliyorsa ve modelinizin giriş boyutları varsa [1, 224, 224, 3] kayan nokta değerinden dolayı resmin renk değerlerini, aşağıdaki örnekte olduğu gibi bir kayan nokta aralığına ayarlayın:

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 ..&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şinizi (NSData) çevirmene kopyalayın ve çalıştırın:

Swift

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

Çevirmenin output(at:) yöntemini çağırarak modelin çıkışını alabilirsiniz. Sonucu 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 sonuç dizinlerini, temsil ettikleri etiketlerle eşler:

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 kullanıcılara nasıl sunduğunuz fark etmeksizin Firebase ML, Firebase ML bunları standart serileştirilmiş protobuf biçiminde şurada depolar: yerel depolama.

Teoride bu, herkesin modelinizi kopyalayabileceği anlamına gelir. Ancak, pratikte çoğu model, uygulamaya özgüdür ve her bir model rakiplerin parçalarının parçalarının sökülüp parçalarının parçalarının kodunuzu tekrarlamanız gerekir. Yine de, anahtar kelimeleri kullanmadan önce bu riskin farkında olmalısınız. bir model oluşturabilirsiniz.