Curso de Matemáticas para IA · Lección 5 de 180
Índices de tensores para IA: lectura de muestras, tokens y características
Aprende a leer subíndices de tensores, traducir direcciones lote-token-característica a NumPy y detectar errores de ejes que parecen válidos en código de IA.
Un programa de IA lee X[1, 2, 0] y devuelve 0.8. Una expresión cercana, X[1, 0, 2], devuelve 0.3. Ambas direcciones son válidas. Solo una significa «la primera característica del último token del segundo ejemplo».
La diferencia es un índice: una posición utilizada para localizar un valor dentro de una estructura ordenada. Los índices son pequeñas piezas de notación, pero determinan qué ejemplo, token, característica, píxel o salida del modelo utiliza realmente un cálculo. Por eso, un índice incorrecto puede producir un número aparentemente creíble en lugar de un error útil.
Al terminar esta lección, podrás leer muestras y coordenadas indexadas, seguir una dirección de tensor lote-token-característica, traducir un subíndice matemático a NumPy y detectar una dirección cuyos números son legales pero cuyos significados de eje son incorrectos. Esto añade orden a las colecciones de datos de la lección 4. El sitio oficial complementario de Mathematics for Machine Learning sitúa esta notación en el recorrido que va de los datos numéricos a los vectores, matrices y modelos utilizados más adelante en el curso.
Un índice responde «¿qué posición?»
Supón que un dataset ordenado contiene tres ejemplos:
El subíndice de dice «selecciona el ejemplo de la posición 2». No dice que el valor del ejemplo sea 2. Si el segundo ejemplo es el par , entonces nombra el par completo.
Añade un segundo subíndice para seleccionar una coordenada dentro de ese ejemplo:
Lee de izquierda a derecha: elige el ejemplo 2 y después la coordenada 1. Los índices forman una dirección; el número almacenado en esa dirección es el valor.
Esto también separa la posición de la identidad. Mover una muestra de la posición 2 a la posición 7 cambia su índice aunque su identificador estable, los píxeles de la imagen y la etiqueta no cambien. Los índices son direcciones útiles, no nombres permanentes de objetos del mundo real.
Cada subíndice elige un eje
Un eje es una dirección en la que se organiza un array. Una tabla tiene un eje de filas y otro de columnas. Aquí, un tensor es un array multidimensional: puede tener esos dos ejes o añadir más para conceptos como lotes y tokens.
Considera un tensor de activaciones
donde:
- es el número de ejemplos del lote;
- es el número de posiciones de token por ejemplo; y
- es el número de características almacenadas para cada token.
La notación dice que cada entrada es un número real y que el tensor tiene forma . Una entrada escalar es
que significa: elige la posición de lote , la posición de token y la posición de característica , en ese orden.
Para un tensor con forma , una convención matemática basada en uno permite
La forma proporciona el rango de cada índice. Los nombres de los ejes proporcionan el significado. Ninguno de los dos hechos sustituye al otro.
Una dirección, seguida hasta llegar a un valor
Usa el siguiente tensor de dos lotes. Cada elemento del lote contiene tres filas de tokens y cada token tiene cuatro valores de características.
| Token | Característica 1 | Característica 2 | Característica 3 | Característica 4 |
|---|---|---|---|---|
| 1 | 0.2 | 0.8 | -0.1 | 0.4 |
| 2 | 1.1 | -0.3 | 0.5 | 0.0 |
| 3 | 0.7 | 0.6 | 0.2 | -0.4 |
| Token | Característica 1 | Característica 2 | Característica 3 | Característica 4 |
|---|---|---|---|---|
| 1 | -0.2 | 0.9 | 0.3 | 0.1 |
| 2 | 0.4 | -0.7 | 1.2 | 0.5 |
| 3 | 0.8 | 0.1 | -0.6 | 1.5 |
Esta lectura paso a paso importa más que memorizar un orden de letras. Otro proyecto podría almacenar los tokens antes que los lotes o usar ejes de altura, anchura y canal para imágenes. El código y la documentación deben declarar el contrato.
NumPy empieza en cero
Muchos textos de matemáticas etiquetan las posiciones empezando en 1. Python y NumPy utilizan indexación basada en cero, así que la primera posición es 0. La guía oficial de indexación de NumPy también confirma que un entero por dimensión selecciona un elemento y que el índice no negativo válido para un eje de tamaño satisface .
| Posición prevista | Matemáticas basadas en uno | NumPy basado en cero |
|---|---|---|
| Elemento 2 del lote | b = 1 | |
| Token 3 | t = 2 | |
| Característica 1 | f = 0 | |
| Dirección completa | X[1, 2, 0] |
Este es el tensor completo y varias selecciones verificadas:
import numpy as np
X = np.array([
[[ 0.2, 0.8, -0.1, 0.4],
[ 1.1, -0.3, 0.5, 0.0],
[ 0.7, 0.6, 0.2, -0.4]],
[[-0.2, 0.9, 0.3, 0.1],
[ 0.4, -0.7, 1.2, 0.5],
[ 0.8, 0.1, -0.6, 1.5]],
])
print("shape:", X.shape)
print("one activation:", X[1, 2, 0])
print("last token of example 2:", X[1, 2])
print("feature 1 of every last token:", X[:, 2, 0])
shape: (2, 3, 4)
one activation: 0.8
last token of example 2: [ 0.8 0.1 -0.6 1.5]
feature 1 of every last token: [0.7 0.8]
Los dos puntos de X[:, 2, 0] significan «conserva todas las posiciones de este eje». El primer eje permanece, mientras que token y característica reciben índices específicos, así que el resultado contiene un valor por cada uno de los dos elementos del lote.
El atributo shape informa de (2, 3, 4), pero la tupla por sí sola no dice «lote, token, característica». Esos nombres proceden del contrato de datos del programa.
Una dirección legal aún puede expresar la pregunta equivocada
Volvamos a las expresiones iniciales:
X[1, 2, 0] # 0.8: batch 2, token 3, feature 1
X[1, 0, 2] # 0.3: batch 2, token 1, feature 3
Ambas direcciones encajan en la forma. NumPy no puede saber que la segunda línea intercambió los significados de token y característica. Es un error de indexación semántico: el programa recupera una entrada real, pero no la que pretendía el cálculo.
Entre las defensas útiles están anotar el contrato de ejes junto al tensor, comprobar la forma en los límites y asignar nombres descriptivos a las variables de índice:
batch_index = 1
token_index = 2
feature_index = 0
activation = X[batch_index, token_index, feature_index]
assert X.shape == (2, 3, 4)
assert activation == 0.8
La aserción comprueba este ejemplo. Las variables descriptivas conservan el razonamiento que llevó a la dirección.
Los errores de límites son más seguros que los errores silenciosos de ejes
Para la forma basada en cero (2, 3, 4), la última dirección no negativa es X[1, 2, 3]. X[2, 0, 0] no es válida porque el índice de lote 2 pediría un tercer elemento de un eje que solo contiene dos. NumPy lanza IndexError en lugar de devolver un valor inventado.
Los índices negativos son una convención de Python: -1 selecciona la última posición de un eje, así que X[-1, -1, -1] es otra forma de leer X[1, 2, 3]. Es código válido, pero no debe traducirse silenciosamente a un subíndice matemático basado en uno. Declara la convención siempre que la distinción importe.
La próxima lección utilizará estas direcciones dentro de sumas. Cuando signifique claramente el -ésimo ejemplo y su pérdida, un símbolo como se convierte en una instrucción compacta para visitar cada pérdida indexada y combinar los valores.
Comprueba lo que has entendido
Pregunta 1
Si x₄ = (2.5, −1.0, 0.3), ¿a qué se refieren x₄ y x₄,₂?
Mostrar la solución paso a paso
Primero, lee el número de subíndices.
- tiene un índice, así que selecciona el ejemplo completo de la posición 4.
- El ejemplo dado es el valor de tres coordenadas .
- añade un índice de coordenada, así que selecciona la coordenada 2 dentro de ese ejemplo.
Por tanto,
El subíndice 4 es una dirección; no es el valor almacenado.
Pregunta 2
Usa la visualización para calcular X₂,₂,₃. Muestra cada elección de eje.
Mostrar la solución paso a paso
Sigue los índices en el orden lote-token-característica declarado.
- elige el elemento 2 del lote.
- elige su segunda fila de tokens: .
- elige la tercera coordenada de esa fila.
Así,
Elegir la característica 3 antes que el token 2 cambiaría la pregunta porque los ejes están ordenados.
Pregunta 3
Traduce la dirección matemática basada en uno X₂,₃,₄ a NumPy basado en cero y encuentra su valor.
Mostrar la solución paso a paso
Resta 1 a cada posición al pasar de la convención basada en uno indicada a NumPy:
Por tanto, la dirección de código es X[1, 2, 3]. En el elemento 2 del lote, el token 3 es y la característica 4 es . Por tanto,
Pregunta 4
Para un tensor basado en cero con forma (2, 3, 4), clasifica X[0, 2, 3], X[1, 3, 0] y X[2, 0, 0] como dentro o fuera de los límites.
Mostrar la solución paso a paso
Traduce la forma a rangos no negativos válidos:
X[0, 2, 3]está dentro de los límites porque cada índice pertenece a su rango.X[1, 3, 0]está fuera de los límites porque el índice de token 3 no está en .X[2, 0, 0]está fuera de los límites porque el índice de lote 2 no está en .
El primer eje que falla basta para que NumPy rechace la dirección completa.
Pregunta 5
Un desarrollador pretende el lote 2, token 3 y característica 1, pero escribe X[1, 0, 2]. ¿Por qué no se produce un error de límites y cómo debe repararse la línea?
Mostrar la solución paso a paso
Para la forma (2, 3, 4), los índices (1, 0, 2) son mecánicamente válidos:
Por tanto, NumPy devuelve el valor del lote 2, token 1 y característica 3, que es . La biblioteca no puede inferir los significados de eje pretendidos.
Convierte las posiciones basadas en uno previstas a posiciones basadas en cero $(1,2,0)`. La línea reparada es:
activation = X[1, 2, 0] # 0.8Es un error semántico, no un error de límites, por lo que los nombres descriptivos de variables y un contrato explícito de ejes son defensas útiles.
Pregunta 6
¿Qué selecciona X[-1, -1, -1] y por qué −1 no es una identidad permanente para ese valor?
Mostrar la solución paso a paso
En NumPy, -1 significa «la última posición de este eje». Para la forma (2, 3, 4), las últimas posiciones basadas en cero son (1, 2, 3). Por tanto,
El significado depende de la forma y el orden actuales. Si se añadiera otro elemento del lote o token, -1 apuntaría a otro sitio. Es una dirección relativa, no un identificador estable asociado al valor almacenado.