Intégrer un modèle personnalisé à votre application

1. Avant de commencer

Dans le premier atelier de cette série, vous avez créé une application très simple qui utilise l'étiquetage d'images pour analyser le contenu d'une image. Vous lui avez transmis une photo d'une marguerite et vous avez indiqué qu'elle avait vu des choses comme un pétale ou le ciel. Dans le deuxième atelier de programmation, vous êtes passé à Python pour entraîner un nouveau modèle personnalisé, capable de reconnaître cinq types de fleurs.

Dans cet atelier de programmation, vous allez mettre à jour l'application à partir du premier atelier avec le modèle de l'autre.

Vous pouvez obtenir le code source complet de cet atelier de programmation en clonant ce dépôt. Des sous-répertoires s'affichent pour Android et iOS. Le code de l'atelier de programmation précédent est disponible sous le nom ImageClassifierStep1 si vous souhaitez poursuivre. Le code final de cet atelier de programmation est disponible en tant que ImageClassifierStep2.

Prérequis

  • Vous devez avoir suivi les deux premiers ateliers de programmation de ce parcours de formation.

Objectifs de l'atelier

  • Intégrer un modèle personnalisé, entraîné dans l'atelier précédent, dans une application Android ou iOS

Prérequis

  • Android Studio, disponible sur developer.android.com/studio pour la partie Android de l'atelier
  • Xcode, disponible sur l'App Store d'Apple pour la partie iOS de l'atelier

2. Obtenir l'application de départ

Pour commencer, vous aurez besoin de l'application Créer votre première application de vision par ordinateur sur l'atelier de programmation Android ou iOS. Si vous avez déjà suivi l'atelier, il s'appelle ImageClassifierStep1. Si vous ne souhaitez pas suivre l'atelier, vous pouvez cloner la version terminée à partir du dépôt.

Ouvrez-le dans Android Studio, effectuez les mises à jour nécessaires et exécutez l'application pour vous assurer qu'elle fonctionne. Ce type de message s'affiche :

F3703D45d1332d1d.png

C'est une application primitive, mais elle offre quelques fonctionnalités très utiles avec seulement un peu de code. Cependant, si vous souhaitez que cette fleur soit reconnue en tant que marguerite, et pas seulement en tant que fleur, vous devez mettre à jour l'application afin d'utiliser votre modèle personnalisé à l'aide de l'outil "Créer un modèle personnalisé pour votre classificateur d'images".

3. Mettre à jour build.gradle pour utiliser les modèles de ML personnalisés

  1. Dans Android Studio, recherchez le fichier build.gradle au niveau de l'application. Pour ce faire, le moyen le plus simple consiste à utiliser l'explorateur de projets. Assurez-vous que Android est sélectionné en haut et qu'un dossier de scripts Gradle s'affiche en bas.
  2. Ouvrez celui associé au module, avec le nom de votre application suivi de ".app", comme indiqué ici (Module: ImageClassifierStep1.app):

8F1D04b40610047.png

  1. En bas du fichier, recherchez le paramètre dependencies. Vous devriez y trouver cette ligne:
implementation 'com.google.mlkit:image-labeling:17.0.1'

Le numéro de version peut être différent. Vous trouverez toujours le numéro de version le plus récent sur le site de ML Kit à l'adresse https://developers.google.com/ml-kit/vision/image-labeling/android.

  1. Remplacez ce code par la référence personnalisée de la bibliothèque d'étiquetage d'images. Le numéro de version est indiqué à l'adresse suivante: https://developers.google.com/ml-kit/vision/image-labeling/custom-models/android.
implementation 'com.google.mlkit:image-labeling-custom:16.3.1'
  1. Vous allez également ajouter le modèle .tflite que vous avez créé lors de l'atelier précédent. Vous ne voulez pas que ce modèle soit compressé lors de la compilation de votre application par Android Studio. Assurez-vous donc d'utiliser ce paramètre dans la section Android du même fichier build.gradle:
aaptOptions{
    noCompress "tflite"
}

Assurez-vous qu'il n'est pas dans un autre paramètre. Il doit être imbriqué directement sous la balise android. Exemple :

62d546bff11d2a50.png

4. Ajouter le modèle TFLite

Dans l'atelier de programmation précédent, vous avez créé votre modèle personnalisé et l'avez téléchargé en tant que model.tflite.

Dans votre projet, recherchez votre dossier assets qui contient actuellement flower1.jpg. Copiez le modèle dans ce dossier comme suit:

  1. Effectuez un clic droit sur le dossier Assets dans Android Studio. Dans le menu qui s'affiche, sélectionnez Afficher dans le Finder. ("Afficher dans l'explorateur" sous Windows et "Afficher dans Fichiers" sous Linux).

db30b47e419a326b.png

  1. Vous êtes alors redirigé vers le répertoire du système de fichiers. Copiez le fichier model.tflite dans ce répertoire avec flower1.jpg.

36de0c51bec1c19e.png

Android Studio affichera les deux fichiers dans votre dossier d'éléments:

