TensorFlow.js: Convierte un modelo guardado de Python en un formato de TensorFlow.js

1. Introducción

Ya diste tus primeros pasos con TensorFlow.js, probaste nuestros modelos prediseñados o, tal vez, creaste los tuyos propios. Pero viste algunas investigaciones de vanguardia en Python y quieres saber si se ejecutará en el navegador web para hacer realidad esa idea genial que te habías convertido en realidad para millones de personas de forma escalable. ¿Le resulta conocido? Si es así, este es el codelab para ti.

El equipo de TensorFlow.js creó una herramienta conveniente para convertir los modelos que están en el formato de SavedModel en TensorFlow.js a través de un conversor de línea de comandos, de modo que pueda disfrutar de estos modelos con el alcance y escala de la Web.

Qué aprenderás

En este codelab, aprenderás a usar el conversor de línea de comandos de TensorFlow.js para transferir un modelo guardado generado por Python al formato model.json que se requiere para su ejecución por parte del cliente en un navegador web.

En particular, haz lo siguiente:

  • Cómo crear un modelo simple de AA de Python y guardarlo en el formato requerido por el conversor de TensorFlow.js
  • Cómo instalar y usar el conversor de TensorFlow.js en el modelo guardado que exportaste desde Python.
  • Toma los archivos resultantes de la conversión y úsalos en tu aplicación web de JS.
  • Comprende qué hacer cuando algo sale mal (no todos los modelos generarán conversiones) y qué opciones tienes.

Imagina poder realizar una investigación reciente y poner ese modelo a disposición de millones de desarrolladores de JS de todo el mundo. O quizás tú mismo lo usarás en tu propia creación, algo que cualquier persona en el mundo puede experimentar si se ejecuta en el navegador web, ya que no se requieren dependencias complejas ni una configuración del entorno. ¿Todo listo para comenzar a hackear? ¡Vamos!

Comparte con nosotros lo que generas

Puede usar lo que aprendimos hoy para convertir algunos de sus modelos favoritos de Python. Si logras hacerlo con éxito y creas un sitio web de demostración que funciona del modelo en acción, etiquétalo en las redes sociales con el hashtag #MadeWithTFJS para tener la oportunidad de que tu proyecto se destaque en nuestro blog de TensorFlow o incluso en futuros eventos de mostrar y contar. Nos encantaría ver más investigaciones sorprendentes que se trasladan a la Web y permitir que más personas usen estos modelos de formas innovadoras o creativas, como este gran ejemplo.

2. ¿Qué es TensorFlow.js?

1aee0ede85885520.png

TensorFlow.js es una biblioteca de aprendizaje automático de código abierto que se puede ejecutar en cualquier lugar que pueda JavaScript. Se basa en la biblioteca original de TensorFlow escrita en Python y tiene como objetivo recrear esta experiencia de desarrollador y el conjunto de APIs para el ecosistema de JavaScript.

¿Dónde se puede utilizar?

Dada la portabilidad de JavaScript, ahora puedes escribir en 1 lenguaje y realizar el aprendizaje automático en todas las siguientes plataformas con facilidad:

  • Del lado del cliente en el navegador web con JavaScript convencional
  • En el servidor y también en dispositivos de IoT como Raspberry Pi con Node.js
  • Apps de escritorio que usan Electron
  • Apps nativas para dispositivos móviles con React Native

TensorFlow.js también admite múltiples backends dentro de cada uno de estos entornos (los entornos reales basados en hardware que puede ejecutar dentro de él, como la CPU o WebGL). Un "backend" en este contexto no significa un entorno del servidor: el backend para la ejecución podría ser del cliente en WebGL, por ejemplo, para garantizar la compatibilidad y también mantener el funcionamiento rápido. En la actualidad, TensorFlow.js admite lo siguiente:

  • Ejecución de WebGL en la tarjeta gráfica del dispositivo (GPU): Es la forma más rápida de ejecutar modelos más grandes (más de 3 MB de tamaño) con aceleración de GPU.
  • Ejecución de Web Assembly (WASM) en la CPU: Para mejorar el rendimiento de la CPU en todos los dispositivos, incluidos, por ejemplo, los teléfonos celulares de generaciones anteriores. Esto es más adecuado para modelos más pequeños (menos de 3 MB de tamaño) que pueden ejecutarse más rápido en la CPU con WASM que con WebGL debido a la sobrecarga que implica subir contenido a un procesador de gráficos.
  • Ejecución de CPU: El resguardo no debe estar disponible ninguno de los otros entornos. Esta es la más lenta de las tres, pero siempre está ahí para ti.

