• Aucun résultat trouvé

Pour l’entraînement, le dataset complet fait environ 200Go pour 6 112 personnes et 150 480 vidéos.

Nous avons extrait des images indépendantes et calculé leurs landmarks. Une fois cela fait, nous pouvons générer des données à partir du générateur puis entraîner le modèle avec cette image générée et les vrais landmarks.

La procédure est comme suit :

1: forEpochs do

2: Générer les landmarks depuis le bruit blanc 3: Prendre les landmarks réels du dataset

4: score_faux = Discriminer les données générées

5: Entraîner le générateur sur le score de l’image générée (score_faux) 6: score_vrai = Discriminer les données réelles

7: Entraîner le discriminateur avec les scores des deux landmarks (score_faux et score_vrai)

c.f équation 1.1

8: end for

Pour améliorer la vitesse d’entraînement, le chargement des données a été parallélisé. Nous avons aussi utilisé une extension pour pytorch, Apex de Nvidia qui calcule au mieux la précision

nécessaire en virgule flottante nécessaire aux variables afin d’accélérer l’entraînement3 4.

Le reste des détails techniques sont donnés dans l’annexe (c.f chapitre A)

Les GANs présentés ici se sont inspirés de l’architecture classique de la littérature qui a ensuite évolué pour donner le résultat final de la section 1.9. Le réseau a été entraîné sur une Nvidia GTX 1050 (4Go VRam) pendant environ 4h. Nous avons utilisé la SELU (Scaled Exponential Linear Unit) comme fonction d’activation, car elle permet contrairement aux autres fonctions (comme la ReLU [? ]), une normalisation interne du modèle ainsi que l’impossibilité d’avoir une explosion ou une disparition du gradient ce qui amène une meilleure stabilité du modèle. En citant le résumé de l’article sur la SELU [62] :

Using the Banach fixed-point theorem, we prove that activations close to zero mean and unit variance that are propagated through many network layers will converge towards zero mean and unit variance — even under the presence of noise and perturbations.

This convergence property of SNNs allows to (1) train deep networks with many layers, (2) employ strong regularization schemes, and (3) to make learning highly robust. Furthermore, for activations not close to unit variance, we prove an upper and lower bound on the variance, thus, vanishing and exploding gradients are impossible.

1.8

Génération de vidéo

Une fois une seule image générée, nous voulons pouvoir trouver l’image suivante, proche, afin de produire des vidéos de visages d’étudiant. Cela constituerait l’apogée du but que nous nous étions fixé. Nous voulons aussi le faire de façon aléatoire afin de remplir nos objectifs.

Pour obtenir des exemples, nous avons testé avec une marche aléatoire (loi normale de moyenne nulle et de variance 0.5) dans l’espace d’entrée (le bruit). Puisque nous voulions surtout une preuve de concept afin de générer des données, nous n’avons pas utilisé d’architecture conditionnelle. Celle-ci nous aurait permis de choisir quel vecteur ajouter au bruit pour pouvoir se déplacer dans la direction de la caractéristique qui nous intéresse. Ici, la marche aléatoire permet de générer des visages avec des caractéristiques non déterministes de façon continue. C’est donc cette méthode que nous avons choisie afin de rendre notre création de visages plus diverse.

En parcourant l’espace appris, nous pouvons donc générer des visages de façon continue et construire notre banque d’images proches synthétiques (vidéos). Une fois cela réalisé, nous

3. https://nvidia.github.io/apex/index.html

Figure 1.7 – Exemple d’exploration de l’espace du GAN. En ajoutant du bruit (flèche bleue) nous pouvons modifier les images et générer une séquence continue .

aurons donc atteint le but que nous souhaitions, produire des vidéos de visages pour se créer un jeu de données.

Pour ce faire, nous parcourons l’entrée du GAN (le bruit) grâce à une marche aléatoire. Comme on peut le voir figure 1.7, en partant d’un vecteur quelconque puis en ajoutant un peu de bruit aléatoire supplémentaire (l’étape de marche), nous pouvons explorer les différentes sorties de notre modèle. Ici nous pouvons voir que les landmarks sont modifiés d’une itération à l’autre (de gauche à droite sur la figure). En effet, deux bruits en entrée similaires produiront une sortie similaire. En ajoutant du bruit avec une faible variance, les différences sont minimes et on peut donc créer une suite d’images continue.

