1. Vue d'ensemble
Objectifs
Firebase ML vous permet de déployer votre modèle en direct. Cela vous permet de conserver une petite taille d'application et de télécharger le modèle ML uniquement lorsque cela est nécessaire, d'expérimenter plusieurs modèles ou de mettre à jour votre modèle ML sans avoir à republier l'intégralité de l'application.
Dans cet atelier de programmation, vous allez convertir une application iOS utilisant un modèle TFLite statique en une application utilisant un modèle servi dynamiquement depuis Firebase. Vous apprendrez à :
- Déployez des modèles TFLite sur Firebase ML et accédez-y depuis votre application
- Consigner les métriques liées au modèle avec Analytics
- Sélectionnez quel modèle est chargé via Remote Config
- Testez A/B différents modèles
Conditions préalables
Avant de commencer cet atelier de programmation, assurez-vous d'avoir installé :
- Xcode 11 (ou supérieur)
- CocoaPods 1.9.1 (ou supérieur)
2. Créer un projet de console Firebase
Ajouter Firebase au projet
- Accédez à la console Firebase .
- Sélectionnez Créer un nouveau projet et nommez votre projet « Firebase ML iOS Codelab ».
3. Obtenez l'exemple de projet
Téléchargez le code
Commencez par cloner l'exemple de projet et exécutez pod update
dans le répertoire du projet :
git clone https://github.com/FirebaseExtended/codelab-digitclassifier-ios.git cd codelab-digitclassifier-ios pod install --repo-update
Si git n'est pas installé, vous pouvez également télécharger l'exemple de projet depuis sa page GitHub ou en cliquant sur ce lien . Une fois que vous avez téléchargé le projet, exécutez-le dans Xcode et jouez avec le classificateur de chiffres pour avoir une idée de son fonctionnement.
Configurer Firebase
Suivez la documentation pour créer un nouveau projet Firebase. Une fois que vous avez votre projet, téléchargez le fichier GoogleService-Info.plist
de votre projet depuis la console Firebase et faites-le glisser vers la racine du projet Xcode.
Ajoutez Firebase à votre Podfile et exécutez l'installation du pod.
pod 'FirebaseMLModelDownloader', '9.3.0-beta'
Dans la méthode didFinishLaunchingWithOptions
de votre AppDelegate
, importez Firebase en haut du fichier
import FirebaseCore
Et ajoutez un appel pour configurer Firebase.
FirebaseApp.configure()
Exécutez à nouveau le projet pour vous assurer que l'application est correctement configurée et ne plante pas au lancement.
4. Déployer un modèle sur Firebase ML
Le déploiement d'un modèle sur Firebase ML est utile pour deux raisons principales :
- Nous pouvons garder la taille d'installation de l'application petite et télécharger le modèle uniquement si nécessaire
- Le modèle peut être mis à jour régulièrement et avec un cycle de publication différent de celui de l'ensemble de l'application
Avant de pouvoir remplacer le modèle statique de notre application par un modèle téléchargé dynamiquement depuis Firebase, nous devons le déployer sur Firebase ML. Le modèle peut être déployé via la console ou par programme, à l'aide du SDK d'administration Firebase. Dans cette étape, nous allons déployer via la console.
Pour simplifier les choses, nous utiliserons le modèle TensorFlow Lite déjà présent dans notre application. Tout d’abord, ouvrez Firebase et cliquez sur Machine Learning dans le panneau de navigation de gauche. Accédez ensuite à « Personnalisé » et cliquez sur le bouton « Ajouter un modèle ».
Lorsque vous y êtes invité, attribuez au modèle un nom descriptif tel que mnist_v1
et importez le fichier à partir du répertoire du projet de l'atelier de programmation.
5. Téléchargez le modèle depuis Firebase ML
Choisir quand télécharger le modèle distant de Firebase dans votre application peut être délicat car les modèles TFLite peuvent devenir relativement volumineux. Idéalement, nous voulons éviter de charger le modèle immédiatement au lancement de l'application, car si notre modèle est utilisé pour une seule fonctionnalité et que l'utilisateur n'utilise jamais cette fonctionnalité, nous aurons téléchargé une quantité importante de données sans raison. Nous pouvons également définir des options de téléchargement telles que la récupération des modèles uniquement lorsque vous êtes connecté au wifi. Si vous souhaitez vous assurer que le modèle est disponible même sans connexion réseau, vous devez également regrouper le modèle dans l'application en tant que sauvegarde.
Par souci de simplicité, nous supprimerons le modèle fourni par défaut et téléchargerons toujours un modèle depuis Firebase au démarrage de l'application. De cette façon, lors de l'exécution de la reconnaissance numérique, vous pouvez être sûr que l'inférence s'exécute avec le modèle fourni par Firebase.
En haut de ModelLoader.swift
, importez le module Firebase.
import FirebaseCore import FirebaseMLModelDownloader
Implémentez ensuite la méthode suivante.
static func downloadModel(named name: String, completion: @escaping (CustomModel?, DownloadError?) -> Void) { guard FirebaseApp.app() != nil else { completion(nil, .firebaseNotInitialized) return } guard success == nil && failure == nil else { completion(nil, .downloadInProgress) return } let conditions = ModelDownloadConditions(allowsCellularAccess: false) ModelDownloader.modelDownloader().getModel(name: name, downloadType: .localModelUpdateInBackground, conditions: conditions) { result in switch (result) { case .success(let customModel): // Download complete. // The CustomModel object contains the local path of the model file, // which you can use to instantiate a TensorFlow Lite classifier. return completion(customModel, nil) case .failure(let error): // Download was unsuccessful. Notify error message. completion(nil, .downloadFailed(underlyingError: error)) } } }
Dans ViewController.swift
's viewDidLoad
, remplacez l'appel d'initialisation DigitClassifier par notre nouvelle méthode de téléchargement de modèle.
// Download the model from Firebase print("Fetching model...") ModelLoader.downloadModel(named: "mnist_v1") { (customModel, error) in guard let customModel = customModel else { if let error = error { print(error) } return } print("Model download complete") // Initialize a DigitClassifier instance DigitClassifier.newInstance(modelPath: customModel.path) { result in switch result { case let .success(classifier): self.classifier = classifier case .error(_): self.resultLabel.text = "Failed to initialize." } } }
Réexécutez votre application. Après quelques secondes, vous devriez voir un journal dans Xcode indiquant que le modèle distant a été téléchargé avec succès. Essayez de dessiner un chiffre et confirmez que le comportement de l'application n'a pas changé.
6. Suivez les commentaires des utilisateurs et la conversion pour mesurer la précision du modèle
Nous mesurerons la précision du modèle en suivant les commentaires des utilisateurs sur les prédictions du modèle. Si un utilisateur clique sur « oui », cela indiquera que la prédiction était exacte.
Nous pouvons enregistrer un événement Analytics pour suivre l'exactitude de notre modèle. Tout d'abord, nous devons ajouter Analytics au Podfile avant qu'il puisse être utilisé dans le projet :
pod 'FirebaseAnalytics'
Puis dans ViewController.swift
importez Firebase en haut du fichier
import FirebaseAnalytics
Et ajoutez la ligne de code suivante dans la méthode correctButtonPressed
.
Analytics.logEvent("correct_inference", parameters: nil)
Exécutez à nouveau l'application et dessinez un chiffre. Appuyez plusieurs fois sur le bouton « Oui » pour envoyer un retour indiquant que l'inférence était exacte.
Analyses de débogage
Généralement, les événements enregistrés par votre application sont regroupés sur une période d'environ une heure et téléchargés ensemble. Cette approche préserve la batterie des appareils des utilisateurs finaux et réduit l'utilisation des données du réseau. Cependant, dans le but de valider la mise en œuvre de votre analyse (et afin d'afficher vos analyses dans le rapport DebugView), vous pouvez activer le mode Débogage sur votre appareil de développement pour télécharger les événements dans un délai minimal.
Pour activer le mode Analytics Debug sur votre appareil de développement, spécifiez l'argument de ligne de commande suivant dans Xcode :
-FIRDebugEnabled
Exécutez à nouveau l'application et dessinez un chiffre. Appuyez plusieurs fois sur le bouton « Oui » pour envoyer un retour indiquant que l'inférence était exacte. Vous pouvez désormais afficher les événements du journal en temps quasi réel via la vue de débogage de la console Firebase. Cliquez sur Analytics > DebugView dans la barre de navigation de gauche.
7. Suivez le temps d'inférence avec Firebase Performance
Lorsque vous testez votre modèle, les mesures de performances effectuées sur les appareils de développement ne suffisent pas à capturer les performances du modèle entre les mains de vos utilisateurs, car il est difficile de savoir sur quel matériel les utilisateurs exécuteront votre application. Heureusement, vous pouvez mesurer les performances de votre modèle sur les appareils des utilisateurs avec Firebase Performance pour avoir une meilleure idée des performances de votre modèle.
Pour mesurer le temps nécessaire à l'exécution de l'inférence, importez d'abord Firebase dans DigitClassifier.swift :
import FirebasePerformance
Démarrez ensuite une trace de performances dans la méthode classify et arrêtez la trace une fois l'inférence terminée. Assurez-vous d'ajouter les lignes de code suivantes à l'intérieur de la fermeture DispatchQueue.global.async et non directement sous la déclaration de méthode.
let inferenceTrace = Performance.startTrace(name: "tflite inference") defer { inferenceTrace?.stop() }
Si vous êtes curieux, vous pouvez activer la journalisation du débogage via les instructions ici pour confirmer que vos traces de performances sont enregistrées. Après un certain temps, les traces de performances seront également visibles dans la console Firebase.
8. Déployez un deuxième modèle sur Firebase ML
Lorsque nous proposons une nouvelle version de votre modèle, par exemple une version avec une meilleure architecture de modèle ou une version formée sur un ensemble de données plus grand ou mis à jour, nous pouvons être tentés de remplacer notre modèle actuel par la nouvelle version. Cependant, un modèle performant lors des tests ne fonctionne pas nécessairement aussi bien en production. Faisons donc des tests A/B en production pour comparer notre modèle d'origine et le nouveau.
Activer l'API de gestion des modèles Firebase
Dans cette étape, nous allons permettre à l'API Firebase Model Management de déployer une nouvelle version de notre modèle TensorFlow Lite à l'aide du code Python.
Créez un bucket pour stocker vos modèles ML
Dans votre console Firebase, accédez à Stockage et cliquez sur Commencer.
Suivez la boîte de dialogue pour configurer votre bucket.
Activer l'API Firebase ML
Accédez à la page API Firebase ML sur Google Cloud Console et cliquez sur Activer.
Sélectionnez l'application Digit Classifier lorsque vous y êtes invité.
Nous allons maintenant former une nouvelle version du modèle en utilisant un ensemble de données plus grand, puis nous le déploierons par programmation directement à partir du bloc-notes de formation à l'aide du SDK Firebase Admin.
Téléchargez la clé privée du compte de service
Avant de pouvoir utiliser le SDK Firebase Admin, nous devrons créer un compte de service. Ouvrez le panneau Comptes de service de la console Firebase en cliquant sur ce lien et cliquez sur le bouton pour créer un nouveau compte de service pour le SDK d'administration Firebase. Lorsque vous y êtes invité, cliquez sur le bouton Générer une nouvelle clé privée. Nous utiliserons la clé du compte de service pour authentifier nos demandes à partir du notebook Colab.
Nous pouvons désormais former et déployer le nouveau modèle.
- Ouvrez ce notebook Colab et faites-en une copie sous votre propre Drive.
- Exécutez la première cellule « Former un modèle TensorFlow Lite amélioré » en cliquant sur le bouton de lecture à gauche de celle-ci. Cela entraînera la formation d'un nouveau modèle et peut prendre un certain temps.
- L'exécution de la deuxième cellule créera une invite de téléchargement de fichier. Téléchargez le fichier json que vous avez téléchargé depuis la console Firebase lors de la création de votre compte de service.
- Exécutez les deux dernières cellules.
Après avoir exécuté le notebook Colab, vous devriez voir un deuxième modèle dans la console Firebase. Assurez-vous que le deuxième modèle est nommé mnist_v2
.
9. Sélectionnez un modèle via Remote Config
Maintenant que nous avons deux modèles distincts, nous allons ajouter un paramètre permettant de sélectionner le modèle à télécharger au moment de l'exécution. La valeur du paramètre que le client reçoit déterminera le modèle que le client téléchargera. Tout d’abord, ouvrez la console Firebase et cliquez sur le bouton Remote Config dans le menu de navigation de gauche. Cliquez ensuite sur le bouton "Ajouter un paramètre".
Nommez le nouveau paramètre model_name
et donnez-lui une valeur par défaut de mnist_v1
. Cliquez sur Publier les modifications pour appliquer les mises à jour. En mettant le nom du modèle dans le paramètre de configuration distant, nous pouvons tester plusieurs modèles sans ajouter de nouveau paramètre pour chaque modèle que nous voulons tester.
Après avoir ajouté le paramètre, vous devriez le voir dans la console :
Dans notre code, nous devrons ajouter une vérification lors du chargement du modèle distant. Lorsque nous recevrons le paramètre de Remote Config, nous récupérerons le modèle distant avec le nom correspondant ; sinon nous tenterons de charger mnist_v1
. Avant de pouvoir utiliser Remote Config, nous devons l'ajouter à notre projet en le spécifiant comme dépendance dans le Podfile :
pod 'FirebaseRemoteConfig'
Exécutez l'installation du pod et rouvrez le projet Xcode. Dans ModelLoader.swift
, implémentez la méthode fetchParameterizedModel
.
static func fetchParameterizedModel(completion: @escaping (CustomModel?, DownloadError?) -> Void) { RemoteConfig.remoteConfig().fetchAndActivate { (status, error) in DispatchQueue.main.async { if let error = error { let compositeError = DownloadError.downloadFailed(underlyingError: error) completion(nil, compositeError) return } let modelName: String if let name = RemoteConfig.remoteConfig().configValue(forKey: "model_name").stringValue { modelName = name } else { let defaultName = "mnist_v1" print("Unable to fetch model name from config, falling back to default \(defaultName)") modelName = defaultName } downloadModel(named: modelName, completion: completion) } } }
Enfin, dans ViewController.swift
, remplacez l'appel downloadModel
par la nouvelle méthode que nous venons d'implémenter.
// Download the model from Firebase print("Fetching model...") ModelLoader.fetchParameterizedModel { (customModel, error) in guard let customModel = customModel else { if let error = error { print(error) } return } print("Model download complete") // Initialize a DigitClassifier instance DigitClassifier.newInstance(modelPath: customModel.path) { result in switch result { case let .success(classifier): self.classifier = classifier case .error(_): self.resultLabel.text = "Failed to initialize." } } }
Réexécutez l'application et assurez-vous qu'elle charge toujours correctement le modèle.
10. A/B Testez les deux modèles
Enfin, nous pouvons utiliser le comportement de test A/B intégré de Firebase pour voir lequel de nos deux modèles est le plus performant. Accédez à Analytics -> Événements dans la console Firebase. Si l'événement correct_inference
s'affiche, marquez-le comme "Événement de conversion", sinon, vous pouvez accéder à Analytics -> Événements de conversion et cliquer sur "Créer un nouvel événement de conversion" et inscrire correct_inference.
Allez maintenant dans "Remote Config dans la console Firebase, sélectionnez le bouton "A/B test" dans le menu Plus d'options sur le paramètre "model_name" que nous venons d'ajouter.
Dans le menu qui suit, acceptez le nom par défaut.
Sélectionnez votre application dans la liste déroulante et modifiez les critères de ciblage sur 50 % d'utilisateurs actifs.
Si vous avez pu définir l'événement correct_inference
comme conversion plus tôt, utilisez cet événement comme métrique principale à suivre. Sinon, si vous ne souhaitez pas attendre que l'événement apparaisse dans Analytics, vous pouvez ajouter correct_inference
manuellement.
Enfin, sur l'écran Variantes, définissez la variante de votre groupe de contrôle pour utiliser mnist_v1
et votre groupe Variante A pour utiliser mnist_v2
.
Cliquez sur le bouton Réviser dans le coin inférieur droit.
Félicitations, vous avez réussi à créer un test A/B pour vos deux modèles distincts ! Le test A/B est actuellement à l'état de brouillon et peut être démarré à tout moment en cliquant sur le bouton « Démarrer l'expérience ».
Pour un examen plus approfondi des tests A/B, consultez la documentation sur les tests A/B .
11. Conclusion
Dans cet atelier de programmation, vous avez appris à remplacer un élément tflite regroupé de manière statique dans votre application par un modèle TFLite chargé dynamiquement à partir de Firebase. Pour en savoir plus sur TFLite et Firebase, consultez d'autres exemples TFLite et les guides de démarrage de Firebase.
- Documentation sur l'apprentissage automatique Firebase
- Documentation TensorFlow Lite
- Modèles de tests A/B avec Firebase