🧠 COURS COMPLET

TensorFlow.js

Maîtrisez le Machine Learning dans le navigateur

Tenseurs Modèles Entraînement Classification Transfer Learning
01

Introduction à TensorFlow.js

TensorFlow.js est une bibliothèque JavaScript pour le machine learning développée par Google. Elle permet d'entraîner et d'exécuter des modèles de ML directement dans le navigateur ou Node.js.

🌐

Dans le Navigateur

Exécutez des modèles ML sans serveur backend, directement côté client avec WebGL.

🚀

Performance GPU

Accélération GPU via WebGL pour des calculs rapides et efficaces.

🔒

Confidentialité

Les données restent sur l'appareil de l'utilisateur, sans transmission au serveur.

♻️

Réutilisation

Importez des modèles Python TensorFlow/Keras existants.

💡
Cas d'usage : Classification d'images, reconnaissance vocale, prédiction de texte, détection d'objets, analyse de sentiment, recommandations personnalisées.
02

Installation et Configuration

Via CDN (Recommandé pour débuter)

HTML
<script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs@4.11.0"></script>

<script>
    // Vérifier que TensorFlow.js est chargé
    console.log('TensorFlow.js version:', tf.version.tfjs);
</script>

Via NPM

Bash
npm install @tensorflow/tfjs
JavaScript
import * as tf from '@tensorflow/tfjs';

console.log('TensorFlow.js version:', tf.version.tfjs);
03

Les Tenseurs — Concept Fondamental

Un tenseur est une structure de données multi-dimensionnelle, similaire à un tableau. C'est l'unité de base de TensorFlow.js.

Scalaire (0D)

Une seule valeur
5

Vecteur (1D)

Tableau 1D
[1, 2, 3]

Matrice (2D)

Tableau 2D
[[1,2], [3,4]]

Tenseur (3D+)

Tableau 3D+
Images RGB

Création de Tenseurs

JavaScript
// Scalaire (0D)
const scalar = tf.scalar(42);
scalar.print(); // Tensor 42

// Vecteur (1D)
const vector = tf.tensor1d([1, 2, 3, 4, 5]);
vector.print(); // Tensor [1, 2, 3, 4, 5]

// Matrice (2D)
const matrix = tf.tensor2d([[1, 2], [3, 4], [5, 6]], [3, 2]);
matrix.print();

// Tenseur 3D (ex: image RGB 2x2 pixels)
const image = tf.tensor3d([
    [[255, 0, 0], [0, 255, 0]],
    [[0, 0, 255], [255, 255, 0]]
], [2, 2, 3]);

// Depuis un tableau avec shape
const fromArray = tf.tensor([1, 2, 3, 4], [2, 2]);
fromArray.print(); // [[1, 2], [3, 4]]
🎮 Démo Interactive — Créer des Tenseurs
Cliquez pour exécuter la démo...
⚠️
Gestion de la Mémoire : Les tenseurs occupent de la mémoire GPU. Utilisez tensor.dispose() ou tf.tidy() pour libérer la mémoire.
JavaScript
// ❌ Mauvaise pratique — fuite mémoire
const a = tf.tensor([1, 2, 3]);
const b = tf.tensor([4, 5, 6]);
const c = a.add(b);

// ✅ Bonne pratique avec dispose
const a = tf.tensor([1, 2, 3]);
const b = tf.tensor([4, 5, 6]);
const c = a.add(b);
a.dispose();
b.dispose();

// ✅ Meilleure pratique avec tidy
const result = tf.tidy(() => {
    const a = tf.tensor([1, 2, 3]);
    const b = tf.tensor([4, 5, 6]);
    return a.add(b);
});
// a et b sont automatiquement nettoyés
result.print();
result.dispose();
04

Opérations sur les Tenseurs

Opérations Mathématiques de Base

JavaScript
const a = tf.tensor([1, 2, 3, 4]);
const b = tf.tensor([5, 6, 7, 8]);

a.add(b).print();    // [6, 8, 10, 12]
a.sub(b).print();    // [-4, -4, -4, -4]
a.mul(b).print();    // [5, 12, 21, 32]
a.div(b).print();    // [0.2, 0.33, 0.43, 0.5]
a.pow(tf.scalar(2)).print(); // [1, 4, 9, 16]
tf.sqrt(a).print();  // [1, 1.41, 1.73, 2]

Opérations d'Agrégation

JavaScript
const tensor = tf.tensor2d([[1, 2, 3], [4, 5, 6]]);

tensor.sum().print();   // 21
tensor.mean().print();  // 3.5
tensor.max().print();   // 6
tensor.min().print();   // 1

// Somme par axe
tensor.sum(0).print();  // [5, 7, 9]  — colonnes
tensor.sum(1).print();  // [6, 15]    — lignes

Transformation de Forme

JavaScript
const original = tf.tensor([1, 2, 3, 4, 5, 6]);

original.reshape([2, 3]).print();   // [[1,2,3], [4,5,6]]

const matrix = tf.tensor2d([[1, 2, 3], [4, 5, 6]]);
matrix.transpose().print();         // [[1,4], [2,5], [3,6]]
matrix.flatten().print();           // [1, 2, 3, 4, 5, 6]