e9f4e9f393d9b357.png

Vous êtes maintenant prêt à mettre à jour votre code.

5. Mettre à jour votre code pour le modèle personnalisé

La première étape consiste à ajouter du code pour charger le modèle personnalisé.

  1. Dans votre fichier MainActivity, ajoutez ce qui suit à votre onCreate, immédiatement en dessous de la ligne setContentView(R.layout.activity_main).

Cette commande utilise un LocalModel pour créer des modèles à partir de l'élément model.tflite. Si Android Studio se plaint en activant l'option "LocalModel" en rouge, appuyez sur Alt+Entrée pour importer la bibliothèque. Un fichier d'importation est alors ajouté à com.google.mlkit.common.model.LocalModel.

val localModel = LocalModel.Builder()
        .setAssetFilePath("model.tflite")
        .build()

Auparavant, dans votre gestionnaire btn.setOnClickListener, vous utilisiez le modèle par défaut. Il a été configuré avec le code suivant:

val labeler = ImageLabeling.getClient(ImageLabelerOptions.DEFAULT_OPTIONS)

Vous le remplacerez pour utiliser le modèle personnalisé.

  1. Configurez un objet d'options personnalisées:
val options = CustomImageLabelerOptions.Builder(localModel)
        .setConfidenceThreshold(0.7f)
        .setMaxResultCount(5)
        .build()

Les options par défaut seront remplacées par un ensemble personnalisé. Le seuil de confiance définit une barre pour la qualité des prédictions à afficher. Si vous reprenez l'exemple en haut de cet atelier de programmation, où l'image était une marguerite, vous aviez quatre prédictions, chacune avec une valeur, par exemple "Sky" étant .7632.

Vous pourriez ainsi éliminer efficacement les résultats de qualité inférieure en utilisant un seuil de confiance élevé. Par exemple, la valeur 0,9 ne renvoie pas de libellé dont la priorité est inférieure à cette valeur. Le setMaxResultCount() est utile dans les modèles comportant un grand nombre de classes, mais étant donné que ce modèle n'en compte que 5, vous n'aurez qu'à le définir sur 5.

Maintenant que vous avez les options pour l'étiqueteur, vous pouvez remplacer son instanciation par:

val labeler = ImageLabeling.getClient(options)

Le reste du code s'exécute sans le modifier. Essayez-les dès maintenant !

dd40c36c4edbb33.png

Comme vous pouvez le constater, cette fleur a été identifiée comme une marguerite avec une probabilité de 0,959.

Imaginons que vous ayez ajouté une deuxième image florale et que vous l'ayez exécutée précédemment:

8556a5fbea487842.png

comme une rose.

Vous vous demandez peut-être pourquoi elle indique roses plutôt que "rose". En effet, dans l'ensemble de données, les libellés sont indiqués par les noms des dossiers. Malheureusement, ces noms sont légèrement cohérents, et utilisent parfois le singulier (marguerite), et le pluriel, par exemple "roses". Ne le confondez pas avec le modèle qui tente de compter les éléments de l'image. Cette méthode est beaucoup plus primitive et ne peut identifier que les types de fleurs.

6. Télécharger l'application iOS Start

  1. Pour commencer, vous aurez besoin de l'application du premier atelier de programmation. Si vous avez déjà suivi l'atelier, il s'appelle ImageClassifierStep1. Si vous ne souhaitez pas suivre l'atelier, vous pouvez cloner la version terminée à partir du dépôt. Notez que les pods et l'extension .xcworkspace ne sont pas présents dans le dépôt. Veillez donc à exécuter "pod install" à partir du même répertoire que le projet ".xcproject" avant de passer à l'étape suivante.
  2. Ouvrez ImageClassifierStep1.xcworkspace dans Xcode. Vous devez utiliser le fichier .xcworkspace, et non le projet .xcproject, car vous avez fourni le ML avec des pods. L'espace de travail charge ces fichiers.

Dans la suite de cet atelier, je vais exécuter l'application dans le simulateur d'iPhone pour que les cibles de compilation puissent être utilisées. Si vous souhaitez utiliser votre propre appareil, vous devrez peut-être modifier la cible de compilation dans les paramètres de votre projet pour qu'elle corresponde à votre version d'iOS.

Exécutez-le pour obtenir le résultat suivant:

9e151ed18f99fb98.png

Notez les classifications très génériques : rose pétale, fleur, ciel. Le modèle que vous avez créé dans l'atelier de programmation précédent a été entraîné pour détecter cinq variétés de fleurs, dont celle-ci : une marguerite.

Dans la suite de cet atelier de programmation, vous apprendrez comment mettre à jour votre application avec le modèle personnalisé.

7. Utiliser des pods d'étiquettes d'images de ML personnalisés

La première application a utilisé un fichier de pod pour obtenir les bibliothèques et le modèle de base de ML Kit Image Labeler. Vous devrez le mettre à jour pour utiliser les bibliothèques d'étiquetage d'images personnalisées.

  1. Recherchez le fichier nommé podfile dans le répertoire de votre projet. Ouvrez-le. Vous devriez obtenir un écran semblable à celui-ci:
platform :ios, '10.0'

target 'ImageClassifierStep1' do
        pod 'GoogleMLKit/ImageLabeling'
end
  1. Remplacez la déclaration du pod ImageLabeling par ImageLabelingCustom, comme suit:
platform :ios, '10.0'

target 'ImageClassifierStep1' do
        pod 'GoogleMLKit/ImageLabelingCustom'
end
  1. Une fois que vous avez terminé, utilisez le terminal pour accéder au répertoire contenant le fichier pod, ainsi que le fichier .xcworkspace, et exécutez pod install.

bb5d78eb7c7ab975.png

Après quelques instants, les bibliothèques MLKitImageLabeling seront supprimées, et les bibliothèques personnalisées auront été ajoutées. Vous pouvez maintenant ouvrir votre fichier .xcworkspace pour modifier votre code.

8. Ajouter le modèle TFLite à Xcode

Dans l'atelier de programmation précédent, vous avez créé un modèle personnalisé et l'avez téléchargé en tant que model.tflite. Si vous ne l'avez pas en main, revenez à cet atelier de programmation ou passez en revue le code Colab en cliquant ici. Si vous n'avez pas accès à Google Colab, le notebook est disponible via ce lien.

  1. Avec l'espace de travail ouvert dans Xcode, faites glisser model.tflite sur votre projet. Il doit se trouver dans le même dossier que vos autres fichiers, par exemple ViewController.swift ou Main.storyboard.
  2. Une boîte de dialogue s'affiche avec des options permettant d'ajouter le fichier. Assurez-vous que l'option Ajouter aux cibles est sélectionnée, sinon le modèle ne sera pas inclus dans l'application une fois déployé sur un appareil.

Notez que l'entrée "Add to Targets" (Ajouter aux cibles) comporte une classe ImageClassifierStep1 si vous avez commencé à partir de cette étape et poursuivez cet atelier étape par étape ou ImageImageifierStep2 (comme illustré) si vous passez au code final.

5b6a7f40c73f0f1f.png

Vous pourrez ainsi charger le modèle. Nous verrons comment procéder à l'étape suivante.

9. Mettre à jour votre code pour le modèle personnalisé

  1. Ouvrez votre fichier ViewController.swift. Il est possible qu'une erreur s'affiche lors de l'importation de MLKitImageLabeling en haut du fichier. En effet, vous avez supprimé les bibliothèques d'étiquettes d'images génériques lors de la mise à jour de votre fichier de pod. N'hésitez pas à supprimer cette ligne et procédez comme suit:
import MLKitVision
import MLKit
import MLKitImageLabelingCommon
import MLKitImageLabelingCustom

Il peut être facile de les lire rapidement si vous pensez qu'ils répètent le même code. Elle porte sur les termes "commun" et "personnalisé" à la fin du cours.

  1. Vous allez ensuite charger le modèle personnalisé que vous avez ajouté à l'étape précédente. Trouvez le funic getLabels(). Sous la ligne visionImage.orientation = image.imageOrientation, ajoutez les lignes suivantes:
// Add this code to use a custom model
let localModelFilePath = Bundle.main.path(forResource: "model", ofType: "tflite")
let localModel = LocalModel(path: localModelFilePath!)
  1. Trouver le code permettant de spécifier les options pour l'ImageLabeler générique Elle risque de générer une erreur, car les bibliothèques ont été supprimées en conséquence:
let options = ImageLabelerOptions()

Remplacez-le par ce code pour utiliser une CustomImageLabelerOptions qui spécifie le modèle local:

let options = CustomImageLabelerOptions(localModel: localModel)

...Voilà ! Essayez d'exécuter votre application. Lorsque vous essayez de classer l'image, celle-ci doit être plus précise et vous dire que vous regardez une marguerite avec une probabilité élevée.

238cd21748a97cf4.png

Imaginons que vous ayez ajouté une deuxième image florale et que vous l'ayez exécutée précédemment:

75f3970a6b516bfe.png

L'application a détecté que cette image correspondait au libellé "roses".

10. Félicitations !

Vous allez à présent créer une application qui utilise un modèle générique pour reconnaître le contenu d'une image, puis créer votre propre modèle de ML pour reconnaître des éléments spécifiques, tels que des fleurs, puis mettre à jour votre application pour qu'elle utilise votre modèle personnalisé.

L'application obtenue est, bien sûr, très limitée, car elle repose sur des éléments image intégrés. Cependant, cette partie du ML fonctionne bien. Vous pouvez, par exemple, utiliser l'appareil photo AndroidX pour prendre des images d'un flux en direct et les classer afin de voir quelles fleurs votre téléphone reconnaît !

Les possibilités sont infinies. Et si vous avez vos propres données autrement que des fleurs, vous avez les bases pour créer une application qui les reconnaît à l'aide de la vision par ordinateur. Ce ne sont que les premières étapes d'un monde bien plus vaste, et nous espérons que vous avez aimé passer à l'étape suivante.