Amélioration

Nous n’avons pas de dataset d’étudiant en train de faire leurs examens. Pour palier à cela, une piste serait d’appliquer le procédé de transfert de connaissance. Cette méthode consiste à entraîner un modèle sur des données plus nombreuses connexes au but que nous voulons atteindre. De ce fait, le réseau va apprendre les notions générales utiles pour la tâche. Ensuite, nous le spécialisons grâce aux données finales moins nombreuses, mais plus spécifiques. Dans notre cas, nous entraînons notre réseau sur l’espace de voxCeleb2. Cela nous donne

déjà un réseau compétent capable de modéliser un visage (cf. chapitre suivant 2 figure2.8). On reprend ensuite de cette base de façon à le spécialiser sur les images (moins nombreuses) d’étudiants en période d’examen. De ce fait, il va se spécialiser et se réduire à un espace plus étroit.

Ensuite, pour aller plus loin, nous pourrions ajouter des connaissances à priori afin que notre réseau nous crée le visage avec ces informations supplémentaires (p.ex direction du regard [13,14] / émotion [12]).

Aussi, ce même procédé serait valable avec le haut du corps complet de l’étudiant[63]. Avec les mêmes méthodes, il serait possible de générer des mouvements de bras et torse en plus. Il est aussi possible d’inclure la détection d’iris dans les landmarks [64]. Pour les landmarks de corps il faut 14 landmarks (pieds, genoux, hanches, épaules, coudes, poignets, cou, tête) et ceux-ci n’incluent pas le visage. Pour les iris, dépendamment des modèles, on retrouve de 1 a 28 landmarks qui ne représentent que les yeux (et sourcils).

1.9

GAN de visage

Une fois la base posée, et les procédés découverts en générant des landmarks de visages, nous avons voulu essayer des méthodes différentes afin d’explorer des idées inexploitées jusqu’à aujourd’hui.

En effet, après avoir généré des landmarks, ce qui réalise déjà les objectifs de ce chapitre, qui étaient de créer des données qui nous permettraient de simuler des étudiants, nous souhaitons poursuivre et créer un vrai visage texturé, pour pouvoir analyser des attributs plus fins. Nous n’avons pas investigué plus pour ajouter du réalisme aux landmarks afin de renforcer la génération de vidéo dans les modèles précédents. Mais nous nous sommes penchés sur la génération d’un visage complet et réaliste.

Premièrement, nous voulons repartir de ces landmarks pour générer un visage texturé qui pourrait nous permettre d’animer un visage réaliste. Dans un deuxième temps, nous ne voulons pas avoir à donner la position du visage à la main, car générer des scénarios serait trop long et reviendrait au même qu’embaucher des acteurs pour générer des données. Nous proposons donc une méthode novatrice, afin de modifier automatiquement la position du visage d’un étudiant afin de générer des scénarios variés.

L’idée est d’utiliser un agent d’apprentissage par renforcement pour qu’il apprenne à modifier de façon cohérente la position du visage au lieu d’utiliser une marche dans le bruit d’entrée. Dans la partie précédente, nous avons expliqué qu’il était possible de générer des landmarks d’une personne puis de travailler dessus afin d’obtenir des séquences et de créer un dataset. Ici, nous voulons effectuer la même chose en remplaçant l’entrée du bruit blanc par un agent plus intelligent et en créant des visages réalistes. Le cœur du travail revient donc à créer un visage

humain réaliste et de le faire bouger de façon automatique.

La même approche pourrait être faite avec un GAN conditionnel en lui donnant des attributs. Cependant, l’injection d’antécédents et le traitement de la représentation latente des GANS peuvent être compliqués et délicats. C’est pourquoi nous avons choisi une approche récente [44] qui utilise des landmarks comme entrée. Nous aurions aussi pu nous baser sur des méthodes moins récentes comme, [65] mais celle-ci oblige à avoir une image en entrée, et il est bien plus simple d’interagir avec des landmarks plutôt qu’une image complète. Cela facilite la représentation et «cache» l’espace latent. L’accent est mis sur les landmarks, plus compréhensibles pour l’homme. En effet, dans notre cas, nous voulons seulement changer la position spatiale du visage, en conservant ses caractéristiques originales. De plus, les landmarks sont de bons paramètres avec lesquels un agent d’apprentissage peut interagir, c’est le moyen le plus direct et le plus simple de contrôler l’image générée.

