Tutoriel de déploiement d'Edge sur Android

Objectifs du tutoriel

Dans ce tutoriel, vous allez télécharger un modèle TensorFlow Lite personnalisé, exporté et créé à l'aide d'AutoML Vision Edge. Vous exécuterez ensuite une application Android préconfigurée permettant d'identifier des images de fleurs à l'aide de ce modèle.

capture d'écran du produit final sur mobile
Crédit image : Felipe Venâncio, "du jardin de ma mère" (CC BY 2.0, image affichée dans l'application).

Objectifs

Dans ce tutoriel de présentation détaillé, vous allez utiliser du code pour effectuer les opérations suivantes :

  • Exécuter un modèle pré-entraîné dans une application Android à l'aide de l'interpréteur TFLite.

Avant de commencer

Entraîner un modèle à partir d'AutoML Vision Edge

Pour pouvoir déployer un modèle sur un appareil Edge, vous devez entraîner et exporter un modèle TF Lite à partir d'AutoML Vision Edge en suivant le guide de démarrage rapide des modèles des appareils Edge.

Une fois la procédure de démarrage rapide terminée, vous devez disposer des fichiers de modèle entraînés et exportés suivants : un fichier TF Lite, un fichier de libellés et un fichier de métadonnées, comme illustré ci-dessous.

fichiers de modèle TF Lite Cloud Storage

Installer TensorFlow

Avant de commencer le tutoriel, vous devez installer plusieurs éléments logiciels :

Si vous disposez d'une installation Python opérationnelle, exécutez les commandes suivantes pour télécharger le logiciel :

pip install --upgrade  "tensorflow==1.7.*"
pip install PILLOW

Si vous rencontrez des problèmes lors de cette procédure, consultez la documentation officielle de TensorFlow.

Cloner le dépôt Git

À l'aide de la ligne de commande, exécutez la commande suivante pour cloner le dépôt Git :

git clone https://github.com/googlecodelabs/tensorflow-for-poets-2

Accédez au répertoire du clone local du dépôt (répertoire tensorflow-for-poets-2). Vous exécuterez tous les exemples de code suivants à partir de ce répertoire :

cd tensorflow-for-poets-2

Configurer l'application Android

Installer Android Studio

Si nécessaire, installez Android Studio version 3.0 ou ultérieure en local.

Ouvrir le projet avec Android Studio

Pour ouvrir un projet avec Android Studio, procédez comme suit :

  1. Ouvrez Android Studio icône de démarrage d'Android Studio. Une fois le chargement terminé, sélectionnez icône d'ouverture de projet Android Studio Open an existing Android Studio project (Ouvrir un projet Android Studio existant) dans le pop-up suivant :

    pop-up d'ouverture de projet Android Studio

  2. Dans le sélecteur de fichiers, sélectionnez tensorflow-for-poets-2/android/tflite dans votre répertoire de travail.

  3. Lorsque vous ouvrez le projet pour la première fois, un pop-up "Gradle Sync" s'affiche. Il vous demande si vous souhaitez utiliser le wrapper Gradle. "Sélectionnez "OK".

    pop-up d'ouverture de projet Android Studio

Tester l'application

L'application peut être exécutée sur un appareil Android véritable ou dans l'émulateur Android Studio.

Configurer un appareil Android

Vous ne pouvez pas charger l'application sur votre téléphone depuis Android Studio, sauf si vous activez le mode développeur et le débogage USB.

Pour terminer cette procédure de configuration initiale, suivez ces instructions.

Configurer l'émulateur avec accès à la caméra (facultatif)

Si vous choisissez d'utiliser un émulateur au lieu d'un appareil Android véritable, Android Studio facilite la configuration de l'émulateur.

Étant donné que cette application utilise l'appareil photo, configurez l'appareil photo de l'émulateur pour qu'il utilise la caméra de votre ordinateur plutôt que le modèle de test par défaut.

Pour configurer l'appareil photo de l'émulateur, vous devez créer un appareil dans le service Android Virtual Device Manager (Gestionnaire des appareils virtuels Android). Vous pouvez y accéder à l'aide du bouton icône du gestionnaire des appareils virtuels. Depuis la page principale du service, sélectionnez Create Virtual Device (Créer un appareil virtuel) :

option de création d'un d'appareil virtuel Android Studio

Puis, sur la dernière page de la configuration de l'appareil virtuel intitulée "Verify Configuration" (Vérifier la configuration), sélectionnez "Show Advanced Settings" (Afficher les paramètres avancés) :

option de création d'un d'appareil virtuel Android Studio

Une fois les paramètres avancés affichés, vous pouvez configurer les deux sources d'appareil photo pour qu'elles utilisent la webcam de l'ordinateur hôte :

option de choix de la source de l'appareil photo Android Studio

Exécuter l'application d'origine

Avant d'apporter des modifications à l'application, exécutez la version fournie avec le dépôt.

Pour démarrer le processus de compilation et d'installation, exécutez une synchronisation Gradle.

icône de synchronisation Gradle

Après avoir exécuté une synchronisation Gradle, sélectionnez l'icône de lecture icône de lecture Android Studio.

Vous devez ensuite sélectionner votre appareil dans le pop-up suivant :

pop-up de sélection de l'appareil

Après avoir sélectionné votre appareil, vous devez autoriser la démonstration Tensorflow à accéder à votre appareil photo et à vos fichiers :

pop-up d'autorisation d'accès à la caméra

L'application est maintenant installée. Cliquez sur l'icône de l'application icône de l'application Android Studio pour la lancer. Cette version de l'application utilise la version standard de MobileNet, pré-entraînée sur les 1 000 catégories ImageNet.

Voici un exemple :

Test de l'application

Exécuter l'application personnalisée

La configuration par défaut de l'application permet de classer les images dans l'une des 1 000 classes ImageNet à l'aide de la version standard de MobileNet, sans qu'un nouvel entraînement ne soit nécessaire.

Apportez maintenant les modifications requises afin que l'application utilise un modèle créé par AutoML Vision Edge pour vos catégories d'images personnalisées.

Ajouter les fichiers de modèle au projet

Le projet de démonstration est configuré pour rechercher un fichier graph.lite et un fichier labels.txt dans le répertoire android/tflite/app/src/main/assets/.

Remplacez les deux fichiers d'origine par vos versions avec les commandes suivantes :

cp [Downloads]/model.tflite android/tflite/app/src/main/assets/graph.lite
cp [Downloads]/dict.txt  android/tflite/app/src/main/assets/labels.txt

Modifier l'application

Cette application utilise un modèle float, tandis que celui créé par AutoML Vision Edge est un modèle quantifié. Vous devez modifier le code pour permettre à l'application d'utiliser ce modèle.

Changez le type de données de labelProbArray et filterLabelProbArray de float à byte dans la définition de membre de classe et dans l'initialiseur ImageClassifier.

private byte[][] labelProbArray = null;
private byte[][] filterLabelProbArray = null;

labelProbArray = new byte[1][labelList.size()];
filterLabelProbArray = new byte[FILTER_STAGES][labelList.size()];

Attribuez la valeur imgData en fonction du type int8 dans l'initialiseur ImageClassifier.

    imgData =
        ByteBuffer.allocateDirect(
            DIM_BATCH_SIZE * DIM_IMG_SIZE_X * DIM_IMG_SIZE_Y * DIM_PIXEL_SIZE);

Faites passer le type de données de labelProbArray de int8 à float dans printTopKLabels() :

  private String printTopKLabels() {
    for (int i = 0; i < labelList.size(); ++i) {
      sortedLabels.add(
          new AbstractMap.SimpleEntry<>(labelList.get(i), (float)labelProbArray[0][i]));
      if (sortedLabels.size() > RESULTS_TO_SHOW) {
        sortedLabels.poll();
      }
    }
    String textToShow = "";
    final int size = sortedLabels.size();
    for (int i = 0; i < size; ++i) {
      Map.Entry<String, Float> label = sortedLabels.poll();
      textToShow = String.format("\n%s: %4.2f",label.getKey(),label.getValue()) + textToShow;
    }
    return textToShow;
  }

Exécuter l'application

Dans Android Studio, exécutez une synchronisation Gradle afin que le système de compilation puisse trouver vos fichiers :

icône de synchronisation Gradle

Après avoir exécuté une synchronisation Gradle, sélectionnez l'icône de lecture icône de lecture Android Studio pour lancer le processus de compilation et d'installation comme auparavant.

Voici un exemple :

capture d'écran du produit final sur mobile
Crédit image : Felipe Venâncio, "du jardin de ma mère" (CC BY 2.0, image affichée dans l'application).

Vous pouvez appuyer sur les boutons Marche/Arrêt et Volume- pendant quelques secondes pour faire une capture d'écran.

Testez l'application mise à jour en pointant l'appareil photo vers différentes images de fleurs pour voir si elles sont classées correctement.

Fonctionnement

Maintenant que l'application est en cours d'exécution, examinez le code propre à TensorFlow Lite.

AAR Android – TensorFlow

Cette application utilise une archive Archive Android (AAR) TFLite précompilée. Cette archive AAR est hébergée sur jcenter.

Les lignes suivantes du fichier build.gradle du module incluent la version la plus récente de l'AAR du dépôt maven bintray TensorFlow du projet.

build.gradle

repositories {
    maven {
        url 'https://google.bintray.com/tensorflow'
    }
}

dependencies {
    // ...
    compile 'org.tensorflow:tensorflow-lite:+'
}

Le bloc suivant permet d'indiquer à Android Asset Packaging Tool que les éléments .lite et .tflite ne doivent pas être compressés. Cette instruction est importante, car le fichier .lite sera mappé en mémoire, ce qui ne fonctionne pas lorsque le fichier est compressé.

build.gradle

android {
    aaptOptions {
        noCompress "tflite"
        noCompress "lite"
    }
}

Utiliser l'API Java TFLite

Le code d'interface avec TFLite est contenu dans ImageClassifier.java.

Prérequis

Le premier bloc de code présentant un certain intérêt est le constructeur de ImageClassifier :

ImageClassifier.java

ImageClassifier(Activity activity) throws IOException {
    tflite = new Interpreter(loadModelFile(activity));
    labelList = loadLabelList(activity);
    imgData =
        ByteBuffer.allocateDirect(
            4 * DIM_BATCH_SIZE * DIM_IMG_SIZE_X * DIM_IMG_SIZE_Y * DIM_PIXEL_SIZE);
    imgData.order(ByteOrder.nativeOrder());
    labelProbArray = new float[1][labelList.size()];
    Log.d(TAG, "Created a Tensorflow Lite Image Classifier.");
}

Quelques lignes présentent un intérêt particulier.

La ligne suivante crée l'interpréteur TFLite :

ImageClassifier.java

tflite = new Interpreter(loadModelFile(activity));

Cette ligne instancie un interpréteur TFLite. L'interpréteur fonctionne de manière semblable à tf.Session (pour ceux qui connaissent TensorFlow, en dehors de TFLite). Vous transmettez à l'interpréteur un MappedByteBuffer contenant le modèle. La fonction locale loadModelFile crée un MappedByteBuffer contenant le fichier d'éléments graph.lite de l'activité.

Les lignes suivantes créent le tampon de données d'entrée :

ImageClassifier.java

imgData = ByteBuffer.allocateDirect(
    4 * DIM_BATCH_SIZE * DIM_IMG_SIZE_X * DIM_IMG_SIZE_Y * DIM_PIXEL_SIZE);

Ce tampon d'octets est dimensionné pour contenir les données d'image une fois celles-ci converties en float. L'interpréteur peut accepter directement des tableaux à virgule flottante en tant qu'entrée, mais le paramètre ByteBuffer est plus efficace car il évite la présence de données redondantes dans l'interpréteur.

Les lignes suivantes chargent la liste de libellés et créent le tampon de sortie :

labelList = loadLabelList(activity);
//...
labelProbArray = new float[1][labelList.size()];

Le tampon de sortie est un tableau à virgule flottante comprenant un élément pour chaque libellé. Le modèle y écrit les probabilités de sortie.

Exécuter le modèle

Le deuxième bloc présentant un certain intérêt est la méthode classifyFrame. Elle prend un Bitmap en entrée, exécute le modèle et renvoie le texte à afficher dans l'application.

ImageClassifier.java

String classifyFrame(Bitmap bitmap) {
 // ...
 convertBitmapToByteBuffer(bitmap);
 // ...
 tflite.run(imgData, labelProbArray);
 // ...
 String textToShow = printTopKLabels();
 // ...
}

Cette méthode remplit trois fonctions. Tout d'abord, la méthode convertit et copie l'entrée Bitmap dans le imgData ByteBuffer pour la saisir dans le modèle. Ensuite, elle appelle la méthode d'exécution de l'interpréteur, en transmettant le tampon d'entrée et le tableau de sortie en tant qu'arguments. L'interpréteur définit les valeurs du tableau de sortie sur la probabilité calculée pour chaque classe. Les nœuds d'entrée et de sortie sont définis par les arguments de l'étape de conversion toco qui a créé le fichier de modèle .lite précédemment.

Étapes suivantes

Vous avez à présent terminé cette procédure d'utilisation d'un modèle Edge pour une application Android de classification de fleurs. Vous avez testé une application de classification d'images, vous l'avez modifiée, puis vous avez obtenu des exemples d'annotations. Vous avez ensuite examiné le code propre à TensorFlow Lite afin d'en comprendre les fonctionnalités sous-jacentes.