Scalaires, vecteurs, matrices, tenseurs
Prérequis : bloc DL 1.1 · Notions : dimension, shape, indexation, reshape, transposition, opérations élément par élément, broadcasting
Toutes les données d'un réseau de neurones (images, sons, textes, poids) sont stockées dans des tableaux de nombres. Ce qui distingue ces tableaux, c'est leur nombre d'axes, qu'on appelle le rang (ou l'ordre), et leur forme (shape), qui donne la taille de chaque axe.
| Objet | Rang | Notation | Shape | Exemple concret |
|---|---|---|---|---|
| Scalaire | 0 | () | une température : 21,5 | |
| Vecteur | 1 | (n,) | les 3 notes d'un élève | |
| Matrice | 2 | (m, n) | une image en niveaux de gris | |
| Tenseur | 3+ | (d₁, d₂, …) | un lot d'images couleur |
L'élément A[0, 1] correspond à
Les conventions du deep learning
Le premier axe est presque toujours le batch (le lot d'exemples traités ensemble). Formes typiques à connaître par cœur :
- Données tabulaires :
(B, F), B exemples, F caractéristiques. - Images (PyTorch) :
(B, C, H, W), canaux (3 pour RVB), hauteur, largeur. - Texte dans un Transformer :
(B, T, D), T jetons (tokens) de dimension D. - Audio brut :
(B, canaux, échantillons); un spectrogramme :(B, fréquences, trames).
Le nombre total d'éléments est le produit des tailles : un tenseur (32, 3, 64, 64) contient
Opérations de base
Reshape : réorganiser les mêmes éléments dans une autre forme, sans en changer l'ordre de lecture (ligne par ligne). Une image (28, 28) devient un vecteur (784,). Condition : le produit des tailles doit rester identique.
Transposition : échanger lignes et colonnes,
Opérations élément par élément :
Réductions : somme, moyenne, max le long d'un axe. x.sum(axis=0) fait disparaître l'axe 0.
Le broadcasting, règle par règle
Comment additionner une matrice (4, 3) et un vecteur (3,) ? NumPy et PyTorch « étirent » virtuellement le plus petit. Règle exacte : on aligne les formes par la droite ; deux tailles sont compatibles si elles sont égales ou si l'une vaut 1 ; un axe manquant à gauche compte comme 1 ; l'axe de taille 1 est recopié.
C'est exactement ce qui se passe quand on ajoute le biais (4,) + (4, 1) donne (4, 4), pas (4,).
MNIST. Une image de chiffre manuscrit fait 28×28 pixels en niveaux de gris : une matrice (28, 28). Un réseau dense (bloc DL 10.2) attend un vecteur : on aplatit en (784,) car (64, 784).
Normalisation : les pixels valent de 0 à 255 ; on divise tout le tenseur par 255 (un scalaire, broadcasté sur les 50 176 éléments) pour obtenir des valeurs dans [0, 1].
Une table de mixage. Tu enregistres 8 pistes, chacune en stéréo, 4 secondes à 48 000 Hz. Le tenseur brut : (8, 2, 192000), soit 3 072 000 nombres. Tu veux baisser chaque piste d'un gain différent : un vecteur (8,). Pour le broadcaster, il faut le mettre en forme (8, 1, 1) : chaque gain est alors recopié sur les 2 canaux et les 192 000 échantillons de sa piste. Si tu oublies et écris gains[:, None] → (8, 1), NumPy aligne par la droite : (8, 1) contre (2, 192000)… et lève une erreur. La lecture des formes est la première compétence de débogage en deep learning.
- Crée un lot de 16 images RVB 32×32 aléatoires. Affiche sa forme et son nombre d'éléments.
- Aplatis chaque image (sans mélanger les images entre elles) pour obtenir
(16, 3072). - Calcule la moyenne de chaque canal sur tout le lot (résultat
(3,)) et soustrais-la par broadcasting. - Vérifie le piège
(4,) + (4, 1).
Solution commentée
import numpy as np
rng = np.random.default_rng(1)
X = rng.random((16, 3, 32, 32)) # (B, C, H, W)
print(X.shape, X.size) # (16, 3, 32, 32) 49152
assert X.size == 16 * 3 * 32 * 32
flat = X.reshape(16, -1) # -1 : "calcule cette taille toi-même"
assert flat.shape == (16, 3072)
assert np.allclose(flat[5], X[5].ravel()) # l'image 5 reste l'image 5
moy = X.mean(axis=(0, 2, 3)) # on réduit batch, H, W -> reste C
assert moy.shape == (3,)
Xc = X - moy[None, :, None, None] # (3,) -> (1, 3, 1, 1) pour aligner sur C
assert np.allclose(Xc.mean(axis=(0, 2, 3)), 0) # chaque canal est centré
a = np.arange(4) # (4,)
b = np.arange(4)[:, None] # (4, 1)
print((a + b).shape) # (4, 4) : le piège !
assert (a + b).shape == (4, 4)
À retenir
- Rang = nombre d'axes ; shape = taille de chaque axe ; le premier axe est le batch.
- Reshape conserve l'ordre de lecture ; transposition échange les axes.
- Broadcasting : aligner par la droite, tailles égales ou 1.
- Toujours écrire les formes en commentaire quand on code un réseau.