Grâce à cette méthode, nous pouvons transformer un visage (orientation, expression...) en nous limitant aux caractéristiques originales. En revanche, elle ne permet pas de changer de couleur des cheveux ou enlever des lunettes comme dans [34]. Les avantages de la méthode de [44] sont la qualité de l’image produite (état de l’art) par rapport à d’autres méthodes, qu’elle peut être affinée avec seulement quelques images pour une personne inconnue et son temps d’inférence rapide.

Le seul inconvénient des landmarks de visage en général c’est qu’ils ne tiennent pas compte du regard. Pour détecter la pupille et la direction du regard, il faudrait ajouter de l’information grâce à d’autres méthodes [66].

Comme l’implantation du modèle de générateur de visage [44] n’était pas accessible au public, les auteurs n’ayant rien divulgué, nous avons recréé l’architecture à partir de zéro. Ensuite, nous avons ajouté un agent d’apprentissage par renforcement qui est entraîné pour modifier les landmarks et générer de nouveaux visages réalistes grâce à l’environnement créé.

L’ensemble de données utilisé pour toutes les méthodes est toujours VoxCeleb2 [61].

1.9.1 Générateur d’images synthétiques

Nous avons modifié l’architecture de [44], grâce à leur travail, nous avons développé quelque chose de similaire qui nous permet de manipuler les visages.

L’idée principale est de modifier l’orientation et l’expression des visages avec un GAN. L’archi- tecture se base donc sur celle d’un GAN classique comme explicité à la figure1.4. À la place du bruit en entrée, nous donnons au générateur (G) de nouveaux landmarks (x) qui correspondent à la forme du visage que nous voulons. Le générateur prend alors ces points clés et génère une image synthétique (Ib) de la personne.

Figure 1.8 – Architecture du générateur d’image

Puisque le générateur ne reçoit que des informations spatiales (les landmarks), nous lui donnons les caractéristiques de la personne à produire grâce à des paramètres (P ) calculés via un embedder (E) sur les autres images de cette même personne (C).

De plus, par rapport à l’architecture originale, nous concaténons certaines couches (L rose rouge et vert figure 1.8) de l’embedder avec celles d’upsampling du générateur afin de lui procurer plus d’informations.

Enfin, suivant le principe des GANs, un discriminateur (D) donne un score de réalisme de l’image générée. Son but est d’apprendre à détecter les images réelles par rapport aux images générées.

Le but du générateur (et de l’embedder) est de rendre une image si réaliste que le discriminateur pensera que c’est une image réelle. Ils seront en compétition et apprendront les uns des autres. À la fin, le discriminateur sera si bon pour déterminer les images synthétiques par rapport aux images réelles que le générateur aura dû apprendre à réaliser des visages très réalistes respectant la position donnée en entrée.

1.9.2 Embedder

Le but de l’embedder est de donner une bonne représentation de la personne pour aider le générateur à reconstruire une image la plus réaliste possible. L’idée est de créer un vecteur caractérisant le visage par exemple les informations sur la couleur des cheveux, la forme du visage, la couleur de peau, position des lèvres.

Le dataset est organisé par contexte : chaque personne possède plusieurs contextes dont chacun contient plusieurs vidéos (même arrière-plans, vêtements, etc.).

Figure 1.9 – Exemple d’un contexte

Nous avons pris K = 8. Les landmarks sont associés à l’image de gauche. De la couleur a été mise sur les groupes de landmarks pour aider le générateur.

Pour les données d’apprentissage, nous prenons au hasard K images (K=8 dans notre cas) parmi un contexte d’une personne et calculons leurs landmarks (cf figure1.9). Toutes les images de ce contexte sont différentes de l’image que nous donnerons afin d’indiquer la position voulue au réseau. K devrait être le plus élevé possible, mais nous l’avons fixé pour respecter la capacité mémoire du GPU. Un K plus faible obligerait à faire plus d’itérations. Ceci formera notre contexte C constitué de Ciimages de taille 6 × K × 224 × 224, soit 3 canaux RGB pour l’image

