Aller au contenu
Apprendre.
  • M1 · toutes les matières15 matières : Préparation de données, API & sécurité, CI/CD, Docker, Merise, Dataviz, KNIME, ML appliqué : projet LoL, SQL & UML, SQL avancé, Machine Learning, Git, IA frugale & responsable, Qualité des données, MathématiquesAnnée
  • M2 · toutes les matières4 matières : Deep Learning, AI Act, Comex & Fundraising, Gouvernance & DataMeshAnnée
  • Deep LearningM2 · 4 modules · Réseaux de neurones, CNN, texte, modèles génératifs.Matière
  • Préparation de donnéesM1 · 3 modules · Nettoyer, transformer et fusionner des données avec Python.Matière
  • API & sécuritéM1 · 2 modules · Consommer, concevoir et sécuriser des API.Matière
  • CI/CDM1 · 1 module · Intégration et livraison continues.Matière
  • DockerM1 · 3 modules · Conteneurs, images, volumes, réseaux, Compose.Matière
  • MeriseM1 · 2 modules · Modéliser une base : MCD, MLD, MPD.Matière
  • DatavizM1 · 2 modules · Visualiser pour comprendre et décider.Matière
  • KNIMEM1 · 1 module · Explorer et nettoyer des données en workflow.Matière
  • ML appliqué : projet LoLM1 · 2 modules · Du besoin métier au POC de vision par ordinateur.Matière
  • SQL & UMLM1 · 3 modules · Modèles UML et requêtes SQL.Matière
  • SQL avancéM1 · 3 modules · Jointures, fenêtres, CTE, optimisation.Matière
  • Machine LearningM1 · 3 modules · Régression, classification, segmentation, projet.Matière

↑↓ naviguer↵ ouvre le résultat en surbrillanceesc fermer

Partie 2 · Créer

Un espace sans trous

L'autoencodeur donne à chaque image un point. Le VAE (Kingma et Welling, 2013) lui donne une petite zone : l'encodeur rend un centre μ et une largeur σ, deux vecteurs de 2 composantes, et on tire le code z au hasard dans cette zone avant de le décoder.

Conséquence : le décodeur doit reconstruire l'image à partir de n'importe quel code tiré près de μ. Il apprend donc que des codes voisins donnent des images voisines, et les trous se comblent. La largeur se lit composante par composante : environ deux fois sur trois, la composante tirée est à moins de σ du centre.

Le tirage : z = μ + σ × ε, avec ε tiré dans la loi normale centrée réduite (moyenne 0, écart-type 1). z, μ, σ, ε ont chacun 2 composantes, le calcul se fait composante par composante. Exemple de la slide : μ = 0,8, σ = 0,1, ε = −1, donc z = 0,8 + 0,1 × (−1) = 0,7, décodé en [0,7 ; 0,7] ; sa MSE avec l'image [0,9 ; 0,7] vaut 0,02.

Pourquoi écrire le tirage ainsi ? Un tirage « z au hasard autour de μ » n'a pas de dérivée. En mettant le hasard à part, dans ε, z devient une multiplication et une addition, que l'on sait dériver : si μ augmente de 1, z augmente de 1 ; si σ augmente de 1, z change de ε. La règle de la chaîne de J1 passe à travers le tirage, jusqu'aux poids de l'encodeur. Cette écriture s'appelle la reparamétrisation.

Règle σ à 0,05 : z colle à μ quel que soit ε. Règle σ grand : z peut tomber loin de μ.

À toi de coder

Écrire la reparamétrisation

En PyTorch la ligne du cours est z = mu + sigma * torch.randn_like(sigma). En Python pur, ε est fourni (sinon les checks changeraient à chaque exécution) et le calcul se fait composante par composante avec zip. Garde bien σ qui multiplie ε et μ qui s'ajoute : inverser les rôles déplacerait le centre au lieu d'élargir la zone.

Puis calcule la perte de reconstruction de l'exemple : z est recopié dans les deux pixels, comparé à l'image [0,9 ; 0,7].

Ctrl/⌘+Entrée

La KL ramène chaque zone vers une zone de référence. Sans contrainte, l'encodeur pourrait réduire toutes les zones à des points (σ → 0) et retomber dans l'autoencodeur, avec ses trous. On ajoute donc à la perte un terme, la KL (divergence de Kullback-Leibler), qui mesure l'écart entre la zone d'une image et la zone de référence (centre 0, largeur 1 : la loi normale centrée réduite) :

KL = ½ (μ² + σ² − 1 − ln σ²)

Elle vaut 0 quand les deux zones sont identiques. La perte du VAE = erreur de reconstruction + KL. Pour une composante : (μ, σ) = (0 ; 1) donne 0 ; (0,8 ; 0,5) donne 0,64 ; (0,8 ; 0,1) donne 2,13 (zone presque réduite à un point). Avec 2 composantes, on additionne les KL.

Les trois boutons sont les trois lignes du tableau du cours. Essaie aussi un σ plus grand que 1 : la KL remonte, elle pénalise les deux sens.

À toi de coder

Calculer la KL

Traduis la formule en Python pur. Deux pièges classiques : ln σ² est le logarithme de s**2 (pas de s : la valeur serait fausse), et avec un code de 2 composantes on somme les KL composante par composante. Tu dois retrouver les valeurs du tableau : 0 ; 0,64 ; 2,13.

Ctrl/⌘+Entrée

Générer, c'est tirer un code et le décoder. Deux étapes : 1) tirer un code dans la zone de référence (un vecteur de 2 composantes) ; 2) le décoder, le décodeur rend une image de 784 pixels. L'encodeur ne sert plus. Comme la KL a ramené toutes les zones vers la zone de référence, presque tout code tiré dedans tombe près du code d'images d'entraînement : plus de trous. Le notebook tire ainsi 64 coupes (VAE de 202 516 poids).

Limite : les images générées sont floues. Quand plusieurs images ont des codes voisins, la perte récompense le décodeur qui rend une image entre les deux.

Interpoler : on prend les codes z₁ et z₂ de deux vraies coupes et on décode les points du segment qui les relie :

z(t) = (1 − t) × z₁ + t × z₂, t de 0 à 1.

Avec z₁ = [−1 ; 0,5] et z₂ = [1 ; −0,5] : t = 0,25 donne [−0,50 ; 0,25] et t = 0,5 donne [0 ; 0], le milieu du segment. C'est ainsi qu'a été fabriquée la bande de l'accroche (une coupe qui se change en une autre).

Déplace t : le point glisse sur le segment, l'image se transforme progressivement. Le décodeur de la démo est fictif.

À toi de coder

Interpoler entre deux codes

Écris interpoler(z1, z2, t), qui renvoie le code à la fraction t du chemin, composante par composante. Vérifie les cas limites : t = 0 doit redonner z₁ (aucun mélange) et t = 1 doit redonner z₂. Puis fabrique les sept codes du notebook, de t = 0 à t = 1 en six pas égaux : t vaut i / 6 pour i de 0 à 6.

Ctrl/⌘+Entrée