1. Introdução

Última atualização: 11/04/2022
Neste codelab, você vai aprender a treinar um modelo de classificação de imagens usando a Máquina que Aprende e executá-lo com aceleração de hardware do Coral usando o TensorFlow.js, uma biblioteca de machine learning avançada e flexível para JavaScript. Você vai criar um app Electron que mostra imagens de uma webcam e as classifica usando uma TPU de borda Coral. Uma versão totalmente funcional deste codelab está disponível no repositório sig-tfjs do GitHub (link em inglês).
Preciso de um dispositivo Coral?
Não. Você pode testar este codelab sem um dispositivo Coral e ainda ter um bom desempenho em um computador desktop usando o acelerador WebNN.
O que você vai criar
Neste codelab, você vai criar um app Electron que classifica imagens. Seu app:
- Classifica imagens da webcam nas categorias definidas no modelo treinado.
- Usa um acelerador Coral para aumentar o desempenho, se disponível.
- Usa a WebNN para aumentar a performance, se ela for compatível com sua plataforma.
O que você vai aprender
- Como instalar e configurar o pacote NPM tfjs-tflite-node para executar modelos do TFLite no Node.js.
- Como instalar a biblioteca de ambiente de execução da Edge TPU para executar modelos em um dispositivo Coral.
- Como acelerar a inferência de modelos usando uma TPU de borda Coral.
- Como acelerar a inferência de modelos com a WebNN.
Este codelab se concentra no TFLite em Node.js. Conceitos não relevantes e blocos de código são citados rapidamente e fornecidos para que você simplesmente os copie e cole.
O que é necessário
Para concluir este codelab, você precisa do seguinte:
- Um computador com webcam.
- Para o Coral, recomendamos um Raspberry Pi executando o Raspberry Pi OS (64 bits) com área de trabalho.
- Para WebNN, recomendamos uma máquina Intel x86-64 executando Ubuntu 20.04 ou Windows 10.
- Versão do Node.js >= 12.
- Conhecimento de JavaScript.
- (Recomendado) Um acelerador USB Coral para acelerar o modelo.
2. Começar a configuração
Buscar o código
Colocamos todo o código necessário para este projeto em um repositório Git. Para começar, copie e abra o código no ambiente de desenvolvimento de sua preferência. Para este codelab, recomendamos usar um Raspberry Pi executando o Raspberry Pi OS (64 bits) com área de trabalho. Isso facilita a conexão de um acelerador Coral.
Altamente recomendável: use o Git para clonar o repositório em um Raspberry Pi
Para acessar o código, abra uma nova janela do terminal e clone o repositório:
git clone https://github.com/tensorflow/sig-tfjs.git
Todos os arquivos que você precisa editar para o codelab estão no diretório tfjs-tflite-node-codelab (dentro de sig-tfjs). Nesse diretório, você encontra subdiretórios chamados starter_code, cpu_inference_working, coral_inference_working e webnn_inference_working. Estes são pontos de verificação para as etapas deste codelab.
Entre os outros arquivos no repositório, estão os pacotes NPM de que tfjs-tflite-node-codelab depende. Não é necessário editar nenhum desses arquivos, mas é preciso executar alguns dos testes deles para garantir que o ambiente esteja configurado corretamente.
Instale a biblioteca de ambiente de execução da Edge TPU.
Os dispositivos Coral exigem que você instale a biblioteca de tempo de execução da Edge TPU antes de usar. Instale seguindo as instruções para sua plataforma.
No Linux / Raspberry Pi
No Linux, a biblioteca está disponível no PPA do Google como um pacote Debian, libedgetpu1-std, para arquiteturas x86-64 e Armv8 (64 bits). Se o processador usar uma arquitetura diferente, será necessário compilar o código-fonte.
Execute este comando para adicionar o PPA do Coral do Google e instalar a biblioteca de tempo de execução da 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
No Windows / outros SOs
Os binários pré-compilados estão disponíveis para versões x86-64 do macOS e do Windows e podem ser instalados executando o script install.sh ou install.bat no arquivo após o download.
Reinicie o dispositivo
Depois que o ambiente de execução da Edge TPU for instalado, reinicie o dispositivo para ativar a nova regra Udev do Coral adicionada pelo instalador.
Verifique se o dispositivo Coral foi detectado
Para verificar se o dispositivo Coral foi detectado e está funcionando, execute os testes de integração do pacote coral-tflite-delegate. Esse pacote está no diretório raiz do repositório. Para executar os testes de integração, conecte o acelerador Coral e execute estes comandos no diretório do pacote:
npx yarn
npx yarn build-deps
npx yarn test-integration
A resposta será semelhante a esta:
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.
Não se preocupe em instalar @tensorflow/tfjs-node,, conforme mencionado nos registros, já que você vai executar o modelo no TFLite.
Se a saída contiver Encountered unresolved custom op: edgetpu-custom-op, o dispositivo Coral não foi detectado. Verifique se você instalou a biblioteca de ambiente de execução da TPU de borda e conectou o dispositivo Coral ao computador. Você também pode seguir o guia de primeiros passos do Coral para testar a versão em Python das vinculações do Coral. Se a versão do Python funcionar, mas esses testes ainda falharem, envie um relatório de bug.
Executar o código inicial
Agora você já pode executar o código inicial. Siga estas etapas para começar.
- Mova para o diretório
starter_codeemtfjs-tflite-node-codelab. - execute
npm installpara instalar dependências. - Execute
npm startpara iniciar o projeto. Um app mostrando um feed de vídeo da webcam do computador vai abrir.
Qual é nosso ponto de partida?
Nosso ponto de partida é um app de câmera Electron básico desenvolvido para este codelab. O código foi simplificado para mostrar os conceitos do codelab e tem pouco tratamento de erros. Se você optar por reutilizar algum dos códigos em um app de produção, não se esqueça de corrigir erros e testar todo o código.