et 3 pour l’image des landmarks, et chaque image est de taille 224 par 224. Les landmarks sont d’ailleurs colorés par groupes afin d’aider au mieux notre réseau à obtenir une représentation correcte. Ensuite, une par une, nous passons chacune de ces K (8 dans notre cas) images de 6 canaux (image et landmarks) (Ci) à l’embedder. L’embedding final de taille N est la moyenne

de toutes les sorties.

Φ = 1 K K X i=0 E(Ci) (1.2)

Cette idée peut être trouvée dans [39]. Le but de ce procédé est de donner sous forme vectorielle (vecteur de taille N) une représentation de l’objet à générer. Plus on donne d’images pour créer ce vecteur, plus la représentation sera précise.

Le générateur peut ensuite utiliser ces paramètres grâce à une normalisation spéciale. Le principe de l’adaptive instance normalisation (adaIN) [67] est de donner la moyenne et la variance du style souhaité. De ce fait, le réseau apprend à normaliser une image dans le style voulu. Dans notre cas, cela correspond aux caractéristiques spécifiques de la personne que nous souhaitons générer.

style voulu (µ étant la moyenne et σ la variance) : xn= σ(y)  x − µ(x) σ(x)  + µ(y) (1.3)

Chaque couche de normalisation doit donc recevoir une moyenne et une variance. Or tous ces paramètres (moyenne et variance pour chaque couche) sont plus grands que notre représentation de taille N. Il faut donc utiliser une matrice de projection pour agrandir ce vecteur à la taille désirée. On étend donc la représentation aux dimensions du générateur grâce à une couche entièrement connectée.

P = Fc(Φ) (1.4)

Avec ces coefficients P nous pouvons alors pondérer les couches dans le générateur avec la méthode AdaIn [67,68].

Cela donne au générateur (qui n’a que des repères et aucune information sur la couleur/texture de la personne) les informations nécessaires pour recréer le visage d’une personne spécifique.

1.9.3 Générateur

Le générateur est constitué d’une partie compressant les données, appelée downsampling (sous- échantillonnage). Cette partie permet de transformer les données dans un espace plus adéquat à l’apprentissage. S’en suit une partie permettant d’effectuer les modifications nécessaires pour résoudre le problème. Enfin, une partie d’upsampling (sur échantillonnage) permettant de repasser dans l’espace d’entrée des données afin de pouvoir comparer l’entrée et la sortie. Pour l’entrée nous prenons une image qui sera utilisée comme référence. Celle-ci est obtenue à partir de la même vidéo utilisée pour le contexte C de l’embedder (sous-sous-section 1.9.2) Nous calculons ses repères (x) sans les dessiner sur l’image. Ainsi nous avons deux images, le visage de référence (I) et les landmarks de référence (x). Nous donnons les landmarks de référence (x) ainsi que les paramètres de personne P et les couches d’embedder L en entrée du générateur. P et L ont été calculés précédemment. Formellement. :

b

I = G(x, P, L) (1.5)

Plus précisément, les paramètres propres à la personne (P) calculés à l’équation 1.4 sont appliqués sur chaque couche constante et chaque couche d’upsampling.

Les couches de downsampling (L), extraites de l’embedder pour ajouter des informations dans le générateur sont concaténées aux couches d’upsampling équivalentes dans le générateur (cf. couches colorées figure 1.8).

Le générateur reçoit donc toutes ces informations et tente grâce à de nombreux blocs de convolutions (détaillés section 2.2.4, figure A.1) et des normalisations de recréer une image réaliste de la personne dans la position spécifiée par x.

1.9.4 Discriminateur

Pour le discriminateur, nous utilisons le modèle des GANs conditionnels [32] (code : [69]). Un GAN classique prendrait l’image réelle et l’image générée et produirait un score de réalisme pour chacune (comme expliqué à la sous-section 1.3).

Ici, nous voulons que le discriminateur nous donne une note sachant que ces images corres- pondent à une personne précise. Ainsi, le discriminateur peut utiliser cette information pour renforcer ses connaissances à priori sur les images et être plus précis dans le score donné à chacune.

Le discriminateur se compose de deux parties, un réseau à convolution et un produit scalaire. La partie convolution a la même architecture que l’embedder et fournit un vecteur correspondant au réalisme général de l’image sans connaissances préalables de la personne.

Pour aider le discriminateur à avoir un choix plus "personnel" sur le visage généré, nous allons stocker des vecteurs de caractéristiques de chaque personne (Ψ figure 1.8). Ces vecteurs de caractéristiques seront mis à jour pendant l’entraînement et correspondent à une représentation du visage générique d’une personne donnée.