original.expandDims(0);             // shape: [1, 6]
🎮 Démo Interactive — Opérations
Cliquez pour exécuter la démo...
05

Créer des Modèles

TensorFlow.js propose deux API pour créer des modèles :

1. API Sequential (Plus simple)

Empilez des couches les unes sur les autres de manière linéaire.

JavaScript
const model = tf.sequential();

model.add(tf.layers.dense({
    units: 32,           // 32 neurones
    activation: 'relu',  // Fonction d'activation
    inputShape: [10]     // 10 features en entrée
}));

model.add(tf.layers.dense({
    units: 16,
    activation: 'relu'
}));

model.add(tf.layers.dense({
    units: 1,            // 1 sortie
    activation: 'sigmoid' // Classification binaire
}));

model.summary();

2. API Functional (Plus flexible)

Pour des architectures complexes avec plusieurs entrées/sorties.

JavaScript
const input = tf.input({shape: [10]});

const dense1 = tf.layers.dense({units: 32, activation: 'relu'}).apply(input);
const dense2 = tf.layers.dense({units: 16, activation: 'relu'}).apply(dense1);
const output = tf.layers.dense({units: 1, activation: 'sigmoid'}).apply(dense2);

const model = tf.model({inputs: input, outputs: output});
model.summary();

Types de Couches Courantes

Dense

Fully connected — chaque neurone relié à tous.

Dropout

Désactive aléatoirement des neurones (anti-surapprentissage).

Conv2D

Convolution 2D pour traiter les images.

MaxPooling2D

Réduit la dimensionnalité spatiale.

06

Entraînement d'un Modèle

Étape 1 : Compiler le Modèle

JavaScript
model.compile({
    optimizer: 'adam',           // Algorithme d'optimisation
    loss: 'binaryCrossentropy', // Fonction de perte
    metrics: ['accuracy']        // Métriques à suivre
});

// Autres optimiseurs : 'sgd', 'rmsprop', 'adagrad'
// Autres losses : 'meanSquaredError', 'categoricalCrossentropy'

Étape 2 : Préparer les Données

JavaScript
// Features
const xs = tf.tensor2d([[0,0], [0,1], [1,0], [1,1]]);
// Labels (XOR)
const ys = tf.tensor2d([[0], [1], [1], [0]]);

// Normalisation (important!)
const xsNormalized = xs.div(xs.max());

Étape 3 : Entraîner

JavaScript
async function trainModel() {
    const history = await model.fit(xs, ys, {
        epochs: 100,
        batchSize: 4,
        validationSplit: 0.2,
        callbacks: {
            onEpochEnd: (epoch, logs) => {
                console.log(`Epoch ${epoch}: loss = ${logs.loss.toFixed(4)}`);
            }
        }
    });
    console.log('Entraînement terminé!');
}

trainModel();

Étape 4 : Prédictions

JavaScript
const input = tf.tensor2d([[0, 0]]);
const prediction = model.predict(input);
prediction.print();

const value = await prediction.data();
console.log('Prédiction:', value[0]);

input.dispose();
prediction.dispose();
07

Exemple Complet : Régression Linéaire

Créons un modèle qui apprend la relation y = 2x + 1

JavaScript
async function linearRegressionExample() {
    // 1. Modèle
    const model = tf.sequential();
    model.add(tf.layers.dense({ units: 1, inputShape: [1] }));

    // 2. Compiler
    model.compile({
        optimizer: tf.train.sgd(0.1),
        loss: 'meanSquaredError'
    });

    // 3. Données (y = 2x + 1)
    const xs = tf.tensor2d([1, 2, 3, 4, 5], [5, 1]);
    const ys = tf.tensor2d([3, 5, 7, 9, 11], [5, 1]);

    // 4. Entraîner
    await model.fit(xs, ys, {
        epochs: 500,
        callbacks: {
            onEpochEnd: (epoch, logs) => {
                if (epoch % 100 === 0)
                    console.log(`Epoch ${epoch}: loss = ${logs.loss.toFixed(4)}`);
            }
        }
    });

    // 5. Tester
    for (const x of [6, 7, 10]) {
        const pred = model.predict(tf.tensor2d([x], [1, 1]));
        const val = (await pred.data())[0];
        console.log(`x=${x} → prédit=${val.toFixed(2)}, attendu=${2*x+1}`);
        pred.dispose();
    }

    // 6. Sauvegarder
    await model.save('localstorage://linear-model');
}

linearRegressionExample();
🎮 Démo Interactive — Régression Linéaire
Entraînez le modèle puis prédisez...
08

Classification Multi-Classes

Exemple : Classifier des fleurs Iris (3 classes)