Conferir o código inicial
Há muitos arquivos nesse código inicial, mas o único que você precisa editar é renderer.js. Ele controla o que aparece na página, incluindo o feed de vídeo e os elementos HTML, e é onde você adiciona o modelo de aprendizado de máquina ao app. Entre os outros arquivos, há um index.html, mas ele apenas carrega o arquivo renderer.js. Há também um arquivo main.js, que é o ponto de entrada do Electron. Ele controla o ciclo de vida do app, incluindo o que mostrar quando ele é aberto e o que fazer quando ele é fechado, mas você não precisa fazer nenhuma mudança nele.
Abra o depurador
Talvez seja necessário depurar o app enquanto segue este codelab. Como esse app é baseado no Electron, ele tem o depurador do Chrome integrado. Na maioria das plataformas, é possível abrir com Ctrl + Shift + i. Clique na guia Console para ver registros e mensagens de erro do app.
Não há muito mais para explorar aqui, então vamos direto ao treinamento do classificador de imagens.
3. Treinar um classificador de imagens
Nesta seção, você vai treinar as versões do TFLite e do Coral de um modelo personalizado de classificação de imagens.
Treinar o classificador
Um classificador de imagens recebe imagens como entrada e atribui rótulos a elas. Neste codelab, você vai usar a Máquina que Aprende para treinar um modelo no navegador. Para acelerar o treinamento desta seção, use um computador desktop ou notebook em vez de um Raspberry Pi, mas copie os arquivos resultantes para o Pi.
Agora você está pronto para treinar um modelo. Se você não tiver certeza de qual tipo de modelo treinar, um detector de pessoas é uma opção fácil. Ele apenas detecta se uma pessoa está no quadro.
- Abra a página de treinamento do Máquina que Aprende em uma nova guia.
- Selecione Projeto de imagem e Modelo de imagem padrão.
- Adicione exemplos de imagens para cada classe. Usar a entrada da webcam é a maneira mais fácil de fazer isso. Você também pode renomear as classes.
- Quando você tiver coletado dados suficientes para cada classe (geralmente 50 amostras são suficientes), pressione Treinar modelo.
Quando o treinamento do modelo for concluído, uma prévia da saída dele vai aparecer.

