Déployer un modèle d'apprentissage automatique avec Docker - Partie 2



. OTUS Machine Learning: . , -, : « ML» « ».
Dans la première partie de ce didacticiel, nous avons réussi à enregistrer votre modèle de classification dans un répertoire local et à terminer tout le travail de développement de modèle lié au bloc-notes Jupyter. Désormais, l'accent sera mis sur le déploiement de notre modèle. Pour réutiliser le modèle à des fins de prédiction, vous pouvez simplement le charger et appeler la méthode predict()comme vous le feriez normalement dans un Jupyter Notebook.



Afin de tester le modèle, dans le même dossier que le fichier model.pkl, créez un fichier main.pyavec ce code:



import pickle
#   ,     
import numpy as np
from sklearn.neighbors import KNeighborsClassifier

#    
with open('./model.pkl', 'rb') as model_pkl:
   knn = pickle.load(model_pkl)

#   (    )
unseen = np.array([[3.2, 1.1, 1.5, 2.1]])
result = knn.predict(unseen)

#    
print('Predicted result for observation ' + str(unseen) + ' is: ' + str(result))


Réutilisation du modèle pour la prévision.



Vous pouvez appeler la méthode de prédiction plusieurs fois pour des observations inconnues sans redémarrer le processus d'entraînement. Cependant, lorsque vous exécutez ce fichier py dans le terminal, vous pouvez rencontrer une erreur comme celle-ci:



Traceback (most recent call last):
 File "main.py", line 4, in <module>
   from sklearn.neighbors import KNeighborsClassifier
ImportError: No module named sklearn.neighbors


En effet, le package que nous utilisons n'est pas disponible dans l'environnement dans lequel vous exécutez le fichier. Cela signifie que l'environnement utilisé pour développer le modèle (conda) n'est pas identique au runtime (environnement python en dehors de conda) et cela peut être considéré comme un problème potentiel lors de l'exécution de notre code dans d'autres environnements. Je voulais spécifiquement que vous voyiez cette erreur, pour vous aider à comprendre le problème et pour souligner à nouveau l'importance d'utiliser des conteneurs pour déployer notre code afin d'éviter de tels problèmes. Pour l'instant, vous pouvez simplement installer manuellement tous les packages requis en utilisant la commande "pip install". Nous reviendrons ici plus tard pour le faire automatiquement.



Après avoir installé tous les packages et exécuté avec succès le fichier, le modèle doit rapidement renvoyer le message suivant:



Predicted result for observation [[3.2 1.1 1.5 2.1]] is: [1]


Comme vous pouvez le voir ici, nous utilisons des données inconnues codées en dur pour tester le modèle. Ces nombres représentent respectivement la longueur du sépale, sa largeur, la longueur du pétale et sa largeur. Cependant, puisque nous voulons exposer notre modèle en tant que service, il doit être exposé en tant que fonction qui accepte les requêtes contenant ces quatre paramètres et renvoie un résultat de prédiction. Cette fonction peut ensuite être utilisée pour un serveur d'API (backend) ou déployée dans un environnement d'exécution sans serveur tel que Google Cloud Functions . Dans ce didacticiel, nous allons essayer de créer un serveur API ensemble et de le placer dans un conteneur Docker.






Comment fonctionne l'API?



Parlons du fonctionnement des applications Web aujourd'hui. La plupart des applications Web ont deux composants principaux qui couvrent presque toutes les fonctionnalités dont une application a besoin: frontend et backend. Le frontend se concentre sur le service de l'interface (page Web) pour l'utilisateur, tandis que le serveur frontal stocke souvent HTML, CSS, JS et d'autres fichiers statiques tels que des images et des sons. D'autre part, le serveur principal gérera toute la logique métier qui répond à toutes les demandes envoyées depuis le frontend.





Illustration de la structure des applications Web .



C'est ce qui se passe lorsque vous ouvrez Medium dans votre navigateur.



  1. HTTP- medium.com. DNS-, , . ., .
  2. * .html, * .css, * .js , - .
  3. Medium . , «clap» () .
  4. (javascript) HTTP- id . URL- , . id XXXXXXX.
  5. (, ) .
  6. .
  7. , .