Pour calculer le score, nous faisons un produit scalaire entre le vecteur de caractéristiques générales et le vecteur propre à la personne.

score_I = D(bb I, x, Ψ) = Dconv(x) · Ψ

De ce fait, le score n’est plus calculé seulement avec une représentation générale, mais possède une information plus spécifique et discriminatoire (Ψ). De façon vulgarisée, cela revient à dire

« Ce visage est-il realiste

| {z }

Dconv(x)

sachant que c’est celui de Paul

| {z }

Ψ

»

1.9.5 Pertes

Pour optimiser le modèle, il faut lui donner une rétroaction en fonction de son erreur. Nous utilisons quatre rétroactions (formellement pertes) différentes :

Perte perceptuelle : Lperc

Contrairement à une méthode classique qui consiste à calculer la différence entre chaque pixel des deux images, nous avons appliqué une perte perceptuelle [38] entre l’image de synthèse et l’image de référence. Le principe est de comparer les couches internes d’un réseau ayant des connaissances sur le type de données générées. Dans notre cas, nous avons pris vgg_19 longtemps état de l’art sur des problèmes de vision et couramment utilisé pour cette tâche.

Ce réseau nous permet d’obtenir des notions plus avancées sur les caractéristiques de l’image (courbes, angles, couleur etc..)

Puisque nous générons des visages, nous voulons aussi utiliser un réseau ayant servi à détecter des visages (dans notre cas vgg_face). En effet, ce dernier possédera des couches spécialisées dans ce domaine qui l’ont aidé à réaliser son but premier (p.ex identification). Nous allons donc nous servir de sa représentation interne pour nous donner une information plus profonde sur nos données.

Dans notre cas, nous passons l’image générée et l’image de référence dans vgg_19 [70] pour les traits génériques et vgg_face [71] pour les traits de visages. Ces deux réseaux possèdent déjà des couches permettant de détecter des éléments précis, p.ex, des contours de visage, des couleurs, et d’autres caractéristiques utiles. En passant nos deux images nous pourrons donc comparer des concepts plus profonds, exemple : est-ce que les deux images ont les mêmes courbes, les mêmes lignes de visages, d’yeux, etc.

Mathématiquement, avec V le réseau expert, Vi la i-ème couche de ce réseau et L l’ensemble

des couches considérées :

vgg_loss = 1 |L|

X

i∈L

Vi(x) (1.6)

avec L={1,6,11,20,29,29} pour vgg_19 et L={1,6,11,18,25} pour vgg_face. Nous n’avons pas pris toutes les couches, seulement les premières permettant de détecter des caractéristiques générales. Les autres, plus profondes contribuent plus au but spécifique du réseau expert et nous sont donc moins utiles.

Perte des caractéristiques du discriminateur : Lf d

La même idée que la perte perceptuelle a été appliquée sur les couches de la partie convolutive du discriminateur (sur toutes les couches avant les fonctions d’activation (Selu)). Cette idée se retrouve dans [72]. Elle permet de même de comparer les deux images par rapport à la représentation que le discriminateur en a et apporte donc une information plus profonde qu’uniquement le score de réalisme. Elle a été calculée sur toutes les couches du discriminateur comme à l’équation 1.6avec L étant toutes les couches du discriminateur .

Perte des vecteurs de caractéristiques : Lemb

Nous voulons que nos vecteurs de caractéristiques externes (calculées par l’embeddeur pour chaque contexte différent Φ selon l’équation1.2) et ceux généraux de chaque personne stockée Ψ (équation1.6) soient identiques. Nous avons donc appliqué une perte L1 (distance Manhattan) entre eux.

Perte du score du générateur : Lf b

Nous voulons que le discriminateur donne un retour au générateur. Il faut donc que le générateur maximise son score obtenu sur les images synthétiques.

Lf b= −D(bI, x, Ψ) (1.7)

Perte du discriminateur : Ld

La perte du discriminateur pour donner un score sur la qualité de l’image est donnée comme suit :

max(0, 1 − D(I)) + max(0, 1 + D(bI)) (1.8) À la différence de l’équation1.1dans les GANs plus simplistes, la hinge loss (optimisation grâce

Documents relatifs