Tente dar entradas diferentes ao modelo. Se você encontrar uma entrada classificada incorretamente, adicione-a aos dados de treinamento e treine o modelo novamente.
- Quando estiver satisfeito com a acurácia do modelo, clique em Exportar modelo. Você vai precisar baixar duas versões separadas do modelo.
- Exporte o modelo como um modelo de ponto flutuante do TensorFlow Lite. Será feito o download de um arquivo chamado
converted_tflite.zip. que é executado na CPU. - Exporte o modelo como um modelo do Tensorflow Lite EdgeTPU. Isso faz o download de um arquivo chamado
converted_edgetpu.zipque é executado na Coral Edge TPU.
4. Executar o modelo de CPU no app
Agora que você treinou um modelo, é hora de adicioná-lo ao app. Ao final desta seção, o app poderá executar o modelo usando a CPU do dispositivo.
Adicionar o arquivo de modelo ao app
Descompacte o arquivo do modelo converted_tflite.zip que você baixou ao treinar o classificador. Há dois arquivos no arquivo. model_uquant.tflite é o modelo do TFLite salvo, incluindo o gráfico e os pesos do modelo. labels.txt contém os rótulos legíveis das classes que o modelo prevê. Coloque os dois arquivos no modeldirectory.
Instalar dependências
Para carregar um modelo e pré-processar entradas, são necessárias algumas dependências do TensorFlow.js:
tfjs-tflite-node: o pacote do TensorFlow.js para executar modelos do TFLite no Node.js.@tensorflow/tfjs: o pacote principal do TensorFlow.js.
O @tensorflow/tfjs já está instalado, mas você precisa instalar o tfjs-tflite-node com este comando:
npm install --save tfjs-tflite-node
Depois de instalado, adicione-o ao app na parte de cima de renderer.js:
CODELAB parte 1: importar tfjs-tflite-node.
const {loadTFLiteModel} = require('tfjs-tflite-node');
Carregar o modelo
Agora você pode carregar o modelo. O tfjs-tflite-node fornece a função loadTFLiteModel para fazer isso. Ele pode carregar modelos de um caminho de arquivo, um ArrayBuffer ou um URL do TFHub. Para carregar o modelo e os pesos dele, adicione isto à função main:
CODELAB parte 1: carregue o modelo aqui.
const modelPath = './model/model_unquant.tflite';
const model = await loadTFLiteModel(modelPath);
const labels = fs.readFileSync('./model/labels.txt', 'utf8')
.split('\n');
Executar o modelo
A execução do modelo leva três etapas. Primeiro, extraia e pré-processe um frame de entrada da webcam. Em seguida, você executa o modelo nesse frame e recebe uma previsão. Depois disso, mostre a previsão na página.
Pré-processar a entrada da webcam
No momento, a webcam é apenas um elemento HTML, e os frames exibidos não estão disponíveis para o arquivo JavaScript renderer.js. Para extrair frames da webcam, o TensorFlow.js oferece tf.data.webcam, que fornece um método capture() fácil de usar para capturar frames da câmera.
Para usar, adicione este código de configuração a main():
CODELAB parte 1: configure tf.data.webcam aqui.
const tensorCam = await tf.data.webcam(webcam);
Em seguida, para capturar uma imagem a cada frame, adicione o seguinte a run():
CODELAB, parte 1: capture frames da webcam aqui.
const image = await tensorCam.capture();
Também é necessário pré-processar cada frame para que ele seja compatível com o modelo. O modelo usado neste codelab tem a forma de entrada [1, 224, 224, 3], então ele espera uma imagem RGB de 224 por 224 pixels. O tensorCam.capture() tem uma forma de [224, 224, 3], então você precisa adicionar uma dimensão extra na frente do tensor com tf.expandDims. Além disso, o modelo de CPU espera uma entrada Float32 entre -1 e 1, mas a webcam captura valores de 0 a 255. Divida o tensor de entrada por 127 para mudar o intervalo de [0, 255] para [0, ~2] e subtraia 1 para obter o intervalo desejado [-1, ~1]. Adicione estas linhas a tf.tidy() na função run() para fazer isso:
CODELAB parte 1: pré-processe os frames da webcam aqui.
const expanded = tf.expandDims(image, 0);
const divided = tf.div(expanded, tf.scalar(127));
const normalized = tf.sub(divided, tf.scalar(1));
É importante descartar os tensores depois de usá-los. O tf.tidy() faz isso automaticamente para o código contido no callback, mas não é compatível com funções assíncronas. É preciso descartar manualmente o tensor de imagem criado anteriormente chamando o método dispose() dele.
CODELAB parte 1: descarte os frames da webcam aqui.
image.dispose();
Executar o modelo e mostrar os resultados
Para executar o modelo na entrada pré-processada, chame model.predict() no tensor normalizado. Isso retorna um tensor unidimensional que contém a probabilidade prevista de cada rótulo. Multiplique essa probabilidade por 100 para receber a porcentagem de chance de cada rótulo e use a função showPrediction incluída no código inicial para mostrar a previsão do modelo na tela.
Esse código também usa stats.js para medir quanto tempo leva a previsão, colocando chamadas para stats.begin e stats.end em torno de model.predict.
CODELAB parte 1: execute o modelo e mostre os resultados aqui.
stats.begin();
const prediction = model.predict(normalized);
stats.end();
const percentage = tf.mul(prediction, tf.scalar(100));
showPrediction(percentage.dataSync(), labels);
Execute o app novamente com yarn start para ver as classificações do modelo.

