Introdução
Este projeto guia você pelo processo de implantação de um modelo MobileNetV2 pré-treinado usando TensorFlow.js dentro de uma aplicação web Flask. MobileNetV2 é uma rede neural profunda leve, usada principalmente para classificação de imagens. TensorFlow.js permite executar modelos de machine learning diretamente no navegador, possibilitando aplicações web interativas. Flask, um framework web Python, servirá como backend para hospedar nossa aplicação. Ao final deste projeto, você terá uma aplicação web em execução que classifica imagens em tempo real usando o modelo MobileNetV2.
👀 Pré-visualização
🎯 Tarefas
Neste projeto, você aprenderá:
- Como exportar um modelo MobileNetV2 pré-treinado do Keras para um formato compatível com TensorFlow.js.
- Como criar uma aplicação Flask simples para servir seu conteúdo web e modelo.
- Como projetar uma página HTML para carregar e exibir imagens para classificação.
- Como usar TensorFlow.js para carregar o modelo exportado no navegador.
- Como pré-processar imagens no navegador para corresponder aos requisitos de entrada do MobileNetV2.
- Como executar o modelo no navegador para classificar imagens e exibir os resultados.
🏆 Conquistas
Após concluir este projeto, você será capaz de:
- Converter um modelo Keras pré-treinado em um formato que pode ser usado com TensorFlow.js, permitindo que modelos de ML sejam executados no navegador.
- Configurar uma aplicação Flask e servir conteúdo HTML e arquivos estáticos.
- Integrar TensorFlow.js em uma aplicação web para realizar tarefas de machine learning no lado do cliente.
- Pré-processar imagens em JavaScript para torná-las compatíveis com os requisitos de entrada de modelos de deep learning.
- Fazer previsões usando um modelo de deep learning no navegador e exibir os resultados dinamicamente na página web.
Preparando o Ambiente e os Arquivos do Projeto
Antes de começarmos a codificar, é importante configurar corretamente o ambiente do nosso projeto. Isso inclui a instalação dos pacotes necessários e a compreensão da estrutura de arquivos do projeto que já está em vigor.
Primeiramente, familiarize-se com a estrutura inicial de arquivos do projeto. Os seguintes arquivos e pastas já estão fornecidos no seu diretório de trabalho:
tree
Saída:
.
├── app.py
├── model_convert.py
├── static
│ ├── imagenet_classes.js
│ ├── tfjs.css
│ └── tfjs.js
└── templates
└── tfjs.html
2 directories, 6 files
A estrutura do seu projeto consiste em vários componentes-chave, cada um desempenhando um papel vital na implantação de sua aplicação web para classificação de imagens usando o modelo MobileNetV2 com TensorFlow.js e Flask. Abaixo está uma visão geral de cada diretório e arquivo dentro do seu projeto:
app.py: Este é o arquivo Python principal para sua aplicação Flask. Ele inicializa o aplicativo Flask, configura o roteamento para sua página web e inclui qualquer lógica de backend necessária para servir seu modelo TensorFlow.js e conteúdo web.model_convert.py: Este script Python é responsável por carregar o modelo MobileNetV2 pré-treinado e convertê-lo para um formato compatível com TensorFlow.js. Essa conversão é crucial para permitir que o modelo seja executado em um navegador web.static/: Este diretório armazena arquivos estáticos que são necessários para sua aplicação web. Estes incluem:imagenet_classes.js: Um arquivo JavaScript contendo as classes ImageNet. Este arquivo é usado para mapear as previsões numéricas do modelo para nomes de classes legíveis por humanos.tfjs.css: Uma nova adição, este arquivo Cascading Style Sheets (CSS) é usado para estilizar a interface do usuário da aplicação web. Ele define os aspectos visuais da sua aplicação, como layouts, cores e fontes, garantindo uma interface mais envolvente e amigável.tfjs.js: Outro arquivo novo, este arquivo JavaScript provavelmente contém a lógica para carregar o modelo TensorFlow.js, processar imagens e executar previsões dentro do navegador. Este script é central para a interatividade da sua aplicação, lidando com operações do lado do cliente relacionadas ao modelo TensorFlow.js.
templates/: Este diretório contém arquivos HTML que definem a estrutura e o layout da sua aplicação web. Neste caso, ele inclui:tfjs.html: O template HTML principal para sua aplicação,tfjs.htmlinclui a marcação necessária para exibir imagens, resultados de previsão e possivelmente elementos de interação do usuário, como botões de upload de arquivos. Ele integra o modelo TensorFlow.js, aproveitando o scripttfjs.jspara funcionalidades relacionadas ao modelo etfjs.csspara estilização.
Esta estrutura é projetada para separar as preocupações, tornando seu projeto modular e mais fácil de gerenciar. Os diretórios static e templates são padrão em aplicações Flask, ajudando a organizar ativos estáticos e templates HTML, respectivamente. A separação do script de conversão do modelo (model_convert.py) da lógica principal da aplicação (app.py) aprimora a modularidade e a capacidade de manutenção do seu código.
Em seguida, instale os pacotes necessários:
## Install the required Python packages
pip install tensorflow==2.14.0 tensorflowjs==4.17.0 flask==3.0.2 flask-cors==4.0.0
Os pacotes incluem TensorFlow para o modelo de machine learning, TensorFlow.js para converter o modelo para ser usado em um ambiente web, Flask para criar o servidor web e Flask-CORS para lidar com requisições de origem cruzada (cross-origin requests), que são comuns em aplicações web.
Exportando o Modelo MobileNetV2 Pré-Treinado para o Formato TensorFlow.js
Para usar o modelo MobileNetV2 no navegador, primeiro precisamos exportá-lo do Keras para um formato que o TensorFlow.js possa entender.
## Complete the model_convert.py
## Exporting MobileNetV2 model
import tensorflowjs as tfjs
from tensorflow.keras.applications.mobilenet_v2 import MobileNetV2
## Load the pre-trained MobileNetV2 model
model = MobileNetV2(weights='imagenet')
## Convert and save the model in TensorFlow.js format
tfjs.converters.save_keras_model(model, 'static/model/')
Nesta etapa, você utiliza as bibliotecas TensorFlow e TensorFlow.js para carregar um modelo MobileNetV2 pré-treinado e convertê-lo em um formato compatível com TensorFlow.js.
MobileNetV2 é escolhido por sua eficiência e tamanho relativamente pequeno, tornando-o adequado para implantação na web. Essa conversão é necessária porque o formato original do modelo usado no TensorFlow baseado em Python não é diretamente utilizável em um ambiente web. A função tfjs.converters.save_keras_model pega o modelo Keras e o salva em um diretório estruturado de forma que o TensorFlow.js possa carregá-lo facilmente mais tarde na aplicação web.
Então você pode executar:
python model_convert.py
O modelo convertido será salvo na pasta static/model/:
ls static/model
## group1-shard1of4.bin group1-shard2of4.bin group1-shard3of4.bin group1-shard4of4.bin model.json
Este processo inclui salvar os pesos e a arquitetura do modelo em uma série de arquivos shard e um arquivo model.json, respectivamente.
Criando a Aplicação Flask
Agora, vamos configurar uma aplicação Flask simples para servir nossa página web e o modelo TensorFlow.js.
## Complete the app.py
## Setting up the Flask application
from flask import Flask, render_template
from flask_cors import CORS
app = Flask(__name__)
cors = CORS(app) ## Enable Cross-Origin Resource Sharing
@app.route("/")
def hello():
## Serve the HTML page
return render_template('tfjs.html')
if __name__ == '__main__':
app.run(host='0.0.0.0', port='8080', debug=True)
Esta etapa envolve a configuração de um servidor web Flask básico. Flask é um micro framework web escrito em Python, conhecido por sua simplicidade e facilidade de uso.
Você começa importando Flask e CORS (Cross-Origin Resource Sharing) de suas respectivas bibliotecas. CORS é essencial para aplicações web que solicitam recursos de diferentes domínios, garantindo que sua aplicação web possa fazer requisições com segurança ao seu servidor Flask.
Você define uma rota simples ("/") que serve uma página HTML (tfjs.html), que conterá seu código TensorFlow.js do lado do cliente. A aplicação Flask é configurada para rodar em sua máquina local (host='0.0.0.0') e ouvir na porta 8080. A configuração debug=True é útil durante o desenvolvimento, pois fornece mensagens de erro detalhadas e recarrega automaticamente o servidor quando as alterações no código são detectadas.
Agora, você pode executar a aplicação web Flask:
python app.py
## * Serving Flask app 'app'
## * Debug mode: on
## WARNING: This is a development server. Do not use it in a production ## deployment. Use a production WSGI server instead.
## * Running on all addresses (0.0.0.0)
## * Running on http://127.0.0.1:8080
## * Running on http://172.18.0.7:8080
## Press CTRL+C to quit
Preparando a Estrutura HTML
Agora, precisamos criar a estrutura HTML da nossa aplicação em templates/tfjs.html. Isso inclui o layout para upload de imagem, visualização e exibição dos resultados da previsão.
<!-- HTML structure for the Image Prediction application -->
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Image Prediction</title>
<link
href="https://cdn.jsdelivr.net/npm/tailwindcss@2.0.2/dist/tailwind.min.css"
rel="stylesheet"
/>
<script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs"></script>
<link rel="stylesheet" href="static/tfjs.css" />
</head>
<body class="flex flex-col items-center justify-center min-h-screen">
<div class="card bg-white p-6 rounded-lg max-w-sm">
<h1 class="text-xl font-semibold mb-4 text-center">Image Prediction</h1>
<div class="flex flex-col items-center">
<label
for="imageUpload"
class="button-custom cursor-pointer mb-4 flex items-center justify-center"
>
<span>Upload Image</span>
<input
type="file"
id="imageUpload"
class="file-input"
accept="image/*"
/>
</label>
<div
id="imagePreviewContainer"
class="mb-4 w-56 h-56 border border-dashed border-gray-300 flex items-center justify-center"
>
<img
id="imagePreview"
class="max-w-full max-h-full"
style="display: none"
/>
</div>
<h5 id="output" class="text-md text-gray-700">
Upload an image to start prediction
</h5>
<script type="module" src="static/tfjs.js"></script>
</div>
</div>
</body>
</html>
Esta etapa envolve a criação da estrutura básica da nossa aplicação web usando HTML. Definimos o tipo de documento como HTML e definimos o atributo de idioma como inglês.
Na seção head, incluímos metadados como o conjunto de caracteres e as configurações de viewport para design responsivo. Também vinculamos à biblioteca Tailwind CSS para utilizar suas classes utilitárias para estilizar nossa aplicação. A seção body contém um elemento div com a classe card, que serve como um contêiner para o conteúdo da nossa aplicação.
Dentro deste contêiner, temos uma tag h1 para o título da aplicação, um elemento label para o botão de upload de imagem (que é estilizado para parecer um botão usando Tailwind CSS e classes personalizadas) e um elemento div para servir como um contêiner para a visualização da imagem. O elemento input do tipo file é oculto e acionado quando o rótulo é clicado, permitindo que o usuário faça upload de uma imagem. O elemento div com um id de imagePreviewContainer exibirá a imagem carregada, e a tag h5 será usada para exibir mensagens ao usuário.
Adicionar Estilização
Nesta etapa, adicionaremos alguma estilização CSS básica usando Tailwind CSS para layout e estética em static/tfjs.css, juntamente com alguns estilos personalizados para nossa aplicação.
body {
background-color: #f0f2f5;
}
.card {
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
}
.button-custom {
background-color: #4f46e5; /* Indigo 600 */
color: white;
padding: 0.5rem 1.5rem;
border-radius: 0.375rem; /* rounded-md */
transition: background-color 0.2s;
}
.button-custom:hover {
background-color: #4338ca; /* Indigo 700 */
}
.file-input {
opacity: 0;
position: absolute;
z-index: -1;
}
Nesta etapa, adicionamos estilos CSS personalizados para aprimorar a aparência da nossa aplicação web.
Definimos a cor de fundo do corpo para um cinza claro para um fundo neutro. A classe card adiciona uma sombra à caixa para criar um efeito semelhante a um cartão para o contêiner. A classe button-custom estiliza o botão de upload com uma cor de fundo índigo, texto branco, preenchimento e cantos arredondados.
Também incluímos um efeito de hover para alterar ligeiramente a cor de fundo do botão quando o mouse passa por cima, fornecendo um feedback visual ao usuário. A classe file-input é usada para ocultar o elemento de entrada de arquivo real, tornando o rótulo estilizado personalizado o principal elemento interativo para uploads de arquivos.
Carregar o Modelo TensorFlow
Nas etapas restantes, completaremos o arquivo templates/tfjs.js.
Agora, vamos adicionar TensorFlow.js ao nosso projeto e, em seguida, escrever código JavaScript para carregar nosso modelo TensorFlow. Usaremos uma função assíncrona para aguardar o carregamento do modelo antes de fazer qualquer previsão.
import { IMAGENET_CLASSES } from "./imagenet_classes.js";
const outputDiv = document.getElementById("output");
let model;
async function loadModel() {
try {
outputDiv.textContent = "Loading TF Model...";
model = await tf.loadLayersModel(
"https://****.labex.io/static/model/model.json"
); // Update URL
outputDiv.textContent = "TF Model Loaded.";
} catch (error) {
outputDiv.textContent = `Error loading model: ${error}`;
}
}
loadModel();
Nota: Você deve substituir a URL em tf.loadLayersModel pela URL do ambiente atual. Você pode encontrá-la alternando para a aba Web 8080.

