1. Introducción
Última actualización: 11/04/2022
En este codelab, aprenderás a entrenar un modelo de clasificación de imágenes con Teachable Machine y a ejecutarlo con aceleración de hardware de Coral usando TensorFlow.js, una biblioteca de aprendizaje automático potente y flexible para JavaScript. Compilarás una app Electron que muestre imágenes de una cámara web y las clasificará con una TPU de borde de coral. Hay una versión completamente funcional de este codelab disponible en el repositorio de GitHub de sig-tfjs.
¿Necesito un dispositivo coral?
No. Puedes probar este codelab sin un dispositivo Coral y aun así obtener un buen rendimiento en una máquina de escritorio con el acelerador WebNN.
Qué compilarás
En este codelab, compilarás una app Electron que clasifica imágenes. Tu app:
- Clasifica las imágenes de la cámara web según las categorías definidas en el modelo que entrenaste.
- Usa un acelerador de Coral para aumentar el rendimiento, si hay uno disponible.
- Usa WebNN para aumentar el rendimiento si es compatible con tu plataforma.
Qué aprenderás
- Cómo instalar y configurar el paquete de NPM tfjs-tflite-node para ejecutar modelos de TFLite en Node.js
- Cómo instalar la biblioteca de entorno de ejecución de Edge TPU para ejecutar modelos en un dispositivo Coral.
- Cómo acelerar la inferencia de modelos con una TPU perimetral de Coral.
- Cómo acelerar la inferencia de modelos con WebNN.
Este codelab se enfoca en TFLite en Node.js. Los conceptos y los bloques de código que no son relevantes no se explican, pero se proporcionan para que los copies y pegues.
Requisitos
Para completar este codelab, necesitas lo siguiente:
- Una computadora con cámara web
- Para Coral, recomendamos una Raspberry Pi que ejecute Raspberry Pi OS (64 bits) con computadora de escritorio.
- Para WebNN, recomendamos una máquina Intel x86-64 que ejecute Ubuntu 20.04 o Windows 10.
- Node.js versión >= 12.
- Conocimientos sobre JavaScript
- Un acelerador USB de Coral para acelerar el modelo (recomendado).
2. Prepárate
Obtén el código
Colocamos todo el código que necesitas para este proyecto en un repositorio de Git. Para comenzar, toma el código y ábrelo en tu entorno de desarrollo favorito. Para este codelab, te recomendamos usar una Raspberry Pi que ejecute el SO Raspberry Pi (64 bits) con una computadora de escritorio. Esto facilita la conexión de un acelerador de coral.
Muy recomendable: Usa Git para clonar el repo en una placa Raspberry Pi
Para obtener el código, abre una nueva ventana de terminal y clona el repo:
git clone https://github.com/tensorflow/sig-tfjs.git
Todos los archivos que debes editar para el codelab se encuentran en el directorio tfjs-tflite-node-codelab
(dentro de sig-tfjs
). En este directorio, encontrarás subdirectorios llamados starter_code
, cpu_inference_working
, coral_inference_working
y webnn_inference_working
. Estos son puntos de control para los pasos de este codelab.
Entre los otros archivos del repositorio, se encuentran los paquetes de NPM de los que depende tfjs-tflite-node-codelab
. No necesitarás editar ninguno de estos archivos, pero deberás ejecutar algunas de sus pruebas para asegurarte de que tu entorno esté configurado correctamente.
Instala la biblioteca del entorno de ejecución de Edge TPU
Los dispositivos de Coral requieren que instales la biblioteca de entorno de ejecución de Edge TPU antes de usarlos. Instálala siguiendo las instrucciones para tu plataforma.
En Linux / Raspberry Pi
En Linux, la biblioteca está disponible desde el PPA de Google como un paquete Debian, libedgetpu1-std, para arquitecturas x86-64 y Armv8 (64 bits). Si tu procesador usa una arquitectura diferente, deberás compilarla desde la fuente.
Ejecuta este comando para agregar el PPA de Coral de Google y, luego, instalar la biblioteca del entorno de ejecución de Edge TPU.
# None of this is needed on Coral boards
# This repo is needed for almost all packages below
echo "deb https://packages.cloud.google.com/apt coral-edgetpu-stable main" | sudo tee /etc/apt/sources.list.d/coral-edgetpu.list
# This repo is needed for only python3-coral-cloudiot and python3-coral-enviro
echo "deb https://packages.cloud.google.com/apt coral-cloud-stable main" | sudo tee /etc/apt/sources.list.d/coral-cloud.list
curl https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add -
sudo apt-get update
sudo apt-get install libedgetpu1-std
En Windows y otros SO
Los objetos binarios precompilados están disponibles para las versiones x86-64 de macOS y Windows, y se pueden instalar ejecutando la secuencia de comandos install.sh o install.bat en el archivo una vez que se descargan.
Reinicia el dispositivo
Una vez que se instale el entorno de ejecución de Edge TPU, reinicia el dispositivo para activar la nueva regla Coral Udev que agregó el instalador.
Verifica que se detecte tu dispositivo Coral
Para verificar que el dispositivo Coral se detecte y funcione, ejecuta las pruebas de integración para el paquete coral-tflite-delegate
. Este paquete se encuentra en el directorio raíz del repositorio. Para ejecutar las pruebas de integración, conecta el acelerador de Coral y ejecuta estos comandos en el directorio del paquete:
npx yarn
npx yarn build-deps
npx yarn test-integration
Deberías ver un resultado como el siguiente:
yarn run v1.22.17
$ yarn build && yarn test-integration-dev
$ tsc
$ jasmine --config=jasmine-integration.json
Platform node has already been set. Overwriting the platform with node.
Randomized with seed 78904
Started
============================
Hi there 👋. Looks like you are running TensorFlow.js in Node.js. To speed things up dramatically, install our node backend, which binds to TensorFlow C++, by running npm i @tensorflow/tfjs-node, or npm i @tensorflow/tfjs-node-gpu if you have CUDA. Then call require('@tensorflow/tfjs-node'); (-gpu suffix for CUDA) at the start of your program. Visit https://github.com/tensorflow/tfjs-node for more details.
============================
WARNING: converting 'int32' to 'uint8'
.
1 spec, 0 failures
Finished in 2.777 seconds
Randomized with seed 78904 (jasmine --random=true --seed=78904)
Done in 6.36s.
No te preocupes por instalar @tensorflow/tfjs-node,
como se menciona en los registros, ya que ejecutarás el modelo en TFLite.
Si, en cambio, el resultado contiene Encountered unresolved custom op: edgetpu-custom-op
, significa que no se detectó tu dispositivo Coral. Asegúrate de haber instalado la biblioteca de entorno de ejecución de Edge TPU y de haber conectado el dispositivo Coral a tu computadora. También puedes seguir la guía de introducción de Coral para probar la versión de Python de las vinculaciones de Coral. Si la versión de Python funciona, pero las pruebas aún fallan, completa un informe de errores para avisarnos.
Ejecuta el código de partida
Ya tienes todo listo para ejecutar el código de partida. Sigue estos pasos para comenzar.
- Ve al directorio
starter_code
que se encuentra en el directoriotfjs-tflite-node-codelab
. - Ejecuta
npm install
para instalar dependencias. - Ejecuta
npm start
para iniciar el proyecto. Se debería abrir una app que muestre un feed de video de la cámara web de tu computadora.
¿Cuál es nuestro punto de partida?
Nuestro punto de partida es una app de cámara básica de Electron diseñada para este codelab. El código se simplificó para mostrar los conceptos en el codelab y tiene poco manejo de errores. Si eliges reutilizar el código en una app de producción, asegúrate de solucionar los errores y probar todo el código por completo.
Explora el código de partida
Hay muchos archivos en este código de partida, pero el único que debes editar es renderer.js
. Controla lo que aparece en la página, incluidos el feed de video y los elementos HTML, y es donde agregas tu modelo de aprendizaje automático a la app. Entre los otros archivos, se encuentra el archivo index.html
, pero lo único que hace es cargar el archivo renderer.js
. También hay un archivo main.js
, que es el punto de entrada de Electron. Controla el ciclo de vida de la app, lo que incluye qué mostrar cuando se abre y qué hacer cuando se cierra, pero no será necesario que realices ningún cambio.
Cómo abrir el depurador
Es posible que debas depurar tu app a medida que sigues este codelab. Como esta app se basa en Electron, tiene el depurador de Chrome integrado. En la mayoría de las plataformas, puedes abrirlo con Ctrl + Mayúsculas + i. Haz clic en la pestaña Consola para ver los registros y mensajes de error de la app.
No hay mucho más que explorar aquí, así que comencemos de inmediato a entrenar el clasificador de imágenes.
3. Entrena un clasificador de imágenes
En esta sección, entrenarás las versiones TFLite y Coral de un modelo de clasificación de imágenes personalizado.
Entrena el clasificador
Un clasificador de imágenes toma imágenes de entrada y les asigna etiquetas. En este codelab, usarás Teachable Machine para entrenar un modelo en tu navegador. Para acelerar el entrenamiento de esta sección, puedes usar una computadora de escritorio o laptop en lugar de una Raspberry Pi, pero tendrás que copiar los archivos resultantes a la unidad Pi.
Ya está todo listo para entrenar un modelo. Si no estás seguro de qué tipo de modelo entrenar, un modelo fácil de entrenar es un detector de personas, que solo detecta si una persona está en el marco.
- Abre la página de entrenamiento de Teachable Machine en una pestaña nueva.
- Selecciona Proyecto de imagen y, luego, Modelo de imagen estándar.
- Agrega muestras de imágenes para cada clase. La forma más fácil de hacerlo es mediante la entrada de la cámara web. También puedes cambiar el nombre de las clases.
- Cuando hayas recopilado suficientes datos para cada clase (50 muestras suele ser suficiente), presiona Entrenar modelo.
Cuando el modelo termine de entrenarse, deberías ver una vista previa de su resultado.
Intenta darle diferentes entradas al modelo. Si encuentras una entrada que está mal clasificada, agrégala a los datos de entrenamiento y vuelve a entrenar el modelo.
- Cuando estés conforme con la exactitud del modelo, haz clic en Exportar modelo. Deberás descargar dos versiones separadas del modelo.
- Exporta tu modelo como modelo de punto flotante de Tensorflow Lite. Esta acción descarga un archivo llamado
converted_tflite.zip
. que se ejecuta en la CPU. - Exporta tu modelo como modelo EdgeTPU de Tensorflow Lite. De esta manera, se descarga un archivo llamado
converted_edgetpu.zip
que se ejecuta en la TPU de Coral Edge.
4. Ejecuta el modelo de CPU en tu app
Ahora que entrenaste un modelo, es momento de agregarlo a tu app. Al final de esta sección, la app podrá ejecutar tu modelo usando la CPU del dispositivo.
Agrega el archivo del modelo a la app
Descomprime el archivo del modelo converted_tflite.zip que descargaste cuando entrenaste el clasificador. Hay dos archivos en el archivo. model_uquant.tflite
es el modelo de TFLite guardado, incluidos el grafo del modelo y los pesos. labels.txt
contiene etiquetas legibles para las clases que predice el modelo. Coloca ambos archivos en el modeldirectory.
Instala dependencias
Para cargar un modelo y procesar previamente las entradas, se requieren algunas dependencias de TensorFlow.js:
tfjs-tflite-node
: Es el paquete de TensorFlow.js para ejecutar modelos de TFLite en Node.js.@tensorflow/tfjs
: Es el paquete principal de TensorFlow.js.
@tensorflow/tfjs ya está instalado, pero debes instalar tfjs-tflite-node con este comando:
npm install --save tfjs-tflite-node
Una vez instalado, agrégalo a la app en la parte superior de renderer.js:
CODELAB parte 1: Importa tfjs-tflite-node.
const {loadTFLiteModel} = require('tfjs-tflite-node');
Carga el modelo
Ya está todo listo para cargar el modelo. tfjs-tflite-node
proporciona la función loadTFLiteModel
para hacerlo. Puede cargar modelos desde una ruta de archivo, un ArrayBuffer o una URL de TFHub. Para cargar tu modelo y sus pesos, agrega lo siguiente a la función main
:
CODELAB parte 1: Carga el modelo aquí.
const modelPath = './model/model_unquant.tflite';
const model = await loadTFLiteModel(modelPath);
const labels = fs.readFileSync('./model/labels.txt', 'utf8')
.split('\n');
Ejecuta el modelo
Para ejecutar tu modelo se requieren tres pasos. Primero, extraes y procesas previamente un fotograma de entrada desde la cámara web. Luego, ejecutas el modelo en ese marco y obtienes una predicción. Después, puedes mostrar la predicción en la página.
Procesa previamente la entrada de la cámara web
En este momento, la cámara web es solo un elemento HTML, y los marcos que muestra no están disponibles para el archivo JavaScript render.js. Para extraer fotogramas de la cámara web, TensorFlow.js proporciona tf.data.webcam, que proporciona un método capture()
fácil de usar para capturar fotogramas de la cámara.
Para usarlo, agrega este código de configuración a main()
:
CODELAB parte 1: Configura tf.data.webcam aquí.
const tensorCam = await tf.data.webcam(webcam);
Luego, para capturar una imagen en cada fotograma, agrega lo siguiente a run()
:
CODELAB parte 1: Captura fotogramas de cámara web aquí.
const image = await tensorCam.capture();
También debes procesar previamente cada fotograma para que sea compatible con el modelo. El modelo que usa este codelab tiene la forma de entrada [1, 224, 224, 3], por lo que se espera una imagen RGB de 224 por 224 píxeles. tensorCam.capture()
da una forma de [224, 224, 3], por lo que debes agregar una dimensión adicional al frente del tensor con tf.expandDims. Además, el modelo de CPU espera una entrada Float32 entre -1 y 1, pero la cámara web captura valores de 0 a 255. Puedes dividir el tensor de entrada por 127 para cambiar su rango de [0, 255] a [0, ~2] y, luego, restar 1 para obtener el rango deseado [-1, ~1]. Agrega estas líneas a tf.tidy()
en la función run()
para hacerlo:
CODELAB parte 1: Procesa previamente los fotogramas de la cámara web aquí.
const expanded = tf.expandDims(image, 0);
const divided = tf.div(expanded, tf.scalar(127));
const normalized = tf.sub(divided, tf.scalar(1));
Es importante desechar los tensores después de usarlos. tf.tidy()
lo hace automáticamente para el código contenido en su devolución de llamada, pero no admite funciones asíncronas. Deberás descartar de forma manual el tensor de imagen que creaste antes llamando a su método dispose()
.
CODELAB parte 1: Desecha aquí los marcos de la cámara web.
image.dispose();
Ejecuta el modelo y muestra los resultados
Para ejecutar el modelo en la entrada ya procesada, llama a model.predict()
en el tensor normalizado. Esto muestra un tensor unidimensional que contiene la probabilidad predicha de cada etiqueta. Multiplica esta probabilidad por 100 para obtener el porcentaje de probabilidad de cada etiqueta y usa la función showPrediction
incluida con el código de partida para mostrar la predicción del modelo en la pantalla.
Este código también usa stats.js para medir el tiempo de la predicción. Para ello, coloca llamadas a stats.begin
y stats.end
alrededor de model.predict
.
CODELAB parte 1: Ejecuta el modelo y muestra los resultados aquí.
stats.begin();
const prediction = model.predict(normalized);
stats.end();
const percentage = tf.mul(prediction, tf.scalar(100));
showPrediction(percentage.dataSync(), labels);
Vuelve a ejecutar la app con yarn start
. Deberías ver las clasificaciones de tu modelo.
Rendimiento
Con su configuración actual, el modelo se ejecuta en la CPU. Esto está bien para computadoras de escritorio y la mayoría de las laptops, pero es posible que no sea conveniente si lo ejecutas en una Raspberry Pi o en otro dispositivo de baja potencia. En una Raspberry Pi 4, es probable que veas alrededor de 10 FPS, lo que podría no ser lo suficientemente rápido para algunas aplicaciones. Para obtener un mejor rendimiento sin usar una máquina más rápida, puedes usar silicio específico de la aplicación en forma de una TPU de Coral Edge.
5. Ejecuta el modelo de Coral en tu app
Si no tienes un dispositivo Coral, puedes omitir esta sección.
Este paso del codelab se basa en el código que escribiste en la última sección, pero puedes usar el punto de control cpu_inference_working si deseas comenzar desde cero.
Los pasos para ejecutar el modelo de coral son casi idénticos a los pasos para ejecutar el modelo de CPU. La principal diferencia es el formato del modelo. Dado que Coral solo admite tensores uint8, el modelo está cuantizado. Esto afecta a los tensores de entrada que se pasan al modelo y a los de salida que muestra. Otra diferencia es que los modelos se deben compilar con el compilador de Edge TPU para ejecutarse en una TPU de Coral. TeachableMachine ya realizó este paso, pero puedes aprender a hacerlo en otros modelos si visitas la documentación de Coral.
Cómo agregar el archivo del modelo Coral a la app
Descomprime el archivo del modelo converted_edgetpu.zip que descargaste cuando entrenaste el clasificador. Hay dos archivos incluidos en el archivo. model_edgetpu.tflite
es el modelo de TFLite guardado, incluidos el grafo del modelo y los pesos. labels.txt
contiene etiquetas legibles para las clases que predice el modelo. Coloca el archivo del modelo en el directorio coral_model.
Instala dependencias
Para ejecutar modelos de Coral, se requiere la biblioteca de entorno de ejecución de Edge TPU. Asegúrate de haberla instalado; para ello, sigue las instrucciones de configuración antes de continuar.
Se accede a los dispositivos de Coral como delegados de TFLite. Para acceder a ellas desde JavaScript, instala el paquete coral-tflite-delegate:
npm install --save coral-tflite-delegate
Luego, importa el delegado. Para ello, agrega esta línea a la parte superior del archivo renderer.js:
CODELAB parte 2: Importa el delegado aquí.
const {CoralDelegate} = require('coral-tflite-delegate');
Carga el modelo
Ahora tienes todo listo para cargar el modelo de Coral. Debes hacer esto de la misma manera que con el modelo de CPU, excepto que ahora pasas las opciones a la función loadTFLiteModel
para cargar el delegado Coral.
CODELAB parte 2: Carga el modelo de delegado aquí.
const coralModelPath = './coral_model/model_edgetpu.tflite';
const options = {delegates: [new CoralDelegate()]};
const coralModel = await loadTFLiteModel(coralModelPath, options);
No necesitas cargar las etiquetas porque son las mismas que para el modelo de CPU.
Agrega un botón para cambiar entre CPU y Coral
Agregarás el modelo Coral junto con el modelo de CPU que agregaste en la última sección. Ejecutarlos al mismo tiempo hace que sea difícil ver las diferencias de rendimiento, por lo que un botón de activación alterna entre la ejecución en coral y en la CPU.
Agrega el botón con este código:
CODELAB parte 2: Crea el botón de delegado aquí.
let useCoralDelegate = false;
const toggleCoralButton = document.createElement('button');
function toggleCoral() {
useCoralDelegate = !useCoralDelegate;
toggleCoralButton.innerText = useCoralDelegate
? 'Using Coral. Press to switch to CPU.'
: 'Using CPU. Press to switch to Coral.';
}
toggleCoralButton.addEventListener('click', toggleCoral);
toggleCoral();
document.body.appendChild(toggleCoralButton);
Conectemos esta condición en la función run()
. Cuando useCoralDelegate
es falso, debería ejecutar la versión de CPU. De lo contrario, ejecutará la versión Coral (pero, por ahora, no hará nada). Une el código de la ejecución del modelo de CPU en una sentencia if. Ten en cuenta que el tensor expanded
se excluye de la sentencia if porque lo usa el modelo de Coral.
CODELAB parte 2: Verifica si debes usar el delegado aquí.
// NOTE: Don't just copy-paste this code into the app.
// You'll need to edit the code from the CPU section.
const expanded = tf.expandDims(image, 0);
if (useCoralDelegate) {
// CODELAB part 2: Run Coral prediction here.
} else {
const divided = tf.div(expanded, tf.scalar(127));
const normalized = tf.sub(divided, tf.scalar(1));
stats.begin();
const prediction = model.predict(normalized);
stats.end();
const percentage = tf.mul(prediction, tf.scalar(100));
showPrediction(percentage.dataSync(), labels);
}
Ejecuta el modelo
La versión Coral del modelo espera tensores uint8 de 0 a 255, por lo que no es necesario normalizar su entrada. Sin embargo, la salida también es un tensor de uint8 en el rango de 0 a 255. Debe convertirse en un número de punto flotante de 0 a 100 antes de que se muestre.
CODELAB parte 2: Ejecuta la predicción de Coral aquí. (Esto es parte del fragmento de código anterior)
stats.begin();
const prediction = coralModel.predict(expanded);
stats.end();
const percentage = tf.div(tf.mul(prediction, tf.scalar(100)), tf.scalar(255));
showPrediction(percentage.dataSync(), labels);
Vuelve a ejecutar la app con yarn start
. Debería mostrar las clasificaciones del acelerador de Coral.
Puedes presionar el botón para cambiar entre la inferencia de Coral y CPU. Puedes notar que las clasificaciones de confianza del modelo Coral son menos precisas que las del modelo de CPU y, por lo general, terminan con un decimal par. Esta pérdida de precisión equivale a ejecutar un modelo cuantificado en coral. Por lo general, no es importante en la práctica, pero es algo que se debe tener en cuenta.
Nota sobre el rendimiento
La velocidad de fotogramas que ves incluye el procesamiento previo y posterior, por lo que no es representativa de lo que puede hacer el hardware de Coral. Puedes obtener una mejor idea del rendimiento haciendo clic en el medidor de FPS hasta que muestre la latencia (en milisegundos), que mide solo la llamada a model.predict
. Sin embargo, eso incluye el tiempo que lleva mover los tensores a las vinculaciones de C nativas de TFLite y, luego, al dispositivo Coral, por lo que no es una medición perfecta. Para obtener comparativas de rendimiento más precisas escritas en C++, consulta la página de comparativas de EdgeTPU.
También debes tener en cuenta que el video se grabó en una laptop y no en una Raspberry Pi, por lo que es posible que veas un FPS diferente.
Aceleración del procesamiento previo de Coral
En algunos casos, puedes acelerar el procesamiento previo si cambias los backends de TFJS. El backend predeterminado es WebGL, que es útil para operaciones grandes y paralelizables, pero esta app no hace mucho de eso en la fase de procesamiento previo (la única op que usa es expandDims
, que no es paralela). Puedes cambiar al backend de la CPU para evitar la latencia adicional de mover tensores hacia y desde la GPU agregando esta línea después de las importaciones en la parte superior del archivo.
tf.setBackend(‘cpu');
Esto también afecta el procesamiento previo del modelo de CPU de TFLite, que se paralelizó, por lo que el modelo se ejecuta mucho más lento con este cambio.
6. Acelera el modelo de CPU con WebNN
Si no tienes un acelerador de Coral, o si solo quieres probar otra forma de acelerar el modelo, puedes usar el delegado de WebNN de TFLite. Este delegado usa hardware de aprendizaje automático integrado en los procesadores Intel para acelerar la inferencia de modelos con el kit de herramientas OpenVINO. Por lo tanto, tiene requisitos adicionales que no se trataron en la sección de configuración de este codelab, y deberás instalar el kit de herramientas OpenVINO. Asegúrate de verificar tu configuración con las Plataformas del sistema de destino compatibles antes de continuar, pero ten en cuenta que el delegado de WebNN aún no es compatible con macOS.
Instala el kit de herramientas OpenVINO
El kit de herramientas OpenVINO usa hardware de aprendizaje automático integrado en los procesadores Intel para acelerar los modelos. Puedes descargar una versión precompilada de Intel o compilarla desde la fuente. Existen varias formas de instalar OpenVINO, pero, a los fines de este Codelab, te recomendamos que uses la secuencia de comandos del instalador para Windows o Linux. Asegúrate de instalar la versión del entorno de ejecución de LTS 2021.4.2, ya que es posible que otras versiones no sean compatibles. Después de ejecutar el instalador, asegúrate de configurar las variables de entorno de tu shell como se describe en las instrucciones de instalación de Linux o Windows ( solución permanente), o bien ejecuta el comando setupvars.sh
(Linux) o setupvars.bat
(Windows) ubicado en el directorio webnn-tflite-delegate
.
Verifica que el delegado de WebNN esté funcionando
Para verificar que el delegado de WebNN funcione correctamente, ejecuta las pruebas de integración para el paquete webnn-tflite-delegate
que se encuentra en el directorio raíz del repositorio. Para ejecutar las pruebas de integración, ejecuta estos comandos en el directorio del paquete:
# In webnn-tflite-delegate/
npx yarn
npx yarn test-integration
Deberías ver un resultado como el siguiente:
WebNN delegate: WebNN device set to 0.
INFO: Created TensorFlow Lite WebNN delegate for device Default and power Default.
============================
Hi there 👋. Looks like you are running TensorFlow.js in Node.js. To speed things up dramatically, install our node backend, which binds to TensorFlow C++, by running npm i @tensorflow/tfjs-node, or npm i @tensorflow/tfjs-node-gpu if you have CUDA. Then call require('@tensorflow/tfjs-node'); (-gpu suffix for CUDA) at the start of your program. Visit https://github.com/tensorflow/tfjs-node for more details.
============================
label: wine bottle
score: 0.934505045413971
.
1 spec, 0 failures
Finished in 0.446 seconds
Randomized with seed 58441 (jasmine --random=true --seed=58441)
Done in 8.07s.
Si ves un resultado como este, significa un error de configuración:
Platform node has already been set. Overwriting the platform with node.
Randomized with seed 05938
Started
error Command failed with exit code 3221225477.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
Lo más probable es que este resultado signifique que no configuraste las variables de entorno de OpenVINO. Por ahora, puedes configurarlas ejecutando el comando setupvars.sh
(Linux) o setupvars.bat
(Windows), pero te recomendamos que las configures de forma permanente siguiendo las instrucciones de Linux o Windows ( solución permanente). Si usas Windows, el
setupvars.bat
El comando no es compatible con Bash de Git, así que asegúrate de ejecutarlo junto con otros comandos de este codelab desde el símbolo del sistema de Windows.
Instala el delegado de WebNN
Con OpenVINO instalado, estás listo para acelerar el modelo de la CPU con WebNN. Esta sección del codelab se basa en el código que escribiste en el curso "Cómo ejecutar el modelo de CPU en tu app" sección. Puedes usar el código que escribiste en este paso, pero si ya completaste la sección Coral, usa el punto de control cpu_inference_working para comenzar desde cero.
La parte de Node.js del delegado de WebNN se distribuye en npmjs. Para instalarlo, ejecuta el siguiente comando:
npm install --save webnn-tflite-delegate
Luego, importa el delegado. Para ello, agrega esta línea a la parte superior del archivo renderer.js:
CODELAB parte 2: Importa el delegado aquí.
const {WebNNDelegate, WebNNDevice} = require('webnn-tflite-delegate');
El delegado de WebNN admite la ejecución en la CPU o la GPU; WebNNDevice te permite elegir cuál usar.
Carga el modelo
Ya está todo listo para cargar el modelo con el delegado de WebNN habilitado. En el caso de Coral, debías cargar un archivo de modelo diferente, pero WebNN admite el mismo formato de modelo que TFLite. Agrega WebNNDelegate a la lista de delegados pasados al modelo para habilitarlo:
CODELAB parte 2: Carga el modelo de delegado aquí.
let webnnModel = await loadTFLiteModel(modelPath, {
delegates: [new WebNNDelegate({webnnDevice: WebNNDevice.DEFAULT})],
});
No necesitas volver a cargar las etiquetas porque este es el mismo modelo.
Agrega un botón para alternar entre la CPU de TfLite y la WebNN
Ahora que la versión WebNN del modelo está lista, agrega un botón para alternar entre la inferencia WebNN y TfLite de CPU. Ejecutarlos al mismo tiempo hace que sea difícil ver las diferencias de rendimiento.
Agrega el botón con este código (ten en cuenta que todavía no cambiará de modelo):
CODELAB parte 2: Crea el botón de delegado aquí.
let useWebNNDelegate = false;
const divElem = document.createElement('div');
const toggleWebNNButton = document.createElement('button');
function toggleWebNN() {
useWebNNDelegate = !useWebNNDelegate;
toggleWebNNButton.innerHTML = useWebNNDelegate
? 'Using WebNN. Press to switch to TFLite CPU.'
: 'Using TFLite CPU. Press to switch to WebNN.';
divElem.hidden = useWebNNDelegate ? false : true;
}
toggleWebNNButton.addEventListener('click', toggleWebNN);
toggleWebNN();
document.body.appendChild(toggleWebNNButton);
document.body.appendChild(divElem);
Este código también agrega un elemento div
que se usa para ajustar la configuración de WebNN en la siguiente sección.
Agrega un menú desplegable para alternar entre dispositivos WebNN
WebNN admite la ejecución en CPU y GPU, así que agrega un menú desplegable para alternar entre ellas. Agrega este código después del código que crea el botón:
// Create elements for WebNN device selection
divElem.innerHTML = '<br/>WebNN Device: ';
const selectElem = document.createElement('select');
divElem.appendChild(selectElem);
const webnnDevices = ['Default', 'GPU', 'CPU'];
// append the options
for (let i = 0; i < webnnDevices.length; i++) {
var optionElem = document.createElement('option');
optionElem.value = i;
optionElem.text = webnnDevices[i];
selectElem.appendChild(optionElem);
}
Ahora, si ejecutas la app, verás un menú desplegable con la lista Predeterminado, GPU y CPU. Elegir una de ellas no hará nada en este momento, ya que el menú desplegable todavía no está conectado.
Cómo hacer que el menú desplegable cambie el dispositivo
Para conectar el menú desplegable de modo que cambie el dispositivo WebNN que se usa, agrega un objeto de escucha al evento change del elemento del selector del menú desplegable. Cuando cambie el valor seleccionado, vuelve a crear el modelo de WebNN con el dispositivo WebNN correspondiente seleccionado en las opciones de delegado.
Agrega el siguiente código después del código que agregó el menú desplegable:
selectElem.addEventListener('change', async () => {
let webnnDevice;
switch(selectElem.value) {
case '1':
webnnDevice = WebNNDevice.GPU;
break;
case '2':
webnnDevice = WebNNDevice.CPU;
break;
default:
webnnDevice = WebNNDevice.DEFAULT;
break;
}
webnnModel = await loadTFLiteModel(modelPath, {
delegates: [new WebNNDelegate({webnnDevice})],
});
});
Con este cambio, el menú desplegable crea un modelo nuevo con la configuración correcta cada vez que se modifica. Ahora es el momento de conectar el modelo WebNN y usarlo para la inferencia.
Ejecuta el modelo WebNN
El modelo WebNN está listo para usarse, pero el botón para cambiar entre las CPU WebNN y TfLite todavía no cambia el modelo. Para cambiar el modelo, primero debes cambiar el nombre de la variable model
desde el momento en que cargaste el modelo de CPU de TfLite en la primera sección del codelab.
Cambia la siguiente línea...
const model = await loadTFLiteModel(modelPath);
...para que coincida con esta línea.
const cpuModel = await loadTFLiteModel(modelPath);
Con el nombre de la variable model
a cpuModel
, agrega lo siguiente a la función run
para elegir el modelo correcto según el estado del botón:
CODELAB parte 2: Verifica si debes usar el delegado aquí.
let model;
if (useWebNNDelegate) {
model = webnnModel;
} else {
model = cpuModel;
}
Ahora, cuando ejecutes la app, el botón cambiará entre TfLite CPU y WebNN.
También puedes alternar entre la inferencia de CPU y GPU de WebNN si tienes una GPU Intel integrada.
Nota sobre el rendimiento
La velocidad de fotogramas que ves incluye el procesamiento previo y posterior, por lo que no es representativa de lo que puede hacer WebNN. Puedes obtener una mejor idea del rendimiento haciendo clic en el medidor de FPS hasta que muestre la latencia (en milisegundos), que mide solo la llamada a model.predict
. Sin embargo, eso incluye el tiempo que lleva mover los tensores a las vinculaciones nativas de C de TFLite, por lo que no es una medición perfecta.
7. Felicitaciones
¡Felicitaciones! Acabas de completar tu primer proyecto Coral / WebNN con tfjs-tflite-node en Electron.
Pruébala en una variedad de imágenes. También puedes entrenar un modelo nuevo en TeachableMachine para que clasifique algo completamente diferente.
Resumen
En este codelab, aprendiste lo siguiente:
- Cómo instalar y configurar el paquete npm tfjs-tflite-node para ejecutar modelos de TFLite en Node.js
- Cómo instalar la biblioteca de entorno de ejecución de Edge TPU para ejecutar modelos en un dispositivo Coral.
- Cómo acelerar la inferencia de modelos con una TPU perimetral de Coral.
- Cómo acelerar la inferencia de modelos con WebNN
¿Qué sigue?
Ahora que tienes una base de trabajo desde la cual comenzar, ¿qué ideas creativas se te ocurren para extender este ejecutor de modelos de aprendizaje automático a un caso de uso del mundo real en el que podrías estar trabajando? Tal vez podrías revolucionar la industria en la que trabajas con una inferencia rápida y asequible, o tal vez podrías modificar una tostadora para que deje de tostar cuando el pan se vea bien. Las posibilidades son infinitas.
Para avanzar y obtener más información sobre cómo TeachableMachine entrenó el modelo que usaste, consulta nuestro codelab sobre el aprendizaje por transferencia. Si buscas otros modelos que funcionen con Coral, como el reconocimiento de voz y la estimación de poses, consulta coral.ai/models. También puedes encontrar las versiones de CPU de esos modelos y muchos otros en TensorFlow Hub.
Comparte tus creaciones con nosotros
También puedes extender fácilmente lo que creaste hoy para otros casos de uso creativos, y te recomendamos que pienses de forma innovadora y sigas hackeando.
Recuerda etiquetarnos en redes sociales con el hashtag #MadeWithTFJS para tener la oportunidad de que tu proyecto se destaque en nuestro blog de TensorFlow o incluso en eventos futuros. Nos encantaría ver tus productos.