Desempenho
Como está configurado atualmente, o modelo é executado na CPU. Isso é adequado para computadores desktop e a maioria dos laptops, mas pode não ser desejável se você executar em um Raspberry Pi ou outro dispositivo de baixa energia. Em um Raspberry Pi 4, você provavelmente verá cerca de 10 FPS, o que pode não ser rápido o suficiente para alguns aplicativos. Para melhorar o desempenho sem usar uma máquina mais rápida, use silício específico do aplicativo na forma de uma Coral Edge TPU.
5. Executar o modelo do Coral no seu app
Se você não tiver um dispositivo Coral, pule esta seção.
Esta etapa do codelab se baseia no código que você escreveu na última seção, mas é possível usar o checkpoint cpu_inference_working se quiser começar do zero.
As etapas para executar o modelo do Coral são quase idênticas às do modelo da CPU. A principal diferença é o formato do modelo. Como o Coral só aceita tensores uint8, o modelo é quantizado. Isso afeta os tensores de entrada transmitidos ao modelo e os tensores de saída que ele retorna. Outra diferença é que os modelos precisam ser compilados usando o compilador da Edge TPU para serem executados em uma TPU do Coral. O Teachable Machine já fez essa etapa, mas você pode aprender a fazer isso para outros modelos na documentação do Coral.
Adicionar o arquivo de modelo do Coral ao app
Descompacte o arquivo de modelo converted_edgetpu.zip que você baixou ao treinar o classificador. Há dois arquivos incluídos no arquivo. model_edgetpu.tflite é o modelo do TFLite salvo, incluindo o gráfico e os pesos do modelo. labels.txt contém os rótulos legíveis das classes que o modelo prevê. Coloque o arquivo modelo no diretório coral_model.
Instalar dependências
Para executar modelos do Coral, é necessário usar a biblioteca de tempo de execução da Edge TPU. Siga as instruções de configuração para instalar o app antes de continuar.
Os dispositivos Coral são acessados como delegados do TFLite. Para acessar esses recursos em JavaScript, instale o pacote coral-tflite-delegate:
npm install --save coral-tflite-delegate
Em seguida, importe o delegado adicionando esta linha à parte de cima do arquivo renderer.js:
CODELAB part 2: Import the delegate here.
const {CoralDelegate} = require('coral-tflite-delegate');
Carregar o modelo
Agora você já pode carregar o modelo do Coral. Faça isso da mesma forma que para o modelo de CPU, mas agora transmita opções para a função loadTFLiteModel para carregar o delegado do Coral.
CODELAB parte 2: carregue o modelo delegado aqui.
const coralModelPath = './coral_model/model_edgetpu.tflite';
const options = {delegates: [new CoralDelegate()]};
const coralModel = await loadTFLiteModel(coralModelPath, options);
Não é necessário carregar os rótulos porque eles são os mesmos do modelo de CPU.
Adicionar um botão para alternar entre CPU e Coral
Você vai adicionar o modelo do Coral junto com o modelo de CPU que adicionou na seção anterior. Executar os dois ao mesmo tempo dificulta a identificação das diferenças de performance. Por isso, um botão de alternância muda entre a execução do Coral e da CPU.
Adicione o botão com este código:
CODELAB parte 2: crie o botão de delegação aqui.
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);
Vamos conectar essa condição na função run(). Quando useCoralDelegate for "false", a versão da CPU será executada. Caso contrário, ele executa a versão do Coral, mas, por enquanto, não faz nada. Encapsule o código da execução do modelo de CPU em uma instrução if. Observe que o tensor expanded é deixado de fora da instrução "if" porque o modelo do Coral o usa.
CODELAB parte 2: verifique se é necessário usar o delegado aqui.
// 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);
}
Executar o modelo
A versão do modelo para Coral espera tensores uint8 de 0 a 255, então a entrada não precisa ser normalizada. No entanto, a saída também é um tensor uint8 no intervalo de 0 a 255. Ele precisa ser convertido em um ponto flutuante de 0 a 100 antes de ser exibido.
CODELAB parte 2: execute a previsão do Coral aqui. (Isso faz parte do snippet de código acima)
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);
Execute o app novamente com yarn start. Ele vai mostrar as classificações do acelerador Coral.