Esta etapa envolve adicionar TensorFlow.js ao nosso projeto, incluindo sua tag de script em nosso documento HTML.
Em seguida, escrevemos código JavaScript para carregar assincronamente um modelo TensorFlow pré-treinado. Usamos a função tf.loadLayersModel, fornecendo a ela uma URL para o arquivo JSON do nosso modelo. Esta função retorna uma promise que é resolvida com o modelo carregado. Atualizamos o conteúdo de texto do outputDiv para informar o usuário sobre o status de carregamento do modelo. Se o modelo carregar com sucesso, exibimos "TF Model Loaded."
Caso contrário, capturamos quaisquer erros e exibimos uma mensagem de erro ao usuário. Esta etapa é crucial para permitir que nossa aplicação faça previsões, pois o modelo precisa ser carregado e estar pronto antes que qualquer processamento de imagem possa ocorrer.
Gerenciar Upload e Pré-visualização de Imagens
Esta etapa envolve a criação de funcionalidade para que os usuários carreguem imagens e vejam uma pré-visualização antes que a previsão seja feita. Usaremos um FileReader para ler o arquivo carregado e exibi-lo.
// Continue in static/tfjs.js
const imageUpload = document.getElementById("imageUpload");
const imagePreview = document.getElementById("imagePreview");
imageUpload.addEventListener("change", async (e) => {
const file = e.target.files[0];
if (file) {
const reader = new FileReader();
reader.onload = (e) => {
const img = new Image();
img.src = e.target.result;
img.onload = async () => {
imagePreview.src = img.src;
imagePreview.style.display = "block";
const processedImage = await preprocessImage(img);
makePrediction(processedImage);
};
};
reader.readAsDataURL(file);
}
});
Esta etapa envolve a configuração de um ouvinte de evento para a entrada de upload de imagem.
Quando um usuário seleciona um arquivo, usamos um FileReader para ler o arquivo como uma Data URL. Em seguida, criamos um objeto Image e definimos seu atributo src para o resultado do FileReader, efetivamente carregando a imagem no navegador. Uma vez que a imagem é carregada, exibimos ela dentro do contêiner imagePreview definindo o atributo src do imagePreview para o src da imagem e tornando o elemento imagePreview visível.
Então, a imagem é pré-processada e predita pelo nosso modelo, completaremos essas funções em etapas posteriores.
Pré-processar a Imagem para Previsão
Antes de fazer uma previsão, precisamos pré-processar a imagem carregada para corresponder aos requisitos de entrada do nosso modelo.
// Continue in static/tfjs.js
async function preprocessImage(imageElement) {
try {
let img = tf.browser.fromPixels(imageElement).toFloat();
img = tf.image.resizeBilinear(img, [224, 224]);
const offset = tf.scalar(127.5);
const normalized = img.sub(offset).div(offset);
const batched = normalized.reshape([1, 224, 224, 3]);
return batched;
} catch (error) {
outputDiv.textContent = `Error in model prediction: ${error}`;
}
}
Antes de fazer uma previsão, precisamos pré-processar a imagem carregada para corresponder ao formato de entrada esperado pelo nosso modelo TensorFlow. Este pré-processamento inclui o redimensionamento da imagem para as dimensões necessárias (neste caso, 224x224 pixels) e a normalização dos valores dos pixels.
Usamos operações TensorFlow.js como tf.browser.fromPixels para converter a imagem em um tensor, tf.image.resizeBilinear para redimensionamento e operações aritméticas para normalizar os valores dos pixels. A imagem pré-processada é então remodelada em um lote de um (para corresponder ao formato de entrada esperado pelo modelo), tornando-a pronta para a previsão.
Fazer uma Previsão
Uma vez que a imagem é pré-processada, estamos prontos para fazer uma previsão. A função makePrediction recebe a imagem processada como entrada, alimenta-a através do modelo e interpreta a saída para determinar o rótulo de classe mais provável.
// Continue in static/tfjs.js
async function makePrediction(processedImage) {
try {
const prediction = model.predict(processedImage);
const highestPredictionIndex = await tf.argMax(prediction, 1).data();
const label = IMAGENET_CLASSES[highestPredictionIndex];
outputDiv.textContent = `Prediction: ${label}`;
} catch (error) {
outputDiv.textContent = `Error making prediction: ${error}`;
}
}
Nesta etapa, usamos a função model.predict(processedImage) para alimentar a imagem pré-processada no modelo TensorFlow. A função tf.argMax(prediction, 1).data() é usada para encontrar o índice do valor mais alto no array de previsões, que corresponde ao rótulo de classe mais provável para a imagem. Este rótulo é então exibido ao usuário.
Mude para a aba "Web 8080" e recarregue a página web para ver os seguintes efeitos.
Resumo
Neste projeto, você aprendeu como usar um modelo MobileNetV2 pré-treinado em uma aplicação web Flask usando TensorFlow.js. Começamos instalando as dependências necessárias. Em seguida, exportamos o modelo MobileNetV2 para um formato compatível com TensorFlow.js e configuramos uma aplicação Flask para servir nossa página web. Finalmente, criamos uma página HTML que usa TensorFlow.js para classificar imagens no navegador com nosso modelo MobileNetV2. Seguindo estes passos, você criou uma aplicação web que usa deep learning para classificação de imagens em tempo real.
Este projeto demonstra o poder de combinar tecnologias web tradicionais com modelos avançados de machine learning para criar aplicações web interativas e inteligentes. Você pode estender este projeto adicionando mais recursos, como a capacidade de fazer upload de diferentes imagens, melhorando a interface do usuário ou até mesmo integrando modelos mais complexos para diferentes tarefas.



