Implementación de un modelo de aprendizaje automático con Docker - Parte 2



. OTUS Machine Learning: . , -, : « ML» « ».
En la primera parte de este tutorial, guardamos con éxito su modelo de clasificación en un directorio local y completamos todo el trabajo de desarrollo del modelo relacionado con Jupyter Notebook. A partir de ahora, la atención se centrará en implementar nuestro modelo. Para reutilizar el modelo para la predicción, simplemente puede cargarlo y llamar al método predict()como lo haría normalmente en un Jupyter Notebook.



Para probar el modelo, en la misma carpeta que el archivo model.pkl, cree un archivo main.pycon este código:



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))


Reutilización de modelos para la previsión.



Puede llamar al método predictor varias veces en observaciones desconocidas sin reiniciar el proceso de entrenamiento. Sin embargo, cuando ejecuta este archivo py en la terminal, puede encontrar un error como este:



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


Esto se debe a que el paquete que estamos utilizando no está disponible en el entorno en el que ejecuta el archivo. Esto significa que el entorno utilizado para desarrollar el modelo (conda) no es idéntico al tiempo de ejecución (entorno de Python fuera de conda) y esto puede verse como un problema potencial al ejecutar nuestro código en otros entornos. Específicamente quería que vieras este error, para ayudarte a comprender el problema y para volver a enfatizar la importancia de usar contenedores para implementar nuestro código y evitar tales problemas. Por ahora, puede simplemente instalar manualmente todos los paquetes necesarios usando el comando "pip install". Regresaremos aquí más tarde para hacer esto automáticamente.



Después de instalar todos los paquetes y ejecutar correctamente el archivo, el modelo debería devolver rápidamente el siguiente mensaje:



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


Como puede ver aquí, utilizamos datos desconocidos codificados para probar el modelo. Estos números representan la longitud del sépalo, su ancho, la longitud del pétalo y su ancho, respectivamente. Sin embargo, dado que queremos exponer nuestro modelo como un servicio, debe exponerse como una función que acepta solicitudes que contienen estos cuatro parámetros y devuelve un resultado de predicción. Luego, esta función puede usarse para un servidor de API (backend) o implementarse en un tiempo de ejecución sin servidor como Google Cloud Functions . En este tutorial, intentaremos construir un servidor API juntos y ponerlo en un contenedor Docker.






¿Cómo funciona la API?



Hablemos de cómo funcionan las aplicaciones web en la actualidad. La mayoría de las aplicaciones web tienen dos componentes principales que cubren casi toda la funcionalidad que necesita una aplicación: frontend y backend. La interfaz se centra en servir la interfaz (página web) al usuario, y el servidor de interfaz a menudo almacena HTML, CSS, JS y otros archivos estáticos como imágenes y sonidos. Por otro lado, el servidor backend manejará toda la lógica empresarial que responde a cualquier solicitud enviada desde el frontend.





Ilustración de la estructura de aplicaciones web .



Esto es lo que sucede cuando abres Medium en tu navegador.



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


Por supuesto, este podría no ser exactamente el mismo proceso que ocurre cuando se usa la aplicación web Medium y, de hecho, sería mucho más complicado que esto, pero este proceso simplificado puede ayudarlo a comprender cómo funciona una aplicación web.



Ahora quiero que se concentre en las flechas azules de la imagen de arriba. Se trata de solicitudes HTTP (enviadas desde el navegador) y respuestas HTTP (recibidas por el navegador o enviadas al navegador). Los componentes que procesan las solicitudes del navegador y devuelven respuestas al servidor backend se denominan "API".



A continuación se muestra la definición de API:





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

API!



Hay muchos marcos que nos ayudan a crear API con Python, incluidos Flask, Django, Pyramid, Falcon y Tornado. Las ventajas y desventajas, así como una comparación de estas estructuras, se enumeran aquí . Usaré Flask para este tutorial, pero la técnica y el flujo de trabajo siguen siendo los mismos que para los demás y, alternativamente, puedes usar tu marco favorito en este momento.



La última versión de Flask se puede instalar a través de pip usando este comando:



pip install Flask


Todo lo que necesita hacer ahora es convertir el código del paso anterior en una función y registrar un punto final de API después de inicializar su aplicación Flask. De forma predeterminada, una aplicación Flask se ejecuta en localhost (127.0.0.1) y escuchará las solicitudes en el puerto 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()


Representar su modelo como una API



En la terminal, debería ver lo siguiente:



* 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)


Abra su navegador e ingrese la siguiente consulta en la barra de direcciones:



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


Si aparece algo como esto en su navegador, ¡enhorabuena! Ahora está exponiendo su modelo de aprendizaje automático como un servicio con un punto final de API.



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


Pruebas de API con Postman



Recientemente usamos nuestro navegador para pruebas rápidas de API, pero esta no es una forma muy eficiente. Por ejemplo, no podríamos usar el método GET, sino el método POST con el token de autenticación en el encabezado, y no es fácil lograr que el navegador envíe dicha solicitud. En el desarrollo de software, Postman se usa ampliamente para probar API y es completamente gratuito para uso básico.





Interfaz de usuario de Postman (desde la página de descarga de Postman )

Después de descargar e instalar Postman, abra la herramienta y siga las instrucciones a continuación para enviar su solicitud.





Enviar una solicitud GET con Postman



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


Ahora que sabe cómo exponer su modelo de aprendizaje automático como un servicio a través de un punto final de API y probar ese punto final con Postma, el siguiente paso es contener su aplicación con Docker, donde veremos más de cerca cómo funciona Docker y cómo puede ayudarnos. resolver todos los problemas de dependencia que encontramos antes.



Lea la primera parte.



All Articles