De identificadores de tokens a números útiles
Un embedding de token es una fila de números que representa un token. La codificación de posición le suma una señal que dice dónde está el token. Juntos forman la entrada de todo transformer.
Un identificador es solo una etiqueta. El número 2 no vale «más» que el número 1. El modelo necesita números que pueda multiplicar y sumar.
Al final de esta lección
Nota
Puedo construir los vectores de entrada de un transformer a partir de los identificadores y las posiciones.
Palabras clave
| Palabra | Qué significa | Ejemplo |
|---|---|---|
| Vector | una lista de números | [1, 0, 2] |
| Tabla de embeddings | una tabla con una fila de números por token | |
| Embedding | la fila de la tabla para un token | |
| Posición | el lugar de un token en el texto, contando desde 0 | |
| Señal de posición | un vector que representa un lugar | |
| Vector de entrada | el embedding más la señal de posición |
Las celdas que rellenan los estudiantes quedan en blanco en esta vista previa.
La tabla de embeddings da números
Una tabla de embeddings tiene una fila por token del vocabulario. Para buscar el embedding de un token, se toma la fila cuyo número es su identificador. Esa fila es el embedding del token.
Nuestra tabla tiene cuatro tokens y tres números por fila. Los números empiezan al azar y cambian durante el entrenamiento. Los tokens que se usan de forma parecida acaban con filas parecidas.
Ejemplo resuelto: una tabla muy pequeña
| Token | Identificador | Fila de números |
|---|---|---|
| gato | 0 | 1, 0, 2 |
| come | 1 | 0, 1, 0 |
| ratón | 2 | 2, 1, 1 |
| duerme | 3 | 2, 1, -1 |
Las celdas que rellenan los estudiantes quedan en blanco en esta vista previa.
Buscar las filas y sumar las posiciones
# Una fila de números por identificador: gato, come, ratón, duerme.
table = [[1, 0, 2], [0, 1, 0], [2, 1, 1], [2, 1, -1]]
# Una fila por lugar en la frase: primero, segundo, tercero.
positions = [[1, 1, 0], [0, 1, 1], [1, 0, 1]]
ids = [0, 1, 2] # gato come ratón
for place in range(len(ids)):
row = table[ids[place]]
signal = positions[place]
vector = []
for j in range(3):
vector.append(row[j] + signal[j])
print("id", ids[place], "fila", row, "más posición", signal, "da", vector)
# Cambia ids por [2, 1, 0], es decir, ratón come gato, y pulsa Ejecutar.
# ¿Qué vector cambia y cuál sigue igual?
El tamaño de una tabla real
docker exec jupyter python3 -c "print(50000 * 512)"Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.
El orden importa, la tabla no lo muestra
«gato come ratón» y «ratón come gato» tienen los mismos tres tokens, pero no cuentan la misma historia. Buscar en la tabla da a cada token la misma fila, esté donde esté.
El paso de la próxima lección, la atención, mezcla los vectores de los tokens. Sola, los trata como una bolsa sin orden. Sin ayuda, el modelo no distinguiría las dos frases.
Ejemplo resuelto: dos órdenes, las mismas filas
| Frase | Primero | Segundo | Tercero |
|---|---|---|---|
| gato come ratón | gato: 1, 0, 2 | come: 0, 1, 0 | ratón: 2, 1, 1 |
| ratón come gato | ratón: 2, 1, 1 | come: 0, 1, 0 | gato: 1, 0, 2 |
Las celdas que rellenan los estudiantes quedan en blanco en esta vista previa.
Un error frecuente
Advertencia
Mucha gente piensa que un modelo conoce el orden de las palabras porque los tokens llegan en orden. La atención los trata como una bolsa. El modelo conoce el orden solo si se suma una señal de posición a cada token antes de la primera capa.
Cada token recibe una señal de posición
Una segunda tabla tiene una fila por posición: primero, segundo, tercero. La fila del lugar del token se suma a su embedding, número a número. El resultado es el vector de entrada.
Ahora, «gato» en primer lugar y «gato» en tercer lugar tienen vectores distintos. Algunos modelos aprenden la tabla de posiciones. Otros usan patrones de ondas fijos, sin aprendizaje.
Ejemplo resuelto: sumar las señales de posición
| Lugar | Señal de posición | «gato come ratón» | «ratón come gato» |
|---|---|---|---|
| Primero | 1, 1, 0 | gato: 1+1, 0+1, 2+0 = 2, 1, 2 | ratón: 3, 2, 1 |
| Segundo | 0, 1, 1 | come: 0, 2, 1 | come: 0, 2, 1 |
| Tercero | 1, 0, 1 | ratón: 3, 1, 2 | gato: 1+1, 0+0, 2+1 = 2, 0, 3 |
Las celdas que rellenan los estudiantes quedan en blanco en esta vista previa.
Las dos frases con 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())"Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.