Fourscore et les oiseaux

“Le Nombre imaginaire” ou les mathématiques comme terrain de jeu où l’imagination seule fixe les limites.

Les deux chroniques précédentes ont brossé un tableau superficiel du domaine de la traduction automatique, en s’intéressant aux algorithmes basés sur la grammaire puis aux algorithmes statistiques. Terminons ce petit triptyque avec une dernière classe d’algorithmes de traduction, la plus récente et apparemment la plus couronnée de succès : ce sont les algorithmes à base de réseaux de neurones.

De ceux-ci nous avons déjà parlé ; en voici tout de même une description très simplifiée. Un réseau de neurones, en informatique, c’est une structure où les calculs sont effectués par un grand nombre de petits agents – les neurones. Chaque neurone est relié à certains autres par une connexion orientée affectée d’un certain « poids  », un nombre positif ou négatif. Un neurone donné peut donc avoir des neurones en amont, en aval, ou les deux. Pour savoir s’il doit être actif ou non, chaque neurone regarde parmi ses prédécesseurs ceux qui sont actifs, et fait la somme des poids des connexions venant de ces neurones. Si cette somme pondérée dépasse un certain seuil, le neurone s’active à son tour plus ou moins fortement, et alimente à son tour les neurones en aval.

Intéressons-nous au cas le plus simple, dans lequel les connexions entre neurones ne font pas de boucles : un neurone qui est en amont d’un autre ne peut pas être en aval de ce dernier. Dans ce cas, on trouvera des neurones « sources », qui ne sont en aval d’aucun autre, et des neurones « puits », qui ne sont en amont d’aucun autre.

Un logiciel de reconnaissance d’image utilisant ce principe pourrait avoir un neurone source par pixel de l’image ; chaque neurone source serait activé en fonction du niveau de noir ou de blanc dans le pixel correspondant. En sortie, le réseau pourrait avoir un unique neurone qui s’active si le réseau reconnait, disons, un chat. Entre les deux, on trouverait tout un tas de neurones intermédiaires. Un neurone relié à deux neurones sources correspondant à des pixels contigus peut, par exemple, reconnaître des contours, s’il ne s’active que quand la différence de luminosité entre les deux pixels sources est importante.

Tout cela est fort bien mais par quelle magie un réseau de neurones arbitraires pourrait-il reconnaître un chat ? La réponse est qu’il ne le peut pas ; il faut le lui apprendre. On part d’un réseau aléatoire, dans lequel les connexions entre neurones et leurs poids sont choisies au hasard. Puis on montre à ce réseau une image, ce qui a pour effet d’activer certains neurones sources. Cette activation se transmet – ou pas – au neurone de sortie. Si l’image contenait un chat et si ce neurone de sortie a été activé (par hasard), on « récompense » le réseau en renforçant les connexions qui ont servi à alimenter ce neurone. S’il y a erreur, on diminue au contraire le poids des connexions fautives (le processus réellement mis en œuvre est complexe, mais le principe est là).

On recommence avec une autre image, contenant ou non un chat. On recommence beaucoup. On recommence longtemps. Des millions de fois s’il le faut. Et il le faut.

Quand on estime avoir suffisamment entraîné le réseau, on peut le tester sur un autre corpus d’images qui n’ont pas été utilisées pour l’entraînement mais dont on connaît la nature – chat ou pas chat. Si le réseau se comporte bien lors de ce test, on le déclare bon pour le service et on lui soumet votre flux Facebook, où il trouvera des chats. Beaucoup de chats. Beaucoup trop de chats si vous voulez mon avis. Des chats ad nauseam. Mais là n’est pas le sujet.

Quittons les chats pour revenir à nos moutons. Comment peut-on utiliser des neurones pour traduire du texte ?

Tout d‘abord, nous ne pouvons pas juste prévoir un neurone d’entrée et de sortie par mot et penser que tout va bien se passer. Ce n’est pas qu’une question de taille. Même en prévoyant 400 000 mots par langue, ces neurones tiendraient facilement en mémoire ; le nombre de connexions possibles entre neurones augmenterait certes considérablement, mais seules les connexions existantes prennent réellement de la place en mémoire. Le problème est surtout que l’apprentissage serait très inefficace car ce que vous apprendriez pour un mot n’aurait aucune raison d’être généralisé à un autre mot même sémantiquement très proche. Supposons que notre réseau soit confronté à tout un lot de chats (toujours tirés de votre flux Facebook). Il apprendra à traduire « a white cat » en « un chat blanc », « a black cat » en « un chat noir », etc. Ah oui, il remarquera au passage que la traduction correcte pour « a small cat » est « un petit chat ». Mais quand on lui soumettra « a big cat », s’il ne l’a jamais vu avant, notre réseau le traduira vraisemblablement par « un chat gros », sans pouvoir inférer que les adjectifs de taille se placent plutôt avant le nom. Il lui faudra apprendre cet exemple explicitement – et rien ne garantit qu’il ne refera pas l’erreur sur « a huge cat ».

Heureusement, il existe une technique que nous avons déjà évoquée et qui permet de représenter des mots par des vecteurs d’un espace multidimensionnel – de sorte que deux mots apparaissant souvent dans le même contexte, et qui sont donc a priori sémantiquement reliés, soient représentés comme des vecteurs proches. Ainsi, deux mots qui se retrouvent souvent dans le contexte « le XXX » ou « un XXX » auront des coordonnées proches dans une dimension de l’espace, indiquant leur nature commune de noms masculins. Il y a plus de chances de cette manière qu’un exemple de traduction correcte se propage naturellement vers des cas sémantiquement voisins.

Par ailleurs, un texte est une séquence de mots qui se succèdent et ne peuvent être traduits indépendamment. Contrairement au cas de l’image, où chaque pixel peut contribuer en parallèle au travail du réseau de neurones, l’ordre des mots est crucial. De fait, la traduction du prochain mot dépendra au plus haut point de la séquence des mots précédents, et même de la séquence des mots que vous aurez déjà produits dans votre traduction. Le réseau de neurones doit donc à chaque instant conserver et utiliser un souvenir de ce qu’il a traduit auparavant ; cela s’appelle maintenir un état interne. Il existe des types de réseaux de neurones, appelés réseaux de neurones récurrents (RNN en acronyme anglais) qui savent le faire : l’état précédent d’un neurone d’entrée est conservé à l’étape suivante dans un neurone en aval, et pourra ainsi être combiné avec le nouvel état du neurone d’entrée. La séquence de mots à traduire sera ainsi passé comme à travers un pipe-line au RNN, dont l’état sera ainsi à tout instant représentatif de la séquence de mots déjà reçue. Ce RNN est appelé un encodeur.

Reste à produire un texte dans la langue cible à partir de l’état de l’encodeur. Ici encore, on utilisera un RNN appelé décodeur, qui est en quelque sorte utilisé dans l’autre sens et produit une séquence de mots de la langue cible. Chaque mot produit dépend donc non seulement de l’état de l’encodeur (la séquence de mots sources à traduire) mais aussi de celui du décodeur (la séquence de mots cibles déjà produite).

Pour rendre cela plus concret, faisons un peu de travaux pratiques avec Google Translate, qui utilise une technologie apparentée. Sélectionnez deux langues que vous connaissez – par exemple l’anglais comme source et le français comme cible. Nous allons traduire le petit texte suivant : « The car is out of order and it has a flat tire » – mais nous allons le faire petit à petit pour observer ce qui se passe à mesure que la séquence d’entrée se constitue.

Commencez par taper le mot « The » dans la fenêtre de gauche. Dans celle de droite, l’outil vous proposera « Le » ou « La » : faute de contexte, les deux traductions peuvent s’appliquer.

Si vous continuez à taper « car », la traduction devient « La voiture » : en utilisant la séquence « the car » représentée par l’état de l’encodeur, on peut éliminer l’ambigüité de genre.

Continuons à taper « is out ». Traduction : « La voiture est sortie ». Pourquoi pas, même si à mon sens on dirait plutôt cela d’une personne : « the doctor is out » – « le docteur est sorti ».

Ajoutons « of » ; la traduction devient « La voiture est hors de ». Pas mal.

Arrive « order ». Rétropédalage complet, le traducteur sait reconnaître l’expression idiomatique et nous donne «  La voiture est en panne ».

Ajoutons « and it ». Le logiciel ajoute « et elle ». Saluons-le bien bas ! Il a compris que le mot « it » faisait référence à la voiture et a donc adopté le genre féminin. Cela n’a rien d’évident.

Complétons notre phrase avec « has a flat tire » et nous obtenons une traduction très correcte : « La voiture est en panne et elle a un pneu crevé ». A noter tout de même qu’aucune différence n’est faite entre « un pneu à plat » et « un pneu crevé ».

Rien de bien poétique ou littéraire à l’entrée ni à la sortie donc, mais cela fonctionne assez bien. La prise en compte du contexte marche même mieux que je ne m’y attendais. Ainsi la phrase que je croyais piégée « Shelly, who loved that dog so much, was my friend » est impeccablement traduite en « Shelly, qui aimait tellement ce chien, était mon amie  ». « Shelly » est donc reconnu comme nom féminin, et cette information, acquise dès le premier mot, est conservée jusqu’au dernier, où elle est utilisée pour l’accord de genre. Plus fort encore, « My neighbour, who loved her dog so much, was my friend. » se traduit correctement (« Ma voisine, qui aimait tellement son chien, était mon amie. »). Ici, le genre du sujet est déduit indirectement de la présence du pronom possessif féminin (lequel n’apparaît que bien plus tard). Cela n’a rien d’impressionnant en apparence, mais il s’agit en réalité d’un bel exploit technique, si on considère que le logiciel n’a jamais reçu aucune connaissance explicite de la grammaire anglaise.

Quand on cherche la petite bête, on finit bien par la trouver. Je suis tombé sur un bug assez amusant : « Jean, who loved that dog so much, was my friend » est traduit en « Jean, qui aimait tant ce chien, était mon ami ». Le prénom Jean, pourtant féminin en anglais, s’est auto-traduit en prénom français masculin.

Il est également amusant de tester Google Translate avec un texte connu contenant des formes rares, où l’on voit apparaître presque explicitement la traduction humaine souvent élaborée qui lui avait été donnée lors de l’apprentissage. Par exemple, le célèbre début de la Gettysburg Address d’Abraham Lincoln : « Fourscore and seven years ago our fathers brought forth on this continent a new nation, conceived in liberty and dedicated to the proposition that all men are created equal » est traduite ainsi : « Il y a quatre-vingt et sept ans, nos pères ont engendré sur ce continent une nouvelle nation, conçue dans la liberté et vouée à la proposition que tous les hommes sont créés égaux ». Qui a inventé ce « quatre-vingt et sept ans » ? Un traducteur humain, je vous en fiche mon billet. Manière de faire ressentir à un lecteur français la solennité du « Fourscore and seven years ». Le reste du texte «  sent » trop l’humain pour qu’il en soit autrement. Pourtant, le doute subsiste puisque la traduction littérale, mot à mot de ce « Fourscore and seven years » est justement « quatre vingt et sept ans ». Pour en avoir le cœur net, j’ai donc traduit « Fourscore and two birds were singing ». Bingo  ! Dans ce contexte, Fourscore n’est même pas reconnu et le traducteur y voit un nom propre. Résultat : « Fourscore et deux oiseaux chantaient ». Ce qui est charmant, à défaut d’être solennel voire simplement juste.

Laissons donc notre ami Fourscore chanter avec les oiseaux, pendant que nos chers Traîtres pratiquent seuls l’art de bellement traduire de beaux textes. Mais saluons tout de même une technologie brillante qui découvre seule des règles déjà relativement subtiles.

Yannick Cras

Le nombre imaginaire