¿Qué es la codificación posicional?

¿Qué es la codificación posicional?

La codificación posicional es una técnica que inyecta información sobre la posición de las palabras en una secuencia a arquitecturas transformadoras.

El orden de las palabras juega un papel fundamental en la comprensión del significado semántico de una oración. Por ejemplo, “Allen pasea al perro” y “el perro pasea a Allen” tienen significados completamente diferentes a pesar de tener las mismas palabras o tokens. Al implementar aplicaciones de procesamiento de lenguaje natural (PLN) mediante aprendizaje profundo y redes neuronales, necesitamos crear un mecanismo mediante el cual las máquinas puedan retener el orden de las palabras en una oración para producir resultados lógicos.  

Tradicionalmente, los modelos, como las redes neuronales recurrentes o las memorias largas a corto plazo (LSTM), tienen un mecanismo incorporado que maneja el orden de las palabras. Las RNN y LSTM procesan entradas secuencialmente, un token a la vez, memorizando todas las posiciones de las palabras en una secuencia. En otras palabras, el vector de n dimensiones, también llamado "vector de entrada", se procesa uno tras otro, aprendiendo órdenes de forma inherente. Por el contrario, otras arquitecturas que se benefician de las redes neuronales convolucionales (CNN) o transformadores (Vaswani et al. 2017) no conservan el orden de las palabras y procesan tokens en paralelo. Por lo tanto, necesitamos implementar un mecanismo que pueda representar explícitamente el orden de las palabras en una secuencia, una técnica conocida como codificación posicional. La codificación posicional permite que el transformador retenga información del orden de las palabras, lo que permite la paralelización y el entrenamiento eficiente del modelo. A menudo se pueden encontrar implementaciones de codificación posicional en GitHub.  

Las últimas tendencias de IA presentadas por expertos

Obtenga insights curados sobre las noticias más importantes e intrigantes de la IA. Suscríbase a nuestro boletín semanal Think. Consulte la Declaración de privacidad de IBM .

¡Gracias! Ya está suscrito.

Su suscripción se entregará en inglés. En cada boletín, encontrará un enlace para darse de baja. Puede gestionar sus suscripciones o darse de baja aquí. Consulte nuestra Declaración de privacidad de IBM para obtener más información.

¿Por qué es importante la codificación posicional?

El orden de las palabras en una oración o secuencia dicta el significado inherente de la oración en lenguajes naturales. Además, para machine learning, codificar el orden de las palabras nos da un "diccionario" sobre dónde debe estar cada palabra. Esta información se conserva y puede generalizarse a lo largo del entrenamiento de los modelos de transformadores, lo que permite la paralelización y supera a las RNN y LSTM por su eficiencia de entrenamiento.  

Repasemos el ejemplo:

  • "Allen pasea al perro"
  • "El perro pasea a Allen"

Estas dos oraciones con los mismos tres tokens tienen significados completamente diferentes según el orden de las palabras. Los transformadores, que se basan en la autoatención y el mecanismo de atención multicabezal, no tienen una representación inherente de los órdenes de las palabras y tratarían la palabra individual en una secuencia de forma idéntica si no proporcionamos información posicional explícita. Queremos que el modelo comprenda quién pasea y a quién se pasea, lo que depende completamente de las posiciones.  

Logramos este objetivo procesando primero cada palabra como un vector que representa su significado; por ejemplo, "perro" se codificará en una matriz de alta dimensión que codifica su concepto. En términos técnicos, cada palabra o subpalabra se asigna a una incorporación de entrada de diferentes longitudes. Sin embargo, por sí solo, el vector de significado no nos dice en qué parte de la oración aparece el perro. La codificación posicional agrega un segundo vector, uno que codifica el índice de posición, como "primera palabra" o "segunda palabra", y así sucesivamente. Luego, los dos vectores se suman para representar qué es la palabra y dónde está la palabra. Este vector resultante a menudo se denomina vector de codificación posicional.   

Hay varias formas de crear codificación posicional. En este artículo, exploramos el ejemplo más conocido del uso de una función sinusoidal presentada por los autores en Atención es todo lo que necesita1 para crear codificación posicional.  

Mixture of Experts | 28 de agosto, episodio 70

Decodificación de la IA: Resumen semanal de noticias

Únase a nuestro panel de ingenieros, investigadores, responsables de producto y otros profesionales de talla mundial que se abren paso entre el revuelo de la IA para ofrecerle las últimas noticias e insights al respecto.

Codificación posicional en transformadores

En el artículo original presentado por Vaswani et al. 2017, la idea clave es generar una codificación fija y determinista para cada posición en una secuencia mediante el uso de una función sinusoidal, en particular, la función seno sin(x) y la función de coseno cos(x) .  

¿Qué son las funciones sinusoidales?