Nota: Puedes optar por forzar uno de estos backends si sabes en qué dispositivo lo ejecutarás o, si no lo especificas, puedes dejar que TensorFlow.js decida por ti.

Superpoderes del cliente

La ejecución de TensorFlow.js en el navegador web de la máquina cliente puede generar varios beneficios que vale la pena considerar.

Privacidad

Puedes entrenar y clasificar datos en la máquina cliente sin tener que enviarlos a un servidor web de terceros. En algunas ocasiones, esto puede ser un requisito para cumplir con las leyes locales, como el GDPR, o cuando se procesan datos que el usuario quiere conservar en su máquina y no se envían a un tercero.

Velocidad

Como no tienes que enviar datos a un servidor remoto, la inferencia (el acto de clasificar los datos) puede ser más rápida. Aún mejor, tienes acceso directo a los sensores del dispositivo, como la cámara, el micrófono, el GPS, el acelerómetro y otros, si el usuario te otorga el acceso.

Alcance y escala

Con un solo clic, cualquier persona en el mundo puede hacer clic en el vínculo que le envías, abrir la página web en su navegador y usar lo que has hecho. No se necesita una compleja configuración de Linux en el servidor con controladores CUDA y mucho más solo para usar el sistema de aprendizaje automático.

Costo

Sin servidores significa que lo único que debes pagar es una CDN para alojar tus archivos HTML, CSS, JS y de modelo. El costo de una CDN es mucho más económico que mantener un servidor (posiblemente con una tarjeta gráfica adjunta) en funcionamiento las 24 horas, todos los días.

Funciones del servidor

Aprovechar la implementación de Node.js de TensorFlow.js habilita las siguientes funciones.

Compatibilidad total con CUDA

En el lado del servidor, para acelerar la tarjeta gráfica, debes instalar los controladores CUDA de NVIDIA para permitir que TensorFlow funcione con la tarjeta gráfica (a diferencia del navegador que usa WebGL, no es necesario instalarlo). Sin embargo, gracias a la total compatibilidad con CUDA, puedes aprovechar al máximo las capacidades de nivel inferior de la tarjeta gráfica, lo que agiliza los tiempos de inferencia y entrenamiento. El rendimiento está a la par con la implementación de TensorFlow en Python, ya que ambas comparten el mismo backend de C++.

Tamaño del modelo

Para modelos de vanguardia de la investigación, es posible que se trabaje con modelos muy grandes, quizás de gigabytes. Actualmente, estos modelos no se pueden ejecutar en el navegador web debido a las limitaciones del uso de memoria por pestaña del navegador. Para ejecutar estos modelos más grandes, puedes usar Node.js en tu propio servidor con las especificaciones de hardware que necesitas para ejecutar un modelo de este tipo de manera eficiente.

IoT

Node.js es compatible con computadoras de placa única populares como Raspberry Pi, lo que, a su vez, significa que también puedes ejecutar modelos de TensorFlow.js en esos dispositivos.

Velocidad

Node.js está escrito en JavaScript, lo que significa que se beneficia de una compilación inmediata. Esto significa que, a menudo, puedes ver mejoras en el rendimiento cuando usas Node.js, ya que se optimizará en el entorno de ejecución, especialmente para cualquier procesamiento previo que realices. Un excelente ejemplo de esto se puede observar en este caso de éxito, en el que se muestra cómo Hugging Face usó Node.js para duplicar el rendimiento de su modelo de procesamiento de lenguaje natural.

Ahora que comprendes los conceptos básicos de TensorFlow.js, dónde se puede ejecutar y algunos de sus beneficios, comencemos a hacer cosas útiles con él.

