Tensorflow
Javascript
Machine Learning
Browser
Utiliser TensorFlow.js pour exécuter des modèles de machine learning directement dans le navigateur avec des prédictions en temps réel.
Pourquoi TensorFlow.js dans le navigateur ?
TensorFlow.js permet d'exécuter des modèles de machine learning directement dans le navigateur ou sous Node.js, sans serveur backend. Les avantages sont nombreux :
- Confidentialité : les données ne quittent jamais l'appareil de l'utilisateur.
- Latence zéro : pas d'aller-retour serveur, les prédictions sont immédiates.
- Pas de coût serveur : le GPU/CPU du client fait le travail.
- Fonctionne hors ligne après le chargement du modèle.
Cas d'usage : classification d'images, détection de poses, analyse de sentiments, reconnaissance vocale, détection d'objets en temps réel via la caméra.
Installation et premiers pas
Via npm pour un projet Node.js ou bundler (Webpack, Vite) :
npm install @tensorflow/tfjs
Ou directement via CDN dans le navigateur :
<script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs@latest"></script>
Vérification que TensorFlow.js est opérationnel :
import * as tf from '@tensorflow/tfjs';
// Informations sur le backend utilisé (WebGL, CPU, WASM...)
console.info('Backend:', tf.getBackend());
// Exemple de tenseur simple
const a = tf.tensor([1, 2, 3, 4]);
const b = tf.scalar(2);
const result = a.mul(b);
result.print(); // [2, 4, 6, 8]
Backends disponibles
- WebGL — utilise le GPU du navigateur (le plus rapide).
- WASM — WebAssembly, bon compromis CPU/performance.
- CPU — fallback pur JavaScript, le plus lent.
Utiliser des modèles pré-entraînés
TensorFlow.js propose des modèles pré-entraînés prêts à l'emploi via @tensorflow-models :
npm install @tensorflow-models/mobilenet
npm install @tensorflow-models/coco-ssd
npm install @tensorflow-models/pose-detection
Classification d'image avec MobileNet :
import * as tf from '@tensorflow/tfjs';
import * as mobilenet from '@tensorflow-models/mobilenet';
async function classifierImage(imageElement) {
// Charger le modèle (mis en cache après le premier chargement)
const model = await mobilenet.load();
// Classer l'image
const predictions = await model.classify(imageElement);
// predictions = [{ className: 'cat', probability: 0.93 }, ...]
return predictions;
}
// Utilisation
const img = document.getElementById('mon-image');
const predictions = await classifierImage(img);
console.info(predictions[0]); // { className: 'tabby cat', probability: 0.932 }
A retenir : le premier chargement du modèle peut prendre quelques secondes (fichiers de ~20 Mo). Utilisez un loader pendant ce temps.
Prédictions en temps réel
Détection d'objets en temps réel depuis la webcam avec COCO-SSD :
import * as cocoSsd from '@tensorflow-models/coco-ssd';
async function demarrerDetection() {
const video = document.getElementById('webcam');
const canvas = document.getElementById('overlay');
const ctx = canvas.getContext('2d');
// Accéder à la webcam
const stream = await navigator.mediaDevices.getUserMedia({ video: true });
video.srcObject = stream;
await video.play();
// Charger le modèle
const model = await cocoSsd.load();
// Boucle de détection
async function detecter() {
const predictions = await model.detect(video);
ctx.clearRect(0, 0, canvas.width, canvas.height);
predictions.forEach(pred => {
const [x, y, width, height] = pred.bbox;
ctx.strokeStyle = '#dd0031';
ctx.lineWidth = 2;
ctx.strokeRect(x, y, width, height);
ctx.fillStyle = '#dd0031';
ctx.fillText(
`${pred.class} (${Math.round(pred.score * 100)}%)`,
x, y - 5
);
});
requestAnimationFrame(detecter);
}
detecter();
}
Entraîner un modèle simple
Entraîner un réseau de neurones pour prédire une valeur (exemple : y = 2x - 1) :
import * as tf from '@tensorflow/tfjs';
// Créer un modèle séquentiel simple
const model = tf.sequential();
model.add(tf.layers.dense({ units: 1, inputShape: [1] }));
// Compiler le modèle
model.compile({
optimizer: 'sgd',
loss: 'meanSquaredError'
});
// Données d'entraînement
const xs = tf.tensor1d([-1, 0, 1, 2, 3, 4]);
const ys = tf.tensor1d([-3, -1, 1, 3, 5, 7]); // y = 2x - 1
// Entraîner
await model.fit(xs, ys, {
epochs: 250,
callbacks: {
onEpochEnd: (epoch, logs) => {
if (epoch % 50 === 0) {
console.info(`Epoch ${epoch}: loss = ${logs.loss.toFixed(4)}`);
}
}
}
});
// Prédire
const prediction = model.predict(tf.tensor1d([5]));
prediction.print(); // ~9 (2*5 - 1)
Performances et bonnes pratiques
- Appeler
tf.dispose()outf.tidy()pour libérer la mémoire GPU après chaque prédiction. - Charger le modèle une seule fois et le réutiliser — ne pas le recharger à chaque prédiction.
- Utiliser
model.warmup()au démarrage pour éviter la latence lors de la première inférence. - Privilégier le backend WebGL sur desktop, WASM sur mobile si WebGL est instable.
- Afficher un indicateur de chargement pendant le téléchargement du modèle.
// Bonne pratique : utiliser tidy() pour éviter les fuites mémoire
const prediction = tf.tidy(() => {
const input = tf.tensor2d([[5]]);
return model.predict(input);
});
// Afficher puis libérer
prediction.print();
prediction.dispose();
Mémoire GPU : chaque tenseur créé consomme de la mémoire GPU. Sans
tf.tidy() ou dispose(), vous créez des fuites qui ralentissent ou bloquent le navigateur.