Tu es quoi Comment nous avons distingué la parodie de l'humain - et même gagné

Récemment, le Défi ID R&D Voice Antispoofing a eu lieu , dont la tâche principale était de créer un algorithme permettant de distinguer une voix humaine d'un enregistrement synthétisé (parodie). Je suis ML Researcher en Dasha AI et je travaille beaucoup sur la reconnaissance vocale, j'ai donc décidé de participer. Avec l'équipe, nous avons pris la première place. Sous la coupe, je parlerai de nouvelles approches cool du traitement du son, ainsi que des difficultés et des bizarreries auxquelles nous avons dû faire face.

98 personnes ont participé au concours - il y a si peu de monde car il s'agit d'un concours pour le traitement du son, sur une plateforme russe, et même dans un docker. J'étais dans une équipe avec Dmitry Danevsky, Kaggle Master, que nous avons rencontré et accepté de participer tout en discutant des approches dans une autre compétition.

Défi


On nous a donné 5 Go de fichiers audio, divisés en classes usurpation / humain, et nous avons dû prédire la probabilité de la classe, l'envelopper dans un docker et l'envoyer au serveur. La solution devait fonctionner en 30 minutes et peser moins de 100 Mo. Selon les informations officielles, il était nécessaire de faire la distinction entre la voix d'une personne et celle générée automatiquement - bien que personnellement, il me semble que la classe d'usurpation comprenait également des cas où le son était généré en tenant le haut-parleur au microphone (comme le font les attaquants en volant un enregistrement de la voix de quelqu'un d'autre pour identification).

La métrique était EER :



Nous avons pris le premier code qui venait du réseau, car le code des organisateurs semblait surchargé.

Compétition


Les organisateurs ont fourni la ligne de base et simultanément l'énigme principale de la compétition. C'était aussi simple qu'un bâton: nous prenons des fichiers audio, comptons les spectrogrammes à la craie , entraînons MobileNetV2 et nous nous retrouvons aux alentours de la 12e place ou moins. Pour cette raison, beaucoup auraient pensé qu'une douzaine de personnes avaient participé au concours, mais ce n'était pas le cas. Pendant toute la première étape de la compétition, notre équipe n'a pas pu briser cette ligne de base. Le code idéalement identique a donné le résultat bien pire, et toutes les améliorations (telles que le remplacement par des grilles plus lourdes et des prévisions OOF ) ont aidé, mais ne l'ont pas rapproché de la ligne de base.

Et puis l'inattendu s'est produit: environ une semaine avant la fin du concours, il s'est avéré que la mise en œuvre du comptage des métriques des organisateurs contenait un bug et dépendait de l'ordre des prédictions. À peu près à la même époque, il a été constaté que dans les conteneurs dockers, les organisateurs n'avaient pas gentiment désactivé Internet, de sorte que beaucoup ont téléchargé l'échantillon de test. Ensuite, le concours a été gelé pendant 4 jours, a corrigé la métrique, a mis à jour les données, a désactivé Internet et a recommencé pendant encore 2 semaines. Après le recomptage, nous étions en 7e place avec l'une de nos premières soumissions. Cela a été une puissante motivation pour continuer à participer à la compétition.

En parlant de modèle