3. Cómo configurar tu sistema

En este instructivo, usaremos Ubuntu, una distribución popular de Linux que se usa mucho y que está disponible en Compute Engine de Google Cloud como imagen base si eliges seguir el proceso en una máquina virtual basada en la nube.

Al momento de escribir, podemos seleccionar la imagen de Ubuntu 18.04.4 LTS cuando creemos una nueva instancia normal de Compute Engine, que es lo que usaremos. Por supuesto, puedes usar tu propia máquina o incluso un sistema operativo diferente si así lo deseas, pero las instrucciones de instalación y las dependencias pueden diferir entre los sistemas.

Instalar TensorFlow (versión de Python)

Entonces, como seguramente intentas convertir algún modelo basado en Python existente que encontraste o que escribirás, antes de que podamos exportar un “modelo guardado” de Python, deberás tener configurada la versión de TensorFlow de Python en tu instancia si el “modelo guardado” aún no está disponible para descargar.

Establece una conexión SSH a la máquina en la nube que creaste anteriormente y, luego, escribe lo siguiente en la ventana de la terminal:

Ventana de terminal:

sudo apt update
sudo apt-get install python3

Esto garantizará que Python 3 esté instalado en la máquina. Debes instalar Python 3.4 o superior para usar TensorFlow.

Para verificar que esté instalada la versión correcta, escribe lo siguiente:

Ventana de terminal:

python3 --version

Deberías ver un resultado que indique el número de versión, como Python 3.6.9. Si ves que se imprimió correctamente y es superior a 3.4, estamos listos para continuar.

A continuación, instalaremos PIP para Python 3, que es el administrador de paquetes de Python, y lo actualizaremos. Tipo:

Ventana de terminal:

sudo apt install python3-pip
pip3 install --upgrade pip

Nuevamente, podemos verificar la instalación de pip3 a través de lo siguiente:

Ventana de terminal:

pip3 --version

Cuando se escribe este código, vemos que se imprime pip 20.2.3 en la terminal después de ejecutar este comando.

Antes de que podamos instalar TensorFlow, es necesario el paquete de Python "setuptools" versión 41.0.0 o superior. Ejecuta el siguiente comando para asegurarte de que esté actualizado a la versión más reciente:

Ventana de terminal:

pip3 install -U setuptools

Por último, podemos instalar TensorFlow para Python:

Ventana de terminal:

pip3 install tensorflow

Este proceso puede tardar un poco en completarse, así que espera hasta que termine de ejecutarse.

Comprobemos que TensorFlow esté instalado correctamente. Crea un archivo de Python llamado test.py en el directorio actual:

Ventana de terminal:

nano test.py

Una vez que se abre nano, podemos escribir código de Python para imprimir la versión de TensorFlow instalada:

test.py:

import tensorflow as tf
print(tf.__version__)

Presiona CTRL + O para escribir cambios en el disco y, luego, CTRL + X para salir del editor nano.

Ahora, podemos ejecutar este archivo de Python para ver la versión de TensorFlow impresa en la pantalla:

Ventana de terminal:

python3 test.py

En el momento de la escritura, vemos el error 2.3.1 impreso en la consola para nuestra versión de TensorFlow Python instalada.

4. Crear un modelo de Python

En el siguiente paso de este codelab, se explicará cómo crear un modelo simple de Python para mostrar cómo guardar este modelo entrenado resultante en el “modelo guardado”. para usarlo con nuestro conversor de línea de comandos de TensorFlow.js. El principio sería similar para cualquier modelo de Python que intentas convertir, pero mantendremos este código simple para que todos puedan comprenderlo.

Editemos el archivo test.py que creamos en la primera sección y actualicemos el código de la siguiente manera:

test.py:

import tensorflow as tf
print(tf.__version__)

# Import NumPy - package for working with arrays in Python.
import numpy as np

# Import useful keras functions - this is similar to the
# TensorFlow.js Layers API functionality.
from tensorflow.keras import Sequential
from tensorflow.keras.layers import Dense

