Générer et interpoler des morceaux de musique avec le modèle MusicVAE
Voyez à travers cet exemple intéressant comment MusicVAE interpole de manière lisse deux comptines anglaises pour enfants, « Twinkle Twinkle Little Star » (Ah ! vous dirai-je Maman) et « Mary Had a Little Lamb ».
Twinkle img
Twinkle Twinklw
Introduction
Dans notre dernier rapport, nous avons vu comment Music Transformer pouvait générer un morceau de piano d’une minute à partir de rien. Cela étant, la contrôlabilité est limitée sur Music Transformer – par exemple, il ne prend pas en charge des applications créatives comme le mix-and-match de deux compositions musicales (communément connu sous le nom d’interpolation).
Dans ce rapport-ci, nous allons nous pencher sur la publication de Roberts et al. sur le logiciel MusicVAE, qui propose de modéliser une distribution latente de segments musicaux, et de permettre ainsi l’application d’une interpolation lisse entre différents segments musicaux. C’est également une des premières utilisations des auto-encodeurs variationnels dans le domaine de la génération de musique symbolique.
Contexte – Les auto-encodeurs variationnels (VAE)
Avant d’aller plus loin sur le modèle MusicVAE, voyons tout d’abord les points clefs des auto-encodeurs variationnels.
Un auto-encodeur est un type d’architecture de réseau neuronal qui peut apprendre une représentation compacte, de faible dimension d’un point de de données de manière non-supervisée. Il est constitué d’un encodeur, qui projette un point de donnée d’entrée X vers une variété (manifold) de dimension (inférieure) z, et d’un décodeur, qui vise à reconstruire le point de donnée par rapport au vecteur de caractéristiques compressées de faible dimension.
L’entraînement d’un auto-encodeur s’effectue via l’optimisation d’une fonction de perte qui oblige le réseau à reconstruire le point de donnée d’entrée. Par exemple :
L=MSE(fdecode(fencode(X)),X)L = MSE(f_{decode}(f_{encode}(X)), X)
Un auto-encodeur variationnel (VAE) possède des caractéristiques très similaires à celles d’un auto-encodeur, mais sa distribution de variable latente, p(z)p(z), doit se conformer à une distribution
Gaussienne standard, par exemple, z ~ N (μ, σ2). Ainsi, lors de la génération de données sur VAE, les points de données sont générés par un processus en deux étapes :
-
D’abord, un code latent est échantillonné à partir de la distribution antérieure p(z)p(z): z∼p(z)z \sim p(z)
-
Ensuite, un point de donnée est généré par le décodage du code latent :: X∼p(X∣z)X \sim p(X|z)
Pour faire appliquer cette propriété, la fonction objective de l’entraînement d’un VAE consiste à maximiser la limite inférieure de la preuve (evidence lower bound, ELBO) de la vraisemblance marginale p(X)p(X) avec l’équation suivante :
L=Eq(z∣X)[logp(X∣z)]−DKL(q(z∣x)∣∣p(z))L = E_{q(z|X)}[\log p(X|z)] - D_{KL}(q(z|x) || p(z))
Si nous comparons cette perte de fonction à la perte de fonction de l’auto-encodeur :
-
Leurs premiers termes respectifs ressemblent à la perte de reconstruction – dans le VAE, la distribution postérieure q(z∣X)q(z|X) et la vraisemblance p(X∣z)p(X|z) correspondent respectivement à l’encodeur et au décodeur.
-
Le deuxième terme additionnel dans la perte du VAE est un terme de divergence KL (Kullback-Leibler), qui est communément utilisé pour mesurer la « différence » entre deux distributions de probabilités. Ici, il confirme la distribution postérieure q(z∣X)q(z|X) pour se rapprocher de la distribution antérieure p(z)p(z), qui est habituellement une distribution Gaussienne standard N(μ,σ2).N(\mu, \sigma^2)..
Pour faire simple, nous pouvons penser aux VAE comme à une version « régularisée » d’auto-encodeurs, puisque les auto-encodeurs n’appliquent aucune contrainte sur la distribution de la variable latente encodée. De ce fait, le processus d’encodage-décodage est également légèrement différent :
-
Pendant l’encodage, au lieu d’encoder un seul vecteur latent, nous encodons deux vecteurs latents qui représentent l’écart-moyen μ\mu et
-
Pendant le décodage, nous échantillonnons tout d’abord un vecteur latent de la distribution (cela s’effectue notamment avec une astuce de reparamétrisation ϵ∼N(0,I),z=μ+σ⋅ϵ\epsilon \sim N(0, I), z = \mu + \sigma \cdot \epsilon). Puis, nous introduisons le vecteur latent dans le décodeur pour reconstruire l’entrée.
Pour une version plus détaillée de la dérivation de la fonction objective (ELBO) du VAE et son contexte par rapport à l’inférence variationnelle, nous vous invitons à vous référer à ce document. Nous fournirons une explication plus détaillée sur les VAE dans les rapports à venir.
Pourquoi utiliser les VAE plutôt que les autoencoders pour la génération ?
Pour les applications de génération, les VAE sont communément préférés aux auto-encodeurs pour les raisons suivantes :
-
Premièrement, les VAE nous fournissent une distribution antérieure pour échantillonner la variable latente. Ils sont beaucoup plus pratiques pour générer de nouveaux points de données (ex : de nouvelles images faciales, de nouveaux segments musicaux) comparés aux auto-encodeurs, qui n’incluent aucun moyen intuitif pour échantillonner de nouveaux codes latents.
-
Deuxièmement, grâce à l’application de la distribution Gaussienne dans l’espace de variable latente, on peut espérer obtenir une « surface plus lisse » sur l’espace, comparé à l’espace de variable latente d’un auto-encodeur, qui produit habituellement plus de « trous latents ». Ceci est particulièrement important pour l’application du mix-and-match, qui requiert une interpolation de l’espace latent, c��est-à-dire de « passer par un chemin » dans l’espace latent, tandis que la région de « trous latents » génèrera des entrées de données non-réalistes (ex : des images facialesdéformées, des segments musicaux incohérents).
MusicVAE
Voyons maintenant le modèle MusicVAE plus en détail. Pour l’encodeur et le décodeur, MusicVAE choisit d’utiliser des réseaux neuronaux récurrents (plus précisément des LSTM), en empruntant le concept de la publication Génération de texte en utilisant des VAE récurrents.
-
L’encodeur q(z∣X)q(z|X) traite une séquence d’entrée et produit une séquence d’états cachés. L’écart-moyen et l’écart-type, μ et σ, sont dérivés de l’utilisation du dernier état caché hT par deux réseaux à propagation avant séparés, par exemple : μ=f1(hT),σ=f2(hT)\mu = f_1(h_T), \sigma = f_2(h_T).
-
Le décodeur p(X∣z)p(X|z) utilise en premier lieu le vecteur latent échantillonné zz pour configurer l’état initial du réseau neuronal récurrent (RNN) du décodeur. Ensuite, il génère de manière autorégressive la séquence de sortie de l’état initial. Pendant l’entraînement, la séquence de sortie est entraînée pour reconstruire la séquence d’entrée.
Dans cette étude, MusicVAE est utilisé pour générer des mélodies et des séquences de batterie monophoniques. Dans ce rapport, nous allons nous concentrer sur la génération de mélodies monophoniques. La séquence de mélodies est représentée par une matrice de séquence (T, 130), dans laquelle l’espace de sortie en 130 dimensions (vecteurs one-hot) est constitué de 128 tokens « note-on » pour les 128 hauteurs de notes de MIDI, d’un token pour la fonction « note-off » (relâcher une note jouée) et un token pour la fonction « rest » (silence). Ici, MusicVAE expérimente sur deux longueurs différentes de points de données de mélodie : 2 mesures (2-bar, T = 32) et 16 mesures (16-bar, T = 256), dont nous étudierons les différences en termes de performance dans une section prochaine.
Les lacunes des RNN Vanilla pour MusicVAE
Les auteurs ont relevé deux limites principales sur l’utilisation des RNN Vanilla pour MusicVAE :
-
Puisque le décodeur est autorégressif par nature (il produit la sortie de l’étape en cours en se basant sur les étapes précédentes), c’est un décodeur suffisamment puissant pour pouvoir ne pas prendre en compte le code latent. Si le code latent est ignoré, le terme de divergence KL de l’ELBO pourrait être facilement paramétré sur zéro. Ce qui n’est pas souhaitable, puisque le modèle ne pourra pas apprendre efficacement la distribution de la variable latente.
-
Puisque le modèle compresse toute la séquence en un seul vecteur latent, il présente un goulot d’étranglement très étroit. Comme le montre le tableau de résultats ci-dessous, bien que le VAE récurrent de Vanilla soit capable de reconstruire des mélodies à 2 mesures avec une précision acceptable, les auteurs ont remarqué que cette approche échouait sur les séquences plus longues(ex : 16 mesures).
La solution
MusicVAE présente un décodeur hiérarchique – puisque nous générons des sorties à 16 mesures, les auteurs suggèrent de générer en premier lieu un vecteur latent intermédiaire (nommé « conductor », chef d’orchestre, dans l’étude) pour chaque mesure – par exemple, [z1′,...,z16′]=RNN(z)[z^\prime_1, ..., z^\prime_{16}] = RNN(z). Puis, pour chaque mesure, nous utilisons une autre layer de RNN pour générer les véritables outputs en se basant sur le vecteur latent intermédiaire.
Le raisonnement est que plus la séquence de sortie est longue, plus l’influence de l’état latent se dissipe (ce qui s’apparente à la problématique de disparition des gradients dans les longues séquences). Par conséquent, le décodeur hiérarchique génère en premier lieu une séquence plus courte de codes latents intermédiaires, ce qui, avec un peu de chance, va mitiger le problème de disparition. Ensuite, pour chaque mesure, la sortie est générée en se basant uniquement sur le vecteur latent intermédiaire pour cette mesure, qui est tirée du vecteur latent. Cela pourrait obliger le processus de génération à ne pas ignorer l’état latent, et par conséquent, induire un meilleur apprentissage de la distribution latente.
Interpolation
Maintenant que nous sommes capables d’enseigner une distribution latente cohérente de mélodies, l’interpolation entre deux mélodies distinctes A et B s’effectue à travers les étapes suivantes :
- Obtenir les codes latents à la fois pour A et B, i.e. zA,zBz_A, z_B.
- « Glisser » entre les points de zAz_A et de zBz_B dans l’espace latent et obtenir N codes latents sur le parcours d’interpolation,, i.e.zα=zA+α(zB−zA).z_\alpha = z_A + \alpha(z_B - z_A).
Les auteurs ont démontré que l’interpolation sur l’espace latent résulte en une transformation plus lisse et plus cohérente depuis la mélodie source vers la mélodie cible, comparativement à une interpolation sur l’espace de donnée. Cela prouve donc que la distribution latente apprise est capable de capturer des informations compactes et cohérentes sur la structure des segments musicaux.
Génération
Dans le notebook Colab annexé à cette publication, nous générons une mélodie à 2 mesures et à 16 mesures en utilisant à la fois le VAE récurrent de Vanilla et MusicVAE. Les fichiers audios générés ainsi que les rouleaux de piano correspondants sont enregistrés, comme indiqué ci-dessous, en utilisant la bibliothèque de Weights and Biases wandb.
Reproduire les résultats avec ce Colab notebook
Générer & Interpoler pour 2 Mesures
Générer et interpoler 16 Mesures
Résumé
Le modèle MusicVAE fournit une solution viable pour modéliser la distribution de segments musicauxdans une variété compacte de faible dimension, permettant ainsi des applications créatives de génération de mélodies à partir de rien, ainsi que le mix-and-match de mélodies de styles très différents. Un tel modèle est capable d’augmenter le niveau de contrôlabilité des systèmes de génération de musique, permettant aux utilisateurs d’avoir un contrôle plus précis de la génération de musique dans le style souhaité.
Cependant, bien que MusicVAE soit capable de générer une composition musicale de 16 mesures, il est encore loin de pouvoir générer des séquences polyphoniques d’une minute (qui jouent plusieurs notes à la fois, au lieu d’une seule note) comme Music Transformer. Pouvons-nous combiner les points forts de Music Transformer (génération de longues séquences cohérentes) et de MusicVAE (haut niveau de contrôlabilité) ? Nous étudierons un modèle différent relatif à ce sujet dans notre prochain rapport.
Si vous souhaitez en apprendre davantage, vous pouvez vous référer au papier original, et à l’article de blog de MusicVAE.
N’hésitez pas à nous faire part des compositions musicales et des interpolations que vous avez réalisées ! Tweetez-nous via @weights_biases et @gudgud96