Las funciones sinusoidales son un concepto matemático fundamental que produce un patrón de longitud de onda suave. En particular, los autores utilizan las funciones coseno y seno en las funciones de transformador originales para ayudar a la codificación posicional.

Si trazamos sin(x) y  cos(x) , veremos una curva que sube y baja entre -1 y 1 en un patrón periódico y repetitivo.

Algunas propiedades del seno que lo hacen eficaz para la codificación posicional: 

  • Es periódico: se repite regularmente a lo largo de intervalos, lo cual es útil para representar patrones repetidos.

  • Es fluido y continuo: pequeños cambios en la entrada dan como resultado pequeños cambios en la salida, lo que nos da una forma de representar posiciones en un espacio diferenciable.

  • Al variar la frecuencia de las longitudes de onda a través de las dimensiones, podemos crear una representación variada y multiescalar de la posición. 

Tracemos las ondas seno y coseno para visualizar cómo se ven:

import numpy as np 
import matplotlib.pyplot as plt 

# Create an array of 100 x values evenly spaced from 0 to 2π (approx 6.28)
x = np.linspace(0, 2 * np.pi, 100) 

# Compute the sine and cosine of each x value 
sin_values = np.sin(x) 

# Create the plot 
plt.figure(figsize=(5, 2)) 
plt.plot(x, sin_values, label='sin(x)', color='blue') 

# Customize the plot 
plt.title('Sine Function') 
plt.xlabel('x') 
plt.ylabel('Function value') 
plt.axhline(0, color='black', linewidth=0.5) # horizontal line at y=0 
plt.axvline(0, color='black', linewidth=0.5) # vertical line at x=0 
#plt.grid(True, linestyle='--', alpha=0.5) 
plt.legend() 
plt.tight_layout() 

# Show the plot 
plt.show() 

La función seno

Gráfico de la función seno, una curva repetitiva con un rango positivo y negativo.

Y ahora veamos cómo podemos trazar la función coseno:

#apply the cosine function to the same array, x
cosine = np.cos(x) 

plt.figure(figsize = (5,2)) 
plt.plot(x, cosine, label = 'cos(x)', color = 'blue') 
plt.title('The Cosine Function') 
plt.xlabel('x') 
plt.ylabel('Function value') 
plt.axhline(0, color='black', linewidth=0.5) # horizontal line at y=0 
plt.axvline(0, color='black', linewidth=0.5) # vertical line at x=0 
#plt.grid(True, linestyle='--', alpha=0.5) 
plt.legend() 
plt.tight_layout() 
Un gráfico de la función coseno, que ilustra su naturaleza periódica y sus características clave.

Las fórmulas de codificación de posición sinusoidal, definidas por los autores del documento original de transformadores (Vaswani et al. 2017), se muestran a continuación:

Para posiciones pares:

 PEpos,2i=sin(pos100002i/dmodel) 

Para posiciones impares:

 PEpos,2i+1=cos(pos100002i/dmodel) 

  •  k : la posición de la palabra en la oración (por ejemplo, 0 para la primera palabra, 1 para la segunda, etc.)

  •  i : el índice de dimensión del vector de incorporación. se asigna al índice de columnas. 2i indicará una posición par y 2i+1 indicará una posición impar

  •  dmodel : la dimensionalidad predefinida de las incorporaciones de token (por ejemplo, 512)

  •  n : valor escalar definido por el usuario (por ejemplo, 10 000)

  •  PE : función de posición para trazar la posición k en la secuencia de entrada para obtener el mapeo posicional

     

 

Con esta fórmula, cada palabra, en la posición k, tendrá un valor de incorporación basado en la posición de la palabra. Tomemos el ejemplo que usamos, "Allen pasea al perro"; podemos calcular la incorporación para cada palabra:

-  k1 = "Allen"

-  k2 = "pasea"

-  k3 ="perro"

Escribamos una función de Python simple para calcular el valor de  PE(k) :

import numpy as np 

import matplotlib.pyplot as plt 

  

# create the positional encoding function using the formula above 

def getPositionEncoding(seq_len, d, n=10000): 

    # instantiate an array of 0s as a starting point 

    P = np.zeros((seq_len, d)) 

    # iterate through the positions of each word  

    for k in range(seq_len): 

        #calculate the positional encoding for even and odd position of each word 

        for i in np.arange(int(d/2)): 

            denominator = np.power(n, 2*i/d) 

            P[k, 2*i] = np.sin(k/denominator) 

            P[k, 2*i+1] = np.cos(k/denominator) 
    return P 

Una vez que llamamos a la función y entrada el valor correspondiente en nuestro ejemplo, donde la longitud de la secuencia es 3, con una dimensión simplificada de  d=4 y  n=10000 

P = getPositionEncoding(seq_len=3, d=4, n=10000) 

print(P) 

Obtenemos la siguiente matriz de codificación (también conocida como tensor):

