## Propagation avant (Forward Propagation)

La propagation avant est le voyage aller des données à travers le réseau : elles entrent sous forme brute d'un côté (comme les pixels d'une image), sont transformées à chaque étape par les calculs des neurones, et ressortent de l'autre côté sous forme de prédiction (comme le nom de l'objet sur l'image).

La propagation avant constitue le flux tensorial unidirectionnel qui transforme une entrée brute en une prédiction [@Innovatiana_Forward]. C'est la phase d'inférence pure, où le réseau déploie sa structure et sa compréhension acquise pour interpréter de nouvelles activations.

* **Le processus de sommation pondérée :** À chaque couche, les neurones reçoivent les activations de la couche précédente. Le réseau calcule systématiquement les produits scalaires entre les poids et ces activations pour obtenir la combinaison linéaire avant l'étape de filtrage [@Bodin_Recher_2] : $h = \sum_{i} w_i x_i + b$.

### Formalisme vectoriel et vectorisation

Pour tirer parti de l'accélération matérielle des GPU, on reformule ces calculs individuels sous forme matricielle. L'ensemble d'une couche se calcule en une seule opération, ce qui permet aux GPU d'effectuer des milliers de calculs en parallèle et rend l'entraînement de réseaux profonds faisable [@Nielsen_2019].

::: {.callout-note collapse="true"}
## 🔢 Formule matricielle de la propagation avant

Le calcul vectorisé pour une couche $l$ s'écrit :

$$
\mathbf{a}^l = \sigma\!\left(\mathbf{W}^l \mathbf{a}^{l-1} + \mathbf{b}^l\right)
$$ ([voir le Glossaire](../../glossaire.qmd#symboles-mathématiques-notations))

* **Lettres grasses** (ex: $\mathbf{a}, \mathbf{W}, \mathbf{b}$) : désignent des tenseurs (vecteurs ou matrices) plutôt que des nombres isolés (scalaires).
* **L'exposant $l$** (ex: $\mathbf{a}^l$) : indique la couche du réseau de neurones à laquelle la variable appartient.
* **$\mathbf{a}^l$** : le vecteur d'activations de la couche $l$.
* **$\mathbf{W}^l \in \mathbb{R}^{n_l \times n_{l-1}}$** : la matrice des poids de la couche $l$.
  * Le symbole $\in$ signifie **"appartient à"**.
  * $\mathbb{R}^{n_l \times n_{l-1}}$ représente l'espace des matrices de nombres réels à $n_l$ lignes (nombre de neurones de la couche $l$) et $n_{l-1}$ colonnes (nombre de neurones de la couche précédente $l-1$).
* **$\mathbf{a}^{l-1}$** : le vecteur d'activations de la couche précédente $l-1$ (la couche $\mathbf{a}^0$ correspondant à l'entrée $\mathbf{x}$).
* **$\mathbf{b}^l$** : le vecteur des biais de la couche $l$.
* **$\sigma$** (lettre grecque *sigma*) : la fonction d'activation, appliquée élément par élément sur le vecteur de pré-activation.
:::

* **L'impératif de la non-linéarité :** Appliquer une fonction d'activation non linéaire empêche le réseau de s'effondrer mathématiquement en une simple régression linéaire [@Youtube_NonLinearite; @Maths_IA]. Cette non-linéarité lui permet de modéliser les motifs complexes et les ruptures de la réalité.
* **La transformation progressive des données :** À travers ce chaînage alterné d'opérations, les données transitent d'un état brut (ex: pixels) à des représentations abstraites de plus en plus sémantiques jusqu'à la sortie finale [@Cloudflare_Inference].

::: {.card .card-window .mb-4}

:::: {.card-header}
⚡ Simulateur — Propagation Avant couche par couche
::::

:::: {.card-control-row .sim-controls-row}

```{ojs}
//| echo: false
viewof fp_x1 = Inputs.range([-2, 2], { value: 1.0, step: 0.1, label: "Entrée x₁" })
viewof fp_x2 = Inputs.range([-2, 2], { value: -0.5, step: 0.1, label: "Entrée x₂" })
```

::::

:::: {.card-body .p-2}

::::: {#forward-pass-container .p-1}
:::::

::::

:::

```{ojs}
//| echo: false
import { updateForwardPassViz } from "../../assets/js/simulations/neuron.js"

_forwardPass = {
  updateForwardPassViz(document.getElementById("forward-pass-container"), { x1: fp_x1, x2: fp_x2 });
}
```