Tutoriel : Appliquer des modèles Machine Learning dans Azure Functions avec Python et TensorFlow

Dans cet article, vous allez découvrir comment utiliser Python, TensorFlow et Azure Functions avec un modèle Machine Learning pour classifier une image en fonction de son contenu. Comme vous effectuez tout le travail localement et que vous ne créez aucune ressource Azure dans le cloud, aucun coût n’est à prévoir pour effectuer ce tutoriel.

  • Initialisez un environnement local pour le développement de fonctions Azure en Python.
  • Importez un modèle Machine Learning TensorFlow personnalisé dans une application de fonction.
  • Créez une API HTTP serverless pour classifier une image comme contenant un chien ou un chat.
  • Consommez l’API à partir d’une application web.

Prérequis

Vérification du prérequis

  1. Dans un terminal ou une fenêtre de commande, exécutez func --version pour vérifier que la version d’Azure Functions Core Tools est bien 2.7.1846 ou ultérieure.
  2. Exécutez python --version (Linux/MacOS) ou py --version (Windows) pour vérifier que votre version de Python est bien 3.7.x.

Cloner le dépôt du tutoriel

  1. Dans un fenêtre de terminal ou de commande, clonez le dépôt suivant en utilisant Git :

    git clone https://github.com/Azure-Samples/functions-python-tensorflow-tutorial.git
    
  2. Accédez au dossier et examinez son contenu.

    cd functions-python-tensorflow-tutorial
    
    • start est votre dossier de travail pour le tutoriel.
    • end est le résultat final et l’implémentation complète à titre de référence.
    • resources contient le modèle Machine Learning et les bibliothèques de helpers.
    • frontend est un site web qui appelle l’application de fonction.

Créer et activer un environnement virtuel Python

Accédez au dossier start, et exécutez les commandes suivantes pour créer et activer un environnement virtuel nommé .venv. Veillez à utiliser Python 3.7, qui est pris en charge par Azure Functions.

cd start
python -m venv .venv
source .venv/bin/activate

Si Python n’a pas installé le package venv sur votre distribution Linux, exécutez la commande suivante :

sudo apt-get install python3-venv

Vous devez exécuter toutes les commandes suivantes dans cet environnement virtuel activé. (Pour quitter l’environnement virtuel, exécutez deactivate.)

Créer un projet de fonctions local

Dans Azure Functions, un projet de fonction est un conteneur pour une ou plusieurs fonctions individuelles qui répond chacune à un déclencheur spécifique. Toutes les fonctions d’un projet partagent les mêmes configurations locales et d’hébergement. Dans cette section, vous créez un projet de fonction qui contient une seule fonction réutilisable nommée classify, qui fournit un point de terminaison HTTP. Vous y ajoutez du code spécifique dans une section ultérieure.

  1. Dans le dossier start, utilisez Azure Functions Core Tools pour initialiser une application de fonction Python :

    func init --worker-runtime python
    

    Après l’initialisation, le dossier start contient différents fichiers pour le projet, dont des fichiers de configuration nommés local.settings.json et host.json. Comme local.settings.json peut contenir des secrets téléchargés depuis Azure, le fichier est exclu par défaut du contrôle de code source dans le fichier .gitignore.

    Conseil

    Comme un projet de fonction est lié à un runtime spécifique, toutes les fonctions du projet doivent être écrites dans le même langage.

  2. Ajoutez une fonction à votre projet avec la commande suivante, où l’argument --name est le nom unique de votre fonction et où l’argument --template spécifie le déclencheur de la fonction. func new crée un sous-dossier correspondant au nom de la fonction qui contient un fichier de code approprié au langage choisi du projet et un fichier de configuration nommé function.json.

    func new --name classify --template "HTTP trigger"
    

    Cette commande crée un dossier correspondant au nom de la fonction, classify. Dans ce dossier se trouvent deux fichiers : __init__.py, qui contient le code de la fonction, et function.json, qui décrit le déclencheur de la fonction, et ses liaisons d’entrée et de sortie. Pour plus d’informations sur le contenu de ces fichiers, consultez Modèle de programmation dans le guide du développeur Python.