Bien sûr, ce n'est peut-être pas exactement le même processus que celui qui se produit lors de l'utilisation de l'application Web Medium, et en fait, ce serait beaucoup plus compliqué que cela, mais ce processus simplifié peut vous aider à comprendre le fonctionnement d'une application Web.



Maintenant, je veux que vous vous concentriez sur les flèches bleues dans l'image ci-dessus. Il s'agit des requêtes HTTP (envoyées depuis le navigateur) et des réponses HTTP (reçues par le navigateur ou envoyées au navigateur). Les composants qui traitent les demandes du navigateur et renvoient les réponses au serveur principal sont appelés «API».



Voici la définition de l'API:





(API — application program interface) — , . , API , .

API!



Il existe de nombreux frameworks qui nous aident à créer des API avec Python, notamment Flask, Django, Pyramid, Falcon et Tornado. Les avantages et les inconvénients, ainsi qu'une comparaison de ces structures, sont énumérés ici . J'utiliserai Flask pour ce didacticiel, mais la technique et le flux de travail restent les mêmes que pour les autres, et vous pouvez également utiliser votre framework préféré à ce stade.



La dernière version de Flask peut être installée via pip à l'aide de cette commande:



pip install Flask


Tout ce que vous avez à faire maintenant est de transformer le code de l'étape précédente en fonction et d'enregistrer un point de terminaison d'API après l'initialisation de votre application Flask. Par défaut, une application Flask s'exécute sur localhost (127.0.0.1) et écoutera les requêtes sur le port 5000.



import pickle
#   ,     
import numpy as np
import sys
from sklearn.neighbors import KNeighborsClassifier

#  Flask   API
from flask import Flask, request

#      
with open('./model.pkl', 'rb') as model_pkl:
   knn = pickle.load(model_pkl)

#   Flask
app = Flask(__name__)

#    API
@app.route('/predict')
def predict_iris():
   #     
   sl = request.args.get('sl')
   sw = request.args.get('sw')
   pl = request.args.get('pl')
   pw = request.args.get('pw')

#    predict 
#     
   unseen = np.array([[sl, sw, pl, pw]])
   result = knn.predict(unseen)
  #   
   return 'Predicted result for observation ' + str(unseen) + ' is: ' + str(result)
if __name__ == '__main__':
   app.run()


Représenter votre modèle en tant qu'API



Sur le terminal, vous devriez voir ce qui suit:



* Serving Flask app "main" (lazy loading)
* Environment: production
  WARNING: This is a development server. Do not use it in a production deployment.
  Use a production WSGI server instead.
* Debug mode: off
* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)


Ouvrez votre navigateur et entrez la requête suivante dans la barre d'adresse:



http://localhost:5000/predict?sl=3.2&sw=1.1&pl=1.5&pw=2.1


Si quelque chose comme ça apparaît dans votre navigateur, félicitations! Vous exposez maintenant votre modèle d'apprentissage automatique en tant que service avec un point de terminaison d'API.



Predicted result for observation [['3.2' '1.1' '1.5' '2.1']] is: [1]


Test d'API avec Postman



Nous avons récemment utilisé notre navigateur pour tester rapidement l'API, mais ce n'est pas un moyen très efficace. Par exemple, nous ne pourrions pas utiliser la méthode GET, mais plutôt utiliser la méthode POST avec le jeton d'authentification dans l'en-tête, et il n'est pas facile de faire en sorte que le navigateur envoie une telle requête. Dans le développement de logiciels, Postman est largement utilisé pour tester les API et est entièrement gratuit pour une utilisation de base.





Interface utilisateur de Postman (à partir de la page de téléchargement de Postman )

Après avoir téléchargé et installé Postman, ouvrez l'outil et suivez les instructions ci-dessous pour soumettre votre demande.





Envoi d'une demande GET avec Postman



  1. , GET , API GET . , POST .
  2. URL .
  3. . , .
  4. «», API.
  5. .
  6. HTTP-. .


Maintenant que vous savez comment exposer votre modèle d'apprentissage automatique en tant que service via un point de terminaison d'API et tester ce point de terminaison avec Postma, l'étape suivante consiste à conteneuriser votre application avec Docker, où nous examinerons de plus près le fonctionnement de Docker et comment il peut nous aider. résoudre tous les problèmes de dépendance que nous avons rencontrés auparavant.



Lisez la première partie.



All Articles