Wenn Ihre App benutzerdefinierte TensorFlow Lite-Modellen verwenden, können Sie sie mit Firebase ML bereitstellen. Von bei der Bereitstellung von Modellen mit Firebase die anfängliche Downloadgröße Ihre App aktualisieren und die ML-Modelle Ihrer App aktualisieren, ohne eine neue Version des für Ihre App. Mit Remote Config und A/B Testing können Sie außerdem verschiedene Modelle für verschiedene Gruppen von Nutzenden bereitzustellen.
Vorbereitung
- Die
MLModelDownloader
-Bibliothek ist nur für Swift verfügbar. - TensorFlow Lite läuft nur auf Geräten mit iOS 9 und höher.
TensorFlow Lite-Modelle
TensorFlow Lite-Modelle sind ML-Modelle, die für die Ausführung auf Mobilgeräten optimiert sind. So rufen Sie ein TensorFlow Lite-Modell ab:
- Verwenden Sie ein vordefiniertes Modell, z. B. eines der offiziell TensorFlow Lite-Modelle.
- Conversion ein TensorFlow-Modell, ein Keras-Modell oder eine konkrete Funktion in TensorFlow Lite
Hinweis
Wenn Sie TensorFlow Lite mit Firebase verwenden möchten, müssen Sie CocoaPods verwenden, da TensorFlow Lite derzeit nicht über den Swift Package Manager installiert werden kann. Weitere Informationen finden Sie in der
CocoaPods-Installationsanleitung für
zur Installation von MLModelDownloader
.
Nach der Installation müssen Sie Firebase und TensorFlowLite importieren, um sie verwenden zu können.
Swift
import FirebaseMLModelDownloader
import TensorFlowLite
1. Modell bereitstellen
Sie können Ihre benutzerdefinierten TensorFlow-Modelle entweder über die Firebase-Konsole oder die Firebase Admin Python- und Node.js-SDKs bereitstellen. Weitere Informationen finden Sie unter Benutzerdefinierte Modelle bereitstellen und verwalten
Nachdem Sie Ihrem Firebase-Projekt ein benutzerdefiniertes Modell hinzugefügt haben, können Sie auf das Modell
in Ihren Apps unter Verwendung des von Ihnen angegebenen Namens. Sie können jederzeit
ein neues TensorFlow Lite-Modell erstellen
und das neue Modell auf die Geräte nach
getModel()
wird aufgerufen (siehe unten).
2. Modell auf das Gerät herunterladen und einen TensorFlow Lite-Interpreter initialisieren
Zur Verwendung des TensorFlow Lite-Modells in Ihrer App müssen Sie zuerst das Firebase ML SDK verwenden um die neueste Version des Modells auf das Gerät herunterzuladen.Um den Modelldownload zu starten, rufen Sie die Methode getModel()
des Modelldownloads auf.
Sie geben den Namen an, den Sie dem Modell beim Hochladen zugewiesen haben, unabhängig davon, ob Sie
immer das neueste Modell herunterladen möchten und unter welchen Bedingungen
den Download erlauben möchten.
Sie können zwischen drei Downloadverhalten wählen:
Downloadtyp | Beschreibung |
---|---|
localModel
|
Rufen Sie das lokale Modell vom Gerät ab.
Wenn kein lokales Modell verfügbar ist, verhält sich das Modell wie latestModel . Verwenden
Downloadtyp, wenn Sie kein Interesse an
Modellaktualisierungen suchen. Beispiel:
rufen Sie mit Remote Config
und Sie laden Modelle immer hoch,
unter neuen Namen (empfohlen). |
localModelUpdateInBackground
|
Rufen Sie das lokale Modell vom Gerät ab und beginnen Sie, das Modell im Hintergrund zu aktualisieren.
Wenn kein lokales Modell verfügbar ist,
verhält sich wie latestModel . |
latestModel
|
Rufen Sie das aktuelle Modell ab. Wenn das lokale Modell die neueste Version, gibt den lokalen modellieren. Laden Sie andernfalls die aktuelle modellieren. Dieses Verhalten wird blockiert, bis das die neueste Version heruntergeladen wurde (nicht empfohlen). Verwenden Sie dieses Verhalten nur in in denen Sie ausdrücklich die aktuellsten Version. |
Sie sollten modellbezogene Funktionen deaktivieren, z. B. einen Teil der Benutzeroberfläche ausblenden, bis Sie bestätigen, dass das Modell heruntergeladen wurde.
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)
}
}
Viele Apps starten die Download-Aufgabe im Initialisierungscode, aber Sie können bevor Sie das Modell verwenden.
3. Eingabedaten Inferenz durchführen
Ein- und Ausgabeformen des Modells abrufen
Der TensorFlow Lite-Modellinterpreter nimmt ein oder mehrere mehrdimensionale Arrays als Eingabe und gibt ein oder mehrere mehrdimensionale Arrays als Ausgabe zurück. Diese Arrays enthalten entweder
byte
, int
, long
oder float
Werte. Bevor Sie Daten an ein Modell übergeben oder dessen Ergebnisse verwenden können, müssen Sie wissen,
die Anzahl und Abmessungen ("Form") der Arrays, die Ihr Modell verwendet
Wenn Sie das Modell selbst erstellt haben oder das Eingabe- und Ausgabeformat des Modells wie folgt lautet: dokumentiert ist, haben Sie diese Informationen vielleicht schon. Wenn Sie nicht wissen, die Form und den Datentyp der Eingabe und Ausgabe Ihres Modells ein, können Sie die Methode TensorFlow Lite-Interpreter zur Prüfung Ihres Modells. Beispiel:
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']))
Beispielausgabe:
1 input(s): [ 1 224 224 3] <class 'numpy.float32'> 1 output(s): [1 1000] <class 'numpy.float32'>
Dolmetscher ausführen
Nachdem Sie das Format der Ein- und Ausgabe Ihres Modells ermittelt haben, Eingabedaten und Transformationen der Daten, die für den Erhalt Eingabe der richtigen Form für Ihr Modell.Beispiel: Ihr Modell verarbeitet Bilder und hat Eingabeabmessungen
von [1, 224, 224, 3]
Gleitkommawerten ist, müssen Sie möglicherweise skalieren
die Farbwerte des Bildes in einen Gleitkommabereich, wie im folgenden Beispiel gezeigt:
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)
}
}
Kopieren Sie dann Ihre Eingabe-NSData
in den Interpreter und führen Sie sie aus:
Swift
try interpreter.allocateTensors()
try interpreter.copy(inputData, toInputAt: 0)
try interpreter.invoke()
Sie können die Modellausgabe abrufen, indem Sie die output(at:)
-Methode des Interpreters aufrufen.
Wie Sie die Ausgabe verwenden, hängt vom verwendeten Modell ab.
Bei der Klassifizierung könnten Sie als nächsten Schritt ordnen Sie die Indexe des Ergebnisses den von ihnen dargestellten Labels zu:
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])")
}
Anhang: Modellsicherheit
Unabhängig davon, wie Sie Ihre TensorFlow Lite-Modelle für Firebase ML, speichert Firebase ML sie im standardisierten serialisierten protobuf-Format unter lokalen Speicher.
Theoretisch bedeutet dies, dass jeder Ihr Modell kopieren kann. Sie können jedoch in der Praxis sind die meisten Modelle so anwendungsspezifisch Optimierungen vorzunehmen, bei denen das Risiko dem der Konkurrenz beim Auseinanderbauen und Ihren Code wiederverwenden. Sie sollten sich jedoch dieses Risikos bewusst sein, bevor Sie ein benutzerdefiniertes Modell in Ihrer App verwenden.