# Create a new dense layer with 1 unit, and input shape of [1].
layer0 = Dense(units=1, input_shape=[1])
model = Sequential([layer0])

# Compile the model using stochastic gradient descent as optimiser
# and the mean squared error loss function.
model.compile(optimizer='sgd', loss='mean_absolute_error')

# Provide some training data! Here we are using some fictional data 
# for house square footage and house price (which is simply 1000x the 
# square footage) which our model must learn for itself.
xs = np.array([800.0, 850.0, 900.0, 950.0, 980.0, 1000.0, 1050.0, 1075.0, 1100.0, 1150.0, 1200.0, 1250.0, 1300.0, 1400.0, 1500.0, 1600.0, 1700.0, 1800.0, 1900.0, 2000.0], dtype=float)

ys = np.array([800000.0, 850000.0, 900000.0, 950000.0, 980000.0, 1000000.0, 1050000.0, 1075000.0, 1100000.0, 1150000.0, 1200000.0,  1250000.0, 1300000.0, 1400000.0, 1500000.0, 1600000.0, 1700000.0, 1800000.0, 1900000.0, 2000000.0], dtype=float)

# Train the model for 500 epochs.
model.fit(xs, ys, epochs=500, verbose=0)

# Test the trained model on a test input value
print(model.predict([1200.0]))

# Save the model we just trained to the "SavedModel" format to the
# same directory our test.py file is located.
tf.saved_model.save(model, './')

Este código entrenará una regresión lineal muy simple para aprender a estimar la relación entre nuestras (entradas) x y y (salidas) proporcionadas. Luego, guardaremos el modelo entrenado resultante en el disco. Revisa los comentarios intercalados para obtener más detalles sobre lo que hace cada línea.

Si verificamos nuestro directorio después de ejecutar este programa (llamando a python3 test.py), deberíamos ver algunos archivos y carpetas nuevos creados en nuestro directorio actual:

  • test.py
  • saved_model.pb
  • recursos
  • variables

Ya generamos los archivos que necesitamos que use el conversor de TensorFlow.js para convertir este modelo y ejecutarlo en el navegador.

5. Convertir el modelo guardado al formato de TensorFlow.js

Instala el conversor de TensorFlow.js

Para instalar el conversor, ejecuta el siguiente comando:

Ventana de terminal:

pip3 install tensorflowjs

Eso fue fácil.

Si suponemos que usamos el convertidor de línea de comandos (tensorflowjs_converter) y no la versión del asistente que se muestra arriba, podemos llamar al siguiente comando para convertir el modelo guardado que acabamos de crear y pasar los parámetros de forma explícita al conversor:

Ventana de terminal:

tensorflowjs_converter \
    --input_format=keras_saved_model \
    ./ \
    ./predict_houses_tfjs

¿Qué sucede aquí? Primero, llamamos al objeto binario tensorflowjs_converter que acabamos de instalar y especificamos que intentamos convertir un modelo guardado de Keras.

En nuestro código de ejemplo anterior, notarás que importamos Keras y usamos sus APIs de capas de nivel superior para crear nuestro modelo. Si no usaste Keras en tu código de Python, puedes usar un formato de entrada diferente:

  • keras: Se usa para cargar el formato Keras (tipo de archivo HDF5).
  • tf_saved_model: se carga el modelo que usa las APIs principales de TensorFlow en lugar de Keras.
  • tf_frozen_model: Se usa para cargar un modelo que contiene pesos congelados.
  • tf_hub: Se usa para cargar un modelo generado a partir del concentrador de TensorFlow.

Puedes obtener más información sobre estos otros formatos aquí.

Los siguientes 2 parámetros especifican en qué carpeta se encuentra el modelo guardado. En la demostración anterior, especificamos el directorio actual y, por último, especificamos a qué directorio queremos enviar la conversión, que especificamos antes como una carpeta llamada “predict_houses_tfjs”. del directorio actual.

Cuando ejecutas el comando anterior, se crea una carpeta nueva en el directorio actual llamada predict_houses_tfjs que contiene :

  • model.json
  • Grupo1-shard1of1.bin