Exécuter la fonction localement

  1. Démarrez la fonction en démarrant l’hôte du runtime Azure Functions local dans le dossier start :

    func start
    
  2. Une fois que le point de terminaison classify apparaît dans la sortie, accédez à l’URL http://localhost:7071/api/classify?name=Azure. Le message « Hello Azure ! » devrait apparaître dans la sortie.

  3. Utilisez Ctrl-C pour arrêter l’hôte.

Importer le modèle TensorFlow et ajouter le code helper

Pour modifier la fonction classify de façon à classifier une image en fonction de son contenu, vous utilisez un modèle TensorFlow prédéfini qui a été entraîné avec le service Azure Custom Vision et exporté depuis celui-ci. Le modèle, qui est contenu dans le dossier resources de l’exemple que vous avez cloné précédemment, classifie une image selon qu’elle contient un chien ou un chat. Vous ajoutez ensuite du code helper et des dépendances à votre projet.

Pour générer votre propre modèle en utilisant le niveau gratuit du service Custom Vision, suivez les instructions de l’exemple de dépôt de projet.

Conseil

Si vous voulez héberger votre modèle TensorFlow indépendant de l’application de fonction, vous pouvez monter à la place un partage de fichiers contenant votre modèle dans votre application de fonction Linux. Pour en savoir plus, consultez Monter un partage de fichiers dans une application de fonction Python à l’aide d’Azure CLI.

  1. Dans le dossier start, exécutez la commande suivante pour copier les fichiers modèle dans le dossier classify. Veillez à inclure \* dans la commande.

    cp ../resources/model/* classify
    
  2. Vérifiez que le dossier classify contient les fichiers nommés model.pb et labels.txt. Si ce n’est pas le cas, vérifiez que vous avez exécuté la commande dans le dossier start.

  3. Dans le dossier start, exécutez la commande suivante pour copier un fichier avec le code helper dans le dossier classify :

    cp ../resources/predict.py classify
    
  4. Vérifiez que le dossier classify contient à présent un fichier nommé predict.py.

  5. Ouvrez start/requirements.txt dans un éditeur de texte et ajoutez les dépendances suivantes nécessaires au code helper :

    tensorflow==1.14
    Pillow
    requests
    
  6. Enregistrez requirements.txt.

  7. Installez les dépendances en exécutant la commande suivante dans le dossier start. L’installation peut prendre quelques minutes, pendant lesquelles vous pouvez modifier la fonction dans la section suivante.

    pip install --no-cache-dir -r requirements.txt
    

    Sur Windows, vous pouvez rencontrer l’erreur « Impossible d’installer les packages en raison d’une erreur EnvironmentError : [errno 2]. Pas de fichier ou de répertoire correspondant : », suivi d’un long chemin vers un fichier, comme sharded_mutable_dense_hashtable.cpython-37.pyc. En général, cette erreur se produit parce que la profondeur du chemin du dossier devient trop longue. Dans ce cas, définissez la clé de Registre HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\FileSystem@LongPathsEnabled sur 1 pour activer les chemins longs. Vous pouvez également vérifier où votre interpréteur Python est installé. Si cet emplacement a un chemin long, essayez en le réinstallant dans un dossier avec un chemin plus court.

Conseil

Lors de l’appel de predict.py pour effectuer sa première prédiction, une fonction nommée _initialize charge le modèle TensorFlow à partir du disque et le met en cache dans des variables globales. Cette mise en cache accélère les prédictions suivantes. Pour plus d’informations sur l’utilisation de variables globales, reportez-vous au Guide des développeurs Python sur Azure Functions.

Mettre à jour la fonction pour effectuer des prédictions

  1. Ouvrez le fichier classify/__init__.py dans un éditeur de texte et ajoutez les lignes suivantes après les instructions import existantes pour importer la bibliothèque JSON standard et les assistances predict :

    import logging
    import azure.functions as func
    import json
    
    # Import helper script
    from .predict import predict_image_from_url
    
  2. Remplacez tout le contenu de la fonction main par le code suivant :

    def main(req: func.HttpRequest) -> func.HttpResponse:
        image_url = req.params.get('img')
        logging.info('Image URL received: ' + image_url)
    
        results = predict_image_from_url(image_url)
    
        headers = {
            "Content-type": "application/json",
            "Access-Control-Allow-Origin": "*"
        }
    
        return func.HttpResponse(json.dumps(results), headers = headers)
    

    Cette fonction reçoit une URL d’image dans un paramètre de chaîne de requête nommé img. Elle appelle ensuite predict_image_from_url à partir de la bibliothèque de helpers pour télécharger et classifier l’image en utilisant le modèle TensorFlow. La fonction retourne ensuite une réponse HTTP avec les résultats.

    Important

    Comme ce point de terminaison HTTP est appelé par une page web hébergée sur un autre domaine, la réponse comprend un en-tête Access-Control-Allow-Origin pour satisfaire aux exigences CORS (Cross-Origin Resource Sharing) du navigateur.

    Dans une application de production, remplacez * par l’origine spécifique de la page web pour renforcer la sécurité.

  3. Enregistrez vos modifications puis, en supposant que l’installation des dépendances est terminée, redémarrez l’hôte de fonction local avec func start. Veillez à exécuter l’hôte dans le dossier start avec l’environnement virtuel activé. Sinon, l’hôte démarrera, mais vous verrez des erreurs lors de l’appel de la fonction.

    func start
    
  4. Dans un navigateur, ouvrez l’URL suivante pour appeler la fonction avec l’URL d’une image de chat et vérifiez que le JSON retourné classifie l’image comme étant un chat.

    http://localhost:7071/api/classify?img=https://raw.githubusercontent.com/Azure-Samples/functions-python-tensorflow-tutorial/master/resources/assets/samples/cat1.png
    
  5. Conservez l’hôte en cours d’exécution, car vous allez l’utiliser à l’étape suivante.

Exécuter le front-end de l’application web locale pour tester la fonction

Pour tester l’appel du point de terminaison de fonction à partir d’une autre application web, il existe une application simple dans le dossier frontend du référentiel.

  1. Ouvrez un nouveau terminal ou une invite de commandes, puis activez l’environnement virtuel (comme décrit précédemment sous Créer et activer un environnement virtuel Python).

  2. Accédez au dossier frontend du référentiel.

  3. Démarrez un serveur HTTP avec Python :

    python -m http.server
    
  4. Dans un navigateur, accédez à localhost:8000, puis entrez une des URL de photo suivantes dans la zone de texte ou utilisez l’URL de n’importe quelle image accessible publiquement.

    • https://raw.githubusercontent.com/Azure-Samples/functions-python-tensorflow-tutorial/master/resources/assets/samples/cat1.png
    • https://raw.githubusercontent.com/Azure-Samples/functions-python-tensorflow-tutorial/master/resources/assets/samples/cat2.png
    • https://raw.githubusercontent.com/Azure-Samples/functions-python-tensorflow-tutorial/master/resources/assets/samples/dog1.png
    • https://raw.githubusercontent.com/Azure-Samples/functions-python-tensorflow-tutorial/master/resources/assets/samples/dog2.png
  5. Sélectionnez Submit (Envoyer) pour appeler le point de terminaison de la fonction afin de classifier l’image.

    Screenshot of finished project

    Si le navigateur signale une erreur quand vous envoyez l’URL de l’image, vérifiez le terminal dans lequel vous exécutez l’application de fonction. Si vous voyez une erreur comme « Aucun module "PIL" trouvé », c’est que vous avez peut-être démarré l’application de fonction dans le dossier start sans activer au préalable l’environnement virtuel que vous avez créé précédemment. Si vous voyez encore des erreurs, réexécutez pip install -r requirements.txt avec l’environnement virtuel activé et regardez s’il y a des erreurs.

Notes

Le modèle classifie toujours le contenu de l’image en tant que chat ou chien, que l’image contienne l’un ou l’autre, en classifiant par défaut en tant que chien. Par exemple, les images de tigres et de panthères sont généralement classifiées en tant que chat, mais les images d’éléphants, de carottes ou d’avions sont classifiées en tant que chien.

Nettoyer les ressources

Comme l’intégralité de ce tutoriel s’exécute localement sur votre machine, il n’y a pas de ressources ni de services Azure à nettoyer.

Étapes suivantes

Dans ce tutoriel, vous avez découvert comment créer et personnaliser un point de terminaison d’API HTTP avec Azure Functions pour classifier des images en utilisant un modèle TensorFlow. Vous avez également découvert comment appeler l’API depuis une application web. Vous pouvez utiliser les techniques de ce tutoriel pour élaborer des API plus complexes, qui s’exécutent sur le modèle de calcul serverless fourni par Azure Functions.

Voir aussi :