[[ 0.                      1.                      0.                       1.        ]

 [ 0.84147098  0.54030231  0.09983342  0.99500417]

 [ 0.90929743 -0.41614684  0.19866933  0.98006658]]

Para representar este resultado de manera más concreta, obtenemos

Posición de palabraDim 0
sin(pos ÷ 10000^(0 ÷ 4))
Dim 1
cos(pos ÷ 10000^(0 ÷ 4))
Dim 2
sin(pos ÷ 10000^(2 ÷ 4))
Dim 3
cos(pos ÷ 10000^(2 ÷ 4))
“Allen” k = 00.00000.00000.00001.0000
“pasea” k = 10.8414710.5403020.0100000.999950
“perro” k = 20.909297-0.4161470.0200000.999800

Aquí podemos ver el valor concreto de cada palabra y su correspondiente valor de incorporación posicional. Sin embargo, no podemos usar estas incorporaciones de palabras directamente para interpretar el orden de las palabras. El valor calculado aquí se utiliza para inyectar información sobre la posición en un vector de entrada del transformador. Debido a que la entrada de sin(x)  y  cos(x) son diferentes, cada posición  k  responderá a una función sinusoidal diferente. La posición correspondiente de las diferentes funciones sinusoidales nos da información sobre la posición absoluta y la posición relativa de la palabra en "Allen pasea al perro". En otras palabras, el modelo puede utilizar esta información de tal manera que el modelo pueda aprender a asociar estos patrones con el orden, el espaciado y la estructura.  

Ahora implementemos una función de Python para visualizar la matriz posicional

import numpy as np 

import matplotlib.pyplot as plt 

  

def get_position_encoding(seq_len, d_model, n=10000): 

    P = np.zeros((seq_len, d_model)) 

    for pos in range(seq_len): 

        for i in range(d_model): 

            angle = pos / np.power(n, (2 * (i // 2)) / d_model) 

            P[pos, i] = np.sin(angle) if i % 2 == 0 else np.cos(angle) 

    return P 

  

# Parameters 

seq_len = 100   # Number of tokens 

d_model = 512   # Embedding dimensions 

  

# Generate positional encoding 

P = get_position_encoding(seq_len, d_model) 

  

# Plot 

plt.figure(figsize=(10, 6)) 

cax = plt.matshow(P, cmap='viridis', aspect='auto') 

plt.title("Sinusoidal Positional Encoding Heatmap") 

plt.xlabel("Embedding Dimension") 

plt.ylabel("Token Position") 

plt.colorbar(cax) 

plt.tight_layout() 

plt.show() 
Mapa de calor sinusoidal

Reflexiones finales

Como podemos ver con las diferentes frecuencias basadas en valores de x, cada posición correspondiente de la palabra de entrada k diferirá en una escala de  [-1.1] : el rango de la  sin(x)  función. A partir de nuestro modelo de transformador basado en codificador y decodificador aprenderá y conservará la codificación de posición diferente de cada palabra, lo que permitirá que el modelo retenga la información para el entrenamiento. El vector de posición codificado permanece estático durante el entrenamiento, lo que permite el cálculo paralelo.

Soluciones relacionadas
IBM watsonx.ai

Entrene, valide, ajuste y despliegue IA generativa, modelos fundacionales y capacidades de machine learning con IBM watsonx.ai, un estudio empresarial de próxima generación para creadores de IA. Diseñe aplicaciones de IA en menos tiempo y con menos datos.

Descubra watsonx.ai
Soluciones de inteligencia artificial

Ponga la IA a trabajar en su negocio con la experiencia en IA líder en la industria y la cartera de soluciones de IBM a su lado.

Explore las soluciones de IA
Consultoría y servicios de IA

Reinvente los flujos de trabajo y las operaciones críticas añadiendo IA para maximizar las experiencias, la toma de decisiones en tiempo real y el valor empresarial.

Conozca los servicios de IA
Dé el siguiente paso

Obtenga acceso único a capacidades que abarcan el ciclo de vida del desarrollo de IA. Produzca potentes soluciones de IA con interfaces fáciles de usar, flujos de trabajo y acceso a API y SDK estándar de la industria.

Explore watsonx.ai Reserve una demostración en vivo
Notas de pie de página

1. “Attention Is All You Need”, Ashish Vaswani et al., Proceedings of the 31st International Conference on Neural Information Processing Systems, arXiv:1706.03762v7, revisado el 2 de agosto de 2023.

2. “Long Short-Term Memories”, Sepp Hochreiter and Jürgen Schmidhuber. 1997. Long Short-Term Memory. Neural Comput. 9, 8 (15 de noviembre de 1997), 1735–1780., 

3. “Foundations of Recurrent Neural Networks (RNNs) and Long Short-Term Memories” Alex Sherstinsky et al., Elsevier “Physica D: Nonlinear Phenomena” journal, Volume 404, marzo de 2020: Special Issue on Machine Learning and Dynamical Systems