JavaScript
async function irisClassification() {
    const trainingData = tf.tensor2d([
        [5.1, 3.5, 1.4, 0.2],  // Setosa
        [4.9, 3.0, 1.4, 0.2],
        [7.0, 3.2, 4.7, 1.4],  // Versicolor
        [6.4, 3.2, 4.5, 1.5],
        [6.3, 3.3, 6.0, 2.5],  // Virginica
        [5.8, 2.7, 5.1, 1.9]
    ]);

    // Labels one-hot
    const labels = tf.tensor2d([
        [1,0,0], [1,0,0],  // Setosa
        [0,1,0], [0,1,0],  // Versicolor
        [0,0,1], [0,0,1]   // Virginica
    ]);

    const model = tf.sequential();
    model.add(tf.layers.dense({units:10, activation:'relu', inputShape:[4]}));
    model.add(tf.layers.dense({units:10, activation:'relu'}));
    model.add(tf.layers.dense({units:3, activation:'softmax'}));

    model.compile({
        optimizer: 'adam',
        loss: 'categoricalCrossentropy',
        metrics: ['accuracy']
    });

    await model.fit(trainingData, labels, {epochs: 100, shuffle: true});

    const test = tf.tensor2d([[5.0, 3.5, 1.3, 0.3]]);
    const pred = model.predict(test);
    const probs = await pred.data();

    const classes = ['Setosa', 'Versicolor', 'Virginica'];
    const max = probs.indexOf(Math.max(...probs));

    console.log('Prédiction:', classes[max]);
    console.log('Probabilités:', probs);
}

irisClassification();
One-Hot Encoding : Pour 3 classes, utilisez 3 neurones en sortie avec activation softmax. Chaque label → vecteur : [1,0,0], [0,1,0], [0,0,1].
09

Modèles Pré-entraînés

TensorFlow.js propose des modèles pré-entraînés prêts à l'emploi :

MobileNet — Classification d'Images

JavaScript
async function classifyImage() {
    const model = await mobilenet.load();
    const img = document.getElementById('imageToClassify');
    const predictions = await model.classify(img);

    predictions.forEach(pred => {
        console.log(`${pred.className}: ${(pred.probability * 100).toFixed(2)}%`);
    });
}

PoseNet — Détection de Pose

JavaScript
async function detectPose() {
    const net = await posenet.load();
    const video = document.getElementById('video');
    const pose = await net.estimateSinglePose(video);
    console.log('Points clés:', pose.keypoints);
}

Toxicity — Détection de Contenu Toxique

JavaScript
async function checkToxicity() {
    const model = await toxicity.load(0.9);
    const sentences = ['You are awesome!', 'I hate you'];
    const predictions = await model.classify(sentences);

    predictions.forEach(p => {
        p.results.forEach(r => {
            if (r.match) console.log(`⚠️ ${r.label} détecté`);
        });
    });
}
📱

MobileNet

Classification d'images (1000 classes)

👤

PoseNet

Détection de poses humaines

😊

Face-API

Détection et reconnaissance faciale

💬

Toxicity

Détection de contenu toxique

🎨

BodyPix

Segmentation de personnes

🗣️

Speech Commands

Reconnaissance vocale

10

Techniques Avancées

Transfer Learning

Réutilisez un modèle pré-entraîné et adaptez-le à votre cas d'usage.

JavaScript
async function transferLearning() {
    // Charger MobileNet
    const mobilenet = await tf.loadLayersModel(
        'https://storage.googleapis.com/tfjs-models/tfjs/mobilenet_v1_0.25_224/model.json'
    );

    // Tronquer à une couche intermédiaire
    const layer = mobilenet.getLayer('conv_pw_13_relu');
    const truncated = tf.model({
        inputs: mobilenet.inputs,
        outputs: layer.output
    });

    // Ajouter vos couches personnalisées
    const newModel = tf.sequential();
    newModel.add(truncated);
    newModel.add(tf.layers.flatten());
    newModel.add(tf.layers.dense({units: 100, activation: 'relu'}));
    newModel.add(tf.layers.dense({units: 10, activation: 'softmax'}));

    // Geler les poids de MobileNet
    for (const l of truncated.layers) l.trainable = false;

    newModel.compile({
        optimizer: 'adam',
        loss: 'categoricalCrossentropy',
        metrics: ['accuracy']
    });
}

Callbacks Personnalisés

JavaScript
let bestAccuracy = 0;

const callbacks = {
    onEpochEnd: async (epoch, logs) => {
        console.log(`Epoch ${epoch}: loss = ${logs.loss.toFixed(4)}`);
        if (logs.val_accuracy > bestAccuracy) {
            bestAccuracy = logs.val_accuracy;
            await model.save('localstorage://best-model');
        }
    },
    onBatchEnd: async (batch, logs) => {
        updateProgressBar(batch);
    }
};

await model.fit(xs, ys, { epochs: 50, callbacks });

Sauvegarder et Charger des Modèles

JavaScript
// Sauvegarder
await model.save('localstorage://my-model');  // localStorage
await model.save('indexeddb://my-model');      // IndexedDB
await model.save('downloads://my-model');      // Télécharger

// Charger
const loaded = await tf.loadLayersModel('localstorage://my-model');
const remote = await tf.loadLayersModel('https://example.com/model.json');
💾
Formats de Sauvegarde :
localstorage:// — Stockage local (~5-10MB max)
indexeddb:// — IndexedDB (modèles plus gros)
downloads:// — Télécharger les fichiers
http(s):// — Charger depuis un serveur