Você pode alternar entre a inferência do Coral e da CPU pressionando o botão. Você pode notar que as classificações de confiança do modelo do Coral são menos precisas do que as do modelo da CPU e geralmente terminam com uma casa decimal par. Essa perda de precisão é uma troca de executar um modelo quantizado no Coral. Isso geralmente não importa na prática, mas é algo a ser considerado.
Observação sobre a performance
A taxa de frames que você vê inclui pré-processamento e pós-processamento. Portanto, ela não representa o que o hardware do Coral é capaz de fazer. Para ter uma ideia melhor da performance, clique no medidor de QPS até que ele mostre a latência (em milissegundos), que mede apenas a chamada para model.predict. No entanto, isso ainda inclui o tempo necessário para mover os tensores para as vinculações C nativas do TFLite e depois para o dispositivo Coral. Portanto, não é uma medição perfeita. Para comparativos de desempenho mais precisos escritos em C++, consulte a página de comparativos da EdgeTPU.
Além disso, o vídeo foi gravado em um laptop em vez de um Raspberry Pi, então talvez você veja uma taxa de quadros por segundo diferente.
Acelerar o pré-processamento do Coral
Em alguns casos, é possível acelerar o pré-processamento trocando os backends do TFJS. O back-end padrão é o WebGL, que é bom para operações grandes e paralelizadas, mas esse app não faz muito isso na fase de pré-processamento. A única operação que ele usa é expandDims, que não é paralela. Você pode mudar para o back-end da CPU para evitar a latência extra de mover tensores para e da GPU adicionando esta linha após as importações na parte de cima do arquivo.
tf.setBackend(‘cpu');
Isso também afeta o pré-processamento do modelo de CPU do TFLite, que é paralelizado. Assim, o modelo é executado muito mais lentamente com essa mudança.
6. Acelerar o modelo de CPU com a WebNN
Se você não tiver um acelerador Coral ou quiser testar outra maneira de acelerar o modelo, use o delegado do WebNN TFLite. Esse delegado usa hardware de machine learning integrado aos processadores Intel para acelerar a inferência de modelos com o kit de ferramentas OpenVINO. Por isso, ele tem outros requisitos que não foram abordados na seção de configuração deste codelab, e você precisará instalar o kit de ferramentas OpenVINO. Verifique sua configuração com as Plataformas de sistema de destino compatíveis antes de continuar. No entanto, observe que o delegado WebNN ainda não é compatível com o macOS.
Instale o kit de ferramentas OpenVINO
O kit de ferramentas OpenVINO usa hardware de machine learning integrado aos processadores Intel para acelerar modelos. Você pode baixar uma versão pré-compilada da Intel ou criar uma do zero. Há várias maneiras de instalar o OpenVINO, mas, para este codelab, recomendamos que você use o script de instalação para Windows ou Linux. Instale a versão de ambiente de execução 2021.4.2 LTS, porque outras versões podem não ser compatíveis. Depois de executar o instalador, configure as variáveis de ambiente do shell conforme descrito nas instruções de instalação para Linux ou Windows ( solução permanente) ou executando o comando setupvars.sh (Linux) ou setupvars.bat (Windows) localizado no diretório webnn-tflite-delegate.
Verificar se o delegado do WebNN está funcionando
Para verificar se o delegado do WebNN está funcionando corretamente, execute os testes de integração do pacote webnn-tflite-delegate encontrado no diretório raiz do repositório. Para executar os testes de integração, execute estes comandos no diretório do pacote:
# In webnn-tflite-delegate/
npx yarn
npx yarn test-integration
A resposta será semelhante a esta:
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.
Se você vir uma saída como esta, isso indica um erro de configuração:
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.
Essa saída provavelmente significa que você não definiu as variáveis de ambiente do OpenVINO. Por enquanto, você pode definir essas variáveis executando o comando setupvars.sh (Linux) ou setupvars.bat (Windows), mas talvez queira defini-las permanentemente seguindo as instruções para Linux ou Windows ( solução permanente). Se você estiver usando o Windows, o
setupvars.bat
não é compatível com o Git Bash. Por isso, execute esse e outros comandos deste codelab no prompt de comando do Windows.
Instalar o delegado do WebNN
Com o OpenVINO instalado, você já pode acelerar o modelo de CPU com o WebNN. Esta seção do codelab se baseia no código que você escreveu na seção "Executar o modelo de CPU no seu app". Você pode usar o código escrito nesta etapa, mas, se já tiver concluído a seção do Coral, use o checkpoint cpu_inference_working para começar do zero.
A parte do Node.js do delegado WebNN é distribuída no npmjs. Para instalar, execute este comando:
npm install --save webnn-tflite-delegate
Em seguida, importe o delegado adicionando esta linha à parte de cima do arquivo renderer.js:
CODELAB part 2: Import the delegate here.
const {WebNNDelegate, WebNNDevice} = require('webnn-tflite-delegate');
O delegado WebNN oferece suporte à execução na CPU ou na GPU. O WebNNDevice permite escolher qual usar.
Carregar o modelo
Agora você está pronto para carregar o modelo com o delegado WebNN ativado. No Coral, era necessário carregar um arquivo de modelo diferente, mas o WebNN é compatível com o mesmo formato de modelo do TFLite. Adicione o WebNNDelegate à lista de delegados transmitidos ao modelo para ativá-lo:
CODELAB parte 2: carregue o modelo delegado aqui.
let webnnModel = await loadTFLiteModel(modelPath, {
delegates: [new WebNNDelegate({webnnDevice: WebNNDevice.DEFAULT})],
});
Não é necessário carregar os rótulos novamente porque é o mesmo modelo.
Adicionar um botão para alternar entre a CPU do TfLite e o WebNN
Agora que a versão WebNN do modelo está pronta, adicione um botão para alternar entre a inferência de CPU do WebNN e do TfLite. Executar os dois ao mesmo tempo dificulta a identificação de diferenças de performance.
Adicione o botão com este código (observe que ele ainda não vai mudar de modelo):
CODELAB parte 2: crie o botão de delegação aqui.
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);
Esse código também adiciona um elemento div que você usa para configurar as definições do WebNN na próxima seção.
Adicionar um menu suspenso para alternar entre dispositivos WebNN
A WebNN é compatível com a execução na CPU e na GPU. Por isso, adicione um menu suspenso para alternar entre elas. Adicione este código depois do código que cria o botão:
// 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);
}
Agora, se você executar o app, vai aparecer um menu suspenso com as opções "Padrão", "GPU" e "CPU". Escolher uma delas não vai fazer nada agora, já que o menu suspenso ainda não foi conectado. 
Fazer com que o menu suspenso mude o dispositivo
Para conectar o menu suspenso e mudar o dispositivo WebNN usado, adicione um listener ao evento change do elemento seletor do menu suspenso. Quando o valor selecionado mudar, recrie o modelo WebNN com o dispositivo WebNN correspondente selecionado nas opções de delegado.
Adicione o seguinte código depois do código que adicionou o menu suspenso:
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})],
});
});
Com essa mudança, o menu suspenso cria um novo modelo com as configurações corretas sempre que é alterado. Agora é hora de conectar o modelo WebNN e usá-lo para inferência.
Executar o modelo WebNN
O modelo WebNN está pronto para ser usado, mas o botão para alternar entre WebNN e TfLite CPU ainda não muda o modelo. Para mudar o modelo, primeiro renomeie a variável model de quando você carregou o modelo de CPU do TfLite na primeira seção do codelab.
Mude a linha a seguir...
const model = await loadTFLiteModel(modelPath);
...para que corresponda a esta linha.
const cpuModel = await loadTFLiteModel(modelPath);
Com a variável model renomeada para cpuModel, adicione isso à função run para escolher o modelo correto com base no estado do botão:
CODELAB parte 2: verifique se é necessário usar o delegado aqui.
let model;
if (useWebNNDelegate) {
model = webnnModel;
} else {
model = cpuModel;
}
Agora, quando você executar o app, o botão vai alternar entre a CPU do TfLite e o WebNN. 
Você também pode alternar entre a inferência de CPU e GPU do WebNN se tiver uma GPU Intel integrada.
Observação sobre a performance
A taxa de frames que você vê inclui pré-processamento e pós-processamento. Portanto, ela não representa o que a WebNN é capaz de fazer. Para ter uma ideia melhor da performance, clique no medidor de QPS até que ele mostre a latência (em milissegundos), que mede apenas a chamada para model.predict. No entanto, isso ainda inclui o tempo necessário para mover os tensores para as vinculações C nativas do TFLite. Portanto, não é uma medição perfeita.
7. Parabéns
Parabéns! Você acabou de concluir seu primeiro projeto Coral / WebNN usando tfjs-tflite-node no Electron.
Teste com várias imagens. Você também pode treinar um novo modelo no Teachable Machine para classificar algo completamente diferente.
Resumo
Neste codelab, você aprendeu como:
- Como instalar e configurar o pacote npm tfjs-tflite-node para executar modelos do TFLite no Node.js.
- Como instalar a biblioteca de ambiente de execução da Edge TPU para executar modelos em um dispositivo Coral.
- Como acelerar a inferência de modelos usando uma TPU de borda Coral.
- Como acelerar a inferência de modelos com a WebNN.
Qual é a próxima etapa?
Agora que você já tem uma base de trabalho para começar, quais ideias criativas você pode adotar para ampliar esse executor de modelo de machine learning para um caso de uso real em que você esteja trabalhando? Talvez você possa revolucionar o setor em que trabalha com inferência rápida e acessível ou modificar uma torradeira para que ela pare de tostar quando o pão estiver no ponto certo. As possibilidades são infinitas.
Para saber mais sobre como o Teachable Machine treinou o modelo que você usou, confira nosso codelab sobre aprendizado por transferência. Se você estiver procurando outros modelos que funcionam com o Coral, como reconhecimento de fala e estimativa de postura, acesse coral.ai/models. Você também encontra versões de CPU desses modelos e muitos outros no TensorFlow Hub.
Compartilhe o que você sabe conosco
Você pode estender facilmente o que fez hoje para outros casos de uso criativos. Recomendamos que você pense fora da caixa e continue criando.
Marque-nos nas redes sociais usando a hashtag #MadeWithTFJS para que seu projeto tenha a chance de ser destacado no nosso blog do TensorFlow ou até em eventos futuros. Adoraríamos ver o que você cria.