Estos son los archivos que necesitamos para ejecutar el modelo en el navegador web. Guarda estos archivos, ya que los usaremos en la próxima sección.

6. Cómo usar nuestro modelo convertido en el navegador

Aloja los archivos convertidos

Primero, debemos colocar los archivos model.json y *.bin que se generaron en un servidor web para poder acceder a ellos a través de nuestra página web. Para esta demostración, usaremos Glitch.com, de modo que te resulte fácil seguir el tema. Sin embargo, si tienes experiencia en ingeniería web, puedes optar por activar un servidor HTTP simple en tu instancia actual del servidor Ubuntu para hacerlo. La decisión es tuya.

Cómo subir archivos a Glitch

  1. Accede a Glitch.com.
  2. Usa este vínculo para clonar nuestro proyecto estándar de TensorFlow.js. Este contiene los archivos html, css y js de base que importan la biblioteca de TensorFlow.js para que la usemos.
  3. Haz clic en los “recursos”. carpeta en el panel de la izquierda.
  4. Haz clic en "Subir un recurso". y selecciona group1-shard1of1.bin para subirlos a esta carpeta. Una vez que se suba, debería verse de la siguiente manera: 25a2251c7f165184.png
  5. Si haces clic en el archivo group1-shard1of1.bin que acabas de subir, podrás copiar la URL en su ubicación. Copia esta ruta de acceso ahora como se muestra: 92ded8d46442c404.png
  6. Ahora, edita model.json con tu editor de texto favorito en tu máquina local y busca (con CTRL + F) el archivo group1-shard1of1.bin que se mencionará en algún lugar dentro de él.

Reemplaza este nombre de archivo por la URL que copiaste en el paso 5, pero borra el https://cdn.glitch.com/ inicial que genera la falla a partir de la ruta copiada.

Después de editarlo, debería verse de la siguiente manera (observa que se quitó la ruta de acceso del servidor principal para que solo se conserve el nombre de archivo resultante subido): d5a338f2dc1f31d4.png 7. Ahora, guarda y sube este archivo editado model.json para solucionar el problema haciendo clic en recursos y, luego, en “Subir un recurso” botón (importante). Si no usas el botón físico y lo arrastras y sueltas, se subirá como un archivo editable en lugar de hacerlo en la CDN, que no estará en la misma carpeta, y se supone la ruta de acceso relativa cuando TensorFlow.js intente descargar los archivos binarios para un modelo determinado. Si lo hiciste correctamente, deberías ver 2 archivos en la carpeta assets, como este: 51a6dbd5d3097ffc.png

¡Genial! Ya estamos listos para usar nuestros archivos guardados con algún código real en el navegador.

Carga el modelo

Ahora que alojamos nuestros archivos convertidos, podemos escribir una página web simple para cargar estos archivos y usarlos para hacer una predicción. Abre script.js en la carpeta del proyecto de Glitch y reemplaza el contenido de este archivo por lo siguiente después de cambiar const MODEL_URL de modo que apunte al vínculo de Glitch.com generado para el archivo model.json que subiste a Glitch:

script.js:

// Grab a reference to our status text element on the web page.
// Initially we print out the loaded version of TFJS.
const status = document.getElementById('status');
status.innerText = 'Loaded TensorFlow.js - version: ' + tf.version.tfjs;

// Specify location of our Model.json file we uploaded to the Glitch.com CDN.
const MODEL_URL = YOUR MODEL.JSON URL HERE! CHANGE THIS!';
// Specify a test value we wish to use in our prediction.
// Here we use 950, so we expect the result to be close to 950,000.
const TEST_VALUE = 950.0

// Create an asynchronous function.
async function run() {
    // Load the model from the CDN.
    const model = await tf.loadLayersModel(MODEL_URL);

    // Print out the architecture of the loaded model.
    // This is useful to see that it matches what we built in Python.
    console.log(model.summary());

    // Create a 1 dimensional tensor with our test value.
    const input = tf.tensor1d([TEST_VALUE]);

    // Actually make the prediction.
    const result = model.predict(input);

    // Grab the result of prediction using dataSync method
    // which ensures we do this synchronously.
    status.innerText = 'Input of ' + TEST_VALUE + 
        'sqft predicted as $' + result.dataSync()[0];
}

