La placa recibe todos los datos. ¿Por qué cambia la respuesta?
Una cámara entrega una imagen: el número de píxeles es correcto, el búfer conserva todos los bytes y no falta ningún valor. Sin embargo, el primer cálculo difiere del esperado. Antes de culpar al acelerador o reentrenar, preguntemos si los tres números interpretados como canales de un píxel pertenecen realmente a él. Desarrollamos un caso mínimo donde las dimensiones pasan la comprobación, pero cambia el significado.
Separamos cambiar dimensiones, permutar ejes y hacer contigua la memoria. Es un análisis didáctico ejecutado en un ordenador con Python 3.14.0 y NumPy 2.5.3, no una prueba de microcontrolador ni de producto EL-AI. No medimos latencia, energía ni precisión de una red entrenada. Un filtro lineal permite comprobar cada paso sin esconderlo entre miles de pesos.
Una imagen es una tabla con varias coordenadas
Un tensor es aquí una colección de números con varias coordenadas. N cuenta imágenes, H es altura, W anchura y C canales. NHWC ordena imagen, fila, columna y canal; NCHW coloca el canal antes de las coordenadas espaciales. Pueden representar la misma imagen, siempre que y[n, c, h, w]=x[n, h, w, c] para cada coordenada válida. Igualar el número de elementos no basta.
La imagen tiene dos filas, dos columnas y tres canales sintéticos: (1,10,100), (2,20,200), (3,30,300), (4,40,400). Los valores distintos revelan intercambios. No es una foto RGB de ocho bits: 400 supera 255, por lo que usamos int16, dos bytes por elemento. Sus 12 elementos ocupan 24 bytes de contenido numérico, sin contar metadatos de Python, asignador ni otros búferes.
Cambiar la forma no cambia el orden
Con orden C predeterminado, reshape(1,3,2,2) coloca la secuencia en la nueva forma haciendo variar más rápido el último índice. La secuencia sigue siendo 1,10,100,2,20,200,3,30,300,4,40,400. El primer canal queda [1,10,100,2], en vez de [1,2,3,4]. Las dimensiones encajan, pero se mezclan píxeles y canales. NumPy documenta el orden de indexación, no una conversión semántica de formatos de imagen.
En cambio, transpose(0,3,1,2) asigna el nuevo eje 0 al antiguo 0, el nuevo 1 al antiguo 3, etcétera, preservando las coordenadas deseadas. En este experimento devuelve una vista que comparte el almacenamiento sin copiar contenido en ese paso. No afirmamos lo mismo de todas las bibliotecas o dispositivos. El acceso lógico difiere de la disposición física: una vista NumPy lleva información que una interfaz con solo un puntero podría no recibir.
¿Dónde quedan realmente los bytes?
Primero calculamos desplazamientos para arrays contiguos, con b=2 bytes por elemento e índices desde cero. El desplazamiento mide bytes desde el inicio, no una dirección absoluta. El formato decide qué índice cambia más rápido. Una vista no contigua necesita sus strides reales: desplazamientos en bytes al incrementar cada índice, no solo estas fórmulas contiguas.
Los strides de entrada son (24,12,6,2) bytes; los de la vista NCHW, (24,2,12,6). Avanzar un canal mueve dos bytes y una columna, seis. La copia NCHW contigua tiene (24,8,4,2): cuatro elementos por plano. ascontiguousarray sobre la vista crea esa copia correcta. Sobre el reshape erróneo no reconstruye los píxeles: conserva el error semántico. Aquí el reshape equivocado y la copia correcta incluso comparten strides, pero no valores en las mismas coordenadas.
Un filtro comprobable a mano
El filtro pondera los canales con 1,2,3 y suma por píxel, sin activación, normalización ni sesgo. El primer píxel correcto da 1+2·10+3·100=321. En el reshape esa posición contiene 1,20,300: da 1+40+900=941. No es redondeo: se multiplican otros datos. Acumulamos en int64 para no confundir este problema con desbordamiento de enteros.
| Píxel | Correcto | Reshape |
|---|---|---|
| (0,0) | 321 | 941 |
| (0,1) | 642 | 422 |
| (1,0) | 963 | 226 |
| (1,1) | 1284 | 1262 |

La suma pasa de 3210 a 2851, pero conservarla tampoco bastaría: permutar posiciones puede preservar la suma y alterar el mapa. Un array de unos oculta el error: cualquier grupo da 1+2+3=6, contraejemplo verificado en el código. Las imágenes uniformes pueden tranquilizar falsamente; hacen falta valores distintos, comparación por coordenada y referencia conocida antes de convertir.
Qué garantiza la prueba y qué falta en la placa
El experimento comprueba las doce correspondencias, la permutación inversa, igualdad de la copia y memoria compartida. La permutación lógica cambia metadatos; materializar M elementos exige leerlos y escribirlos, trabajo proporcional a M y otro búfer en este caso. Los 24 bytes describen contenido, no RAM máxima del proceso: vistas compartidas y copias difieren. No inferimos tiempo ni potencia de esos conteos.
En el dispositivo falta comprobar el contrato exacto del runtime: ejes, tipo, contigüidad, strides admitidos, vida del búfer y preprocesamiento. Convertir NHWC/NCHW no intercambia rojo y azul, redimensiona ni normaliza automáticamente. “Copiar siempre” no es una regla universal: una copia innecesaria consume memoria y omitir una requerida cambia la lectura. La alternativa depende del contrato y necesita medidas en la plataforma real.
La respuesta: contar bytes no basta
Los mismos números dan resultados erróneos porque el modelo lee significado por coordenada, no una colección sin orden. El caso separa tres garantías: reshape adapta una forma, transpose preserva ejes y una copia contigua satisface una disposición física. Ninguna sustituye automáticamente a las demás. Hacer explícita y comprobable esa correspondencia antes de optimizar evita culpar al entrenamiento por un error de interfaz.
Fuentes y material ejecutado
NumPy 2.5 — reshape: indexing order, views and copies.
NumPy 2.5 — transpose: axis correspondence.
NumPy 2.5 — ascontiguousarray: contiguous shape and content.
import numpy as np
x=np.array([[[[1,10,100],[2,20,200]],[[3,30,300],[4,40,400]]]],dtype=np.int16)
y=x.transpose(0,3,1,2)
z=x.reshape(1,3,2,2)
w=np.array([1,2,3],dtype=np.int64)[None,:,None,None]
print((y.astype(np.int64)*w).sum(axis=1))
print((z.astype(np.int64)*w).sum(axis=1))
assert np.array_equal(y.transpose(0,2,3,1),x)
Código, datos e instrucciones · JSON. Cálculos didácticos ejecutados con Python 3.14.0; figuras con Matplotlib 3.11.2. Análisis asistido por IA, sin afirmar revisión por pares ni humana. Portada original ImageGen ilustrativa: no documenta personas, sedes ni instalaciones de EL-AI. Fuentes consultadas el 24 de octubre de 2026.