Nous avons utilisé une grille de convolution de type resnet formée sur des spectrogrammes à la craie.

  1. Il y avait au total 5 blocs de ce type. Après chacun de ces blocs, nous avons effectué une surveillance approfondie et augmenté le nombre de filtres d'une fois et demie.
  2. Pendant la compétition, nous sommes passés d'une classification binaire à une classification multi-classes afin d'utiliser plus efficacement la technique de mixage , dans laquelle nous mixons deux sons et résumons leurs étiquettes de classe. De plus, après une telle transition, nous avons pu augmenter artificiellement la probabilité de la classe d'usurpation en la multipliant par 1,3. Cela nous a aidés, car on supposait que l'équilibre des classes dans l'échantillon test pouvait être différent de celui de la formation, et nous avons donc amélioré la qualité des modèles.
  3. Des modèles de pli ont été formés et les prévisions de plusieurs modèles ont été moyennées.
  4. La technique de codage de fréquence s'est également avérée utile. L'essentiel est: les convolutions 2D sont invariantes de position, et dans les spectrogrammes les valeurs le long de l'axe vertical ont des significations physiques très différentes, nous aimerions donc transférer ces informations au modèle. Pour ce faire, nous avons concaténé le spectrogramme et la matrice, constitués de nombres dans un segment de -1 à 1 de bas en haut.

    Pour plus de clarté, je vais donner le code:

    n, d, h, w = x.size()         vertical = torch.linspace(-1, 1, h).view(1, 1, -1, 1)         vertical = vertical.repeat(n, 1, 1, w)         x = torch.cat([x, vertical], dim=1) 
  5. Nous avons formé tout cela, y compris sur les données pseudo-étiquetées de l'échantillon de test ayant fui du premier étage.

Validation


Dès le début de la compétition, tous les participants ont été tourmentés par la question: pourquoi la validation locale donne-t-elle EER 0,01 et moins, et le classement 0,1 et n'est pas particulièrement corrélée? Nous avions 2 hypothèses: soit il y avait des doublons dans les données, soit des données de formation ont été collectées sur un ensemble de locuteurs, et des données de test sur un autre.

La vérité était quelque part entre les deux. Dans les données de formation, environ 5% des données se sont révélées être des doublons, et cela ne compte que les doublons complets des hachages (en passant, il pourrait également contenir différents recadrages du même fichier, mais ce n'est pas si facile à vérifier - c'est pourquoi nous ne l'avons pas fait).

Pour tester la deuxième hypothèse, nous avons formé une grille d'ID de locuteur, reçu des plongements pour chaque locuteur, regroupé le tout avec k-moyennes et plié les stratifié. À savoir, nous nous sommes entraînés sur les haut-parleurs d'un groupe et avons prédit les haut-parleurs des autres. Cette méthode de validation a déjà commencé à corréler avec le classement, bien qu'elle ait montré un score 3-4 fois meilleur. Comme alternative, nous avons essayé de valider uniquement sur les prédictions dans lesquelles le modèle était au moins un peu incertain, c'est-à-dire que la différence entre la prédiction et l'étiquette de classe était> 10 ** - 4 (0,0001), mais un tel schéma n'a pas donné de résultats.

Et qu'est-ce qui n'a pas fonctionné?


Sur Internet, il suffit de trouver des milliers d'heures de discours humain. De plus, un concours similaire avait déjà eu lieu il y a plusieurs années. Par conséquent, il semblait évident de télécharger un grand nombre de données (nous avons téléchargé ~ 300 Go) et de former le classificateur à ce sujet. Dans certains cas, la formation sur ces données s'est avérée un peu si nous enseignions sur des données supplémentaires et sur les trains avant d'atteindre un plateau, puis nous ne nous sommes formés que sur les données de formation. Mais avec ce schéma, le modèle a convergé en environ 2 jours, ce qui signifie 10 jours pour tous les plis. Par conséquent, nous avons abandonné cette idée.

De plus, de nombreux participants ont remarqué une corrélation entre la longueur du fichier et la classe; cette corrélation n'a pas été remarquée dans l'échantillon de test. Les grilles d'images ordinaires comme resnext, nasnet-mobile, mobileNetV3 ne se sont pas très bien montrées.

Postface


Ce n'était pas facile et parfois étrange, mais nous avons quand même eu une expérience cool et nous sommes sortis en tête. Par essais et erreurs, j'ai réalisé quelles approches fonctionnaient assez bien et lesquelles n'étaient pas très bonnes. Maintenant, je vais utiliser ces informations avec nous lors du traitement du son. Je travaille dur pour amener l'IA conversationnelle à un niveau impossible à distinguer de l'humain, et donc toujours à la recherche de tâches et de puces intéressantes. J'espère que vous avez également appris quelque chose de nouveau.

Enfin, je poste notre code .

Source: https://habr.com/ru/post/fr475480/


All Articles