// Call our function to start the prediction!
run();

Si ejecutas el código anterior una vez que cambiaste la constante MODEL_URL para que apunte a tu ruta de acceso model.json, se mostrará el siguiente resultado.

c5e8457213058ec3.png

Si inspeccionamos la consola del navegador web (presiona F12 para que aparezcan las herramientas para desarrolladores en el navegador), también podemos ver la descripción del modelo cargado que imprime:

35e79d70dbd66f27.png

Si comparamos esto con nuestro código de Python al comienzo de este codelab, podemos confirmar que se trata de la misma red que creamos con 1 entrada densa y una capa densa con 1 nodo.

¡Felicitaciones! Acabas de ejecutar un modelo entrenado de Python convertido en el navegador web.

7. Modelos que no generan conversiones

Habrá ocasiones en las que los modelos más complejos que se compilan para usar operaciones menos comunes no serán compatibles con la conversión. La versión de TensorFlow.js basada en navegador es una reescritura completa de TensorFlow y, por lo tanto, actualmente no admitimos todas las operaciones de bajo nivel que tiene la API de C++ de TensorFlow (hay 1,000), aunque, con el tiempo, se están agregando más a medida que crecemos y las operaciones centrales se vuelven más estables.

Al momento de escribir, una de las funciones de TensorFlow para Python que genera una op no compatible cuando se exporta como un modelo guardado es linalg.diag. Si intentamos convertir un Savedmodel que usa esto en Python (que no admite las operaciones resultantes que produce), veremos un error similar al que se muestra a continuación:

5df94fc652393e00.png

Aquí podemos ver destacado en rojo que la llamada a linalg.diag se compiló para producir una op llamada MatrixDiagV3 que no es compatible con TensorFlow.js en el navegador web al momento de escribir este codelab.

¿Qué hacer?

Tienes dos opciones.

  1. Implementa esta op faltante en TensorFlow.js. Somos un proyecto de código abierto y agradecemos tus contribuciones, como las operaciones nuevas. Consulta esta guía sobre cómo escribir operaciones nuevas para TensorFlow.js. Si logras hacerlo, puedes usar la marca Skip_op_check en nuestro convertidor de línea de comandos para ignorar este error y continuar con la conversión de todos modos (se supondrá que esta op está disponible en la nueva compilación de TensorFlow.js que creaste y que tiene compatible con la op faltante).
  2. Determina qué parte de tu código de Python produjo la operación no compatible en el archivo savedmodel que exportaste. En un conjunto pequeño de código, esto puede ser fácil de encontrar, pero en modelos más complejos podría requerir mucha investigación, ya que actualmente no hay un método para identificar la llamada a función de alto nivel de Python que produjo una op determinada una vez en el formato de archivo savedmodel. Sin embargo, una vez que lo encuentres, puedes cambiarlo para usar un método diferente que sea compatible.

8. Felicitaciones

Felicitaciones, diste tus primeros pasos para usar un modelo de Python mediante TensorFlow.js en el navegador web.

Resumen

En este codelab, aprendimos a hacer lo siguiente:

  1. Configurar el entorno de Linux para instalar TensorFlow basado en Python
  2. Exporta un modelo guardado de Python
  3. Instala el conversor de línea de comandos de TensorFlow.js
  4. Usar el conversor de línea de comandos de TensorFlow.js para crear los archivos necesarios del cliente
  5. Usar los archivos generados en una aplicación web real
  6. Identifica los modelos que no generarán conversiones y qué debería implementarse para que puedan hacerlo en el futuro.

¿Qué sigue?

Recuerda etiquetarnos en cualquier contenido que crees con #MadeWithTFJS para tener la oportunidad de aparecer en las redes sociales o incluso en futuros eventos de TensorFlow. Nos encantaría ver lo que conviertes y usar el lado del cliente en el navegador.

Más codelabs de TensorFlow.js para obtener más información

Sitios web que puedes revisar