Des identifiants de jetons aux nombres utiles
Un plongement de jeton (embedding) est une ligne de nombres qui représente un jeton. L’encodage de position y ajoute un signal qui dit où le jeton se trouve. Ensemble, ils forment l’entrée de tout transformeur.
Un identifiant n’est qu’une étiquette. Le nombre 2 ne vaut pas « plus » que le nombre 1. Le modèle a besoin de nombres qu’il peut multiplier et additionner.
À la fin de cette leçon
Remarque
Je peux construire les vecteurs d’entrée d’un transformeur à partir des identifiants et des positions.
Mots-clés
| Mot | Ce que ça veut dire | Exemple |
|---|---|---|
| Vecteur | une liste de nombres | [1, 0, 2] |
| Table de plongements | une table avec une ligne de nombres par jeton | |
| Plongement | la ligne de la table pour un jeton | |
| Position | la place d’un jeton dans le texte, en comptant depuis 0 | |
| Signal de position | un vecteur qui représente une place | |
| Vecteur d’entrée | le plongement plus le signal de position |
Les cellules que les étudiants remplissent restent vides dans cet aperçu.
La table de plongements donne des nombres
Une table de plongements a une ligne par jeton du vocabulaire. Pour plonger un jeton, on prend la ligne dont le numéro est son identifiant. Cette ligne est le plongement du jeton.
Notre table a quatre jetons et trois nombres par ligne. Les nombres partent au hasard et changent pendant l’entraînement. Les jetons employés de façon proche finissent avec des lignes proches.
Exemple travaillé : une toute petite table
| Jeton | Identifiant | Ligne de nombres |
|---|---|---|
| chat | 0 | 1, 0, 2 |
| mange | 1 | 0, 1, 0 |
| souris | 2 | 2, 1, 1 |
| dort | 3 | 2, 1, -1 |
Les cellules que les étudiants remplissent restent vides dans cet aperçu.
Chercher les lignes et ajouter les positions
# Une ligne de nombres par identifiant : chat, mange, souris, dort.
table = [[1, 0, 2], [0, 1, 0], [2, 1, 1], [2, 1, -1]]
# Une ligne par place dans la phrase : première, deuxième, troisième.
positions = [[1, 1, 0], [0, 1, 1], [1, 0, 1]]
ids = [0, 1, 2] # chat mange souris
for place in range(len(ids)):
ligne = table[ids[place]]
signal = positions[place]
vecteur = []
for j in range(3):
vecteur.append(ligne[j] + signal[j])
print("id", ids[place], "ligne", ligne, "plus position", signal, "donne", vecteur)
# Remplacez ids par [2, 1, 0], soit souris mange chat, puis cliquez sur Exécuter.
# Quel vecteur change, et lequel reste le même ?
La taille d’une vraie table
docker exec jupyter python3 -c "print(50000 * 512)"Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
L’ordre compte, la table ne le montre pas
« chat mange souris » et « souris mange chat » contiennent les trois mêmes jetons, mais ne racontent pas la même histoire. Une recherche dans la table donne à chaque jeton la même ligne, où qu’il soit.
L’étape de la leçon suivante, l’attention, mélange les vecteurs des jetons. Seule, elle les traite comme un sac sans ordre. Sans aide, le modèle ne distinguerait donc pas les deux phrases.
Exemple travaillé : deux ordres, les mêmes lignes
| Phrase | Première | Deuxième | Troisième |
|---|---|---|---|
| chat mange souris | chat : 1, 0, 2 | mange : 0, 1, 0 | souris : 2, 1, 1 |
| souris mange chat | souris : 2, 1, 1 | mange : 0, 1, 0 | chat : 1, 0, 2 |
Les cellules que les étudiants remplissent restent vides dans cet aperçu.
Une erreur fréquente
Attention
Beaucoup pensent qu’un modèle connaît l’ordre des mots parce que les jetons arrivent dans l’ordre. L’attention les traite comme un sac. Le modèle connaît l’ordre seulement si un signal de position est ajouté à chaque jeton avant la première couche.
Un signal de position s’ajoute à chaque jeton
Une seconde table a une ligne par position : première, deuxième, troisième. On ajoute la ligne de la place du jeton à son plongement, nombre par nombre. Le résultat est le vecteur d’entrée.
Désormais, « chat » en première place et « chat » en troisième ont des vecteurs différents. Certains modèles apprennent la table des positions. D’autres utilisent des motifs d’ondes fixes, sans apprentissage.
Exemple travaillé : ajouter les signaux de position
| Place | Signal de position | « chat mange souris » | « souris mange chat » |
|---|---|---|---|
| Première | 1, 1, 0 | chat : 1+1, 0+1, 2+0 = 2, 1, 2 | souris : 3, 2, 1 |
| Deuxième | 0, 1, 1 | mange : 0, 2, 1 | mange : 0, 2, 1 |
| Troisième | 1, 0, 1 | souris : 3, 1, 2 | chat : 1+1, 0+0, 2+1 = 2, 0, 3 |
Les cellules que les étudiants remplissent restent vides dans cet aperçu.
Plonger les deux phrases avec NumPy
docker exec jupyter python3 -c "import numpy as np; E = np.array([[1, 0, 2], [0, 1, 0], [2, 1, 1], [2, 1, -1]]); P = np.array([[1, 1, 0], [0, 1, 1], [1, 0, 1]]); print((E[[0, 1, 2]] + P).tolist()); print((E[[2, 1, 0]] + P).tolist())"Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.