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.
À toi de coder
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.
À toi de coder
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).
À toi de coder