## Les fonctions d'activation en détail

Les fonctions d'activation sont les interrupteurs du réseau : elles décident si le signal d'un neurone est assez fort pour être transmis à la couche suivante, tout en tordant la réalité mathématique pour modéliser des courbes plutôt que de simples lignes droites.

Les fonctions d'activation agissent comme des interrupteurs ou des variateurs, dictant la dynamique de transmission du signal au sein du réseau [@DeeplyLearning_Activation; @Daniella2024]. Elles sont le cœur de la non-linéarité et se divisent en deux grandes familles.

* **Les fonctions classiques et leurs limitations :**
  * **Sigmoïde & TanH :** Courbes en "S" d'inspiration biologique. Elles saturent aux valeurs extrêmes, ce qui paralyse l'apprentissage en bloquant le gradient [@RisingScholars_Sigmoid].
  * **ReLU (Rectified Linear Unit) :** Simple et rapide ($\max(0, x)$), elle évite la saturation positive mais souffre du "Dying ReLU" (extinction définitive de neurones) [@Youtube_NonLinearite; @CS231n_Part1; @Ultralytics_LeakyReLU].
  * **Softmax :** Utilisée en sortie pour convertir des scores bruts en distribution de probabilités sur des classes mutuellement exclusives [@Ultralytics_Softmax].

::: {.callout-note collapse="true"}
## 🔍 Détails et Limites des Fonctions Classiques

* **Saturation du Gradient :** Pour de très grandes ou très petites valeurs de $x$, la dérivée de Sigmoïde et TanH tend vers $0$. Lors de la rétropropagation, ce terme multiplicatif annule le gradient, empêchant la mise à jour des poids précédents.
* **Problème du "Dying ReLU" :** Si un neurone ReLU reçoit une entrée négative, son gradient est nul. Si ce cas se généralise (poids mal initialisés ou taux d'apprentissage trop élevé), le neurone s'éteint définitivement.
:::

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

:::: {.card-header}
⚡ Simulateur des Fonctions d'Activation Classiques
::::

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

```{ojs}
//| echo: false
viewof x_classic = Inputs.range([-5, 5], { value: 0, step: 0.1, label: "Valeur de x" })
```

::::

:::: {.row .g-3 .px-3 .pb-2}

::::: {.col-md-7}
:::::: {.card .border .m-0}
::::::: {.card-header .font-monospace .text-uppercase .text-muted .py-2 .small}
📈 Courbes d'Activation
:::::::
::::::: {#classic-plotly-container .card-body .p-2 .activation-chart-wrapper}
:::::::
::::::
:::::

::::: {.col-md-5}
:::::: {#classic-vars-container .list-group .m-0}
::::::
:::::

::::

:::

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

_updateClassic = {
  updateClassicActivation(x_classic, {
    chartEl: document.getElementById("classic-plotly-container"),
    varsEl:  document.getElementById("classic-vars-container")
  });
}
```

* **Les fonctions modernes :**

  Ces fonctions plus récentes (comme GELU ou Swish) évitent les pannes sèches en laissant passer une petite partie du signal négatif de manière plus fluide.

  * **GELU (Gaussian Error Linear Unit) :** Fonction probabiliste douce pondérant le signal négatif, pilier des Transformers car elle maintient un flux de gradient fluide [@Youtube_GELU; @Wiki_Transformeur; @Cortial_OpenStudio].
  * **SELU (Scaled Exponential Linear Unit) :** Conçue pour introduire des propriétés auto-normalisantes, permettant aux réseaux profonds de converger sans normalisation externe [@PlanificationLR; @Stanford_CS230].
  * **Swish :** Version lissée de ReLU qui laisse passer les petites valeurs négatives pour éviter les coupures abruptes [@Lim2026].

::: {.callout-note collapse="true"}
## 🔍 Fonctionnement des Activations Modernes

* **GELU et Probabilité :** Elle multiplie l'entrée $x$ par la fonction de répartition d'une loi normale standard $\Phi(x)$. Le neurone est donc activé de manière déterministe mais selon son importance probabiliste relative.
* **Auto-normalisation (SELU) :** En combinant un facteur d'échelle $\lambda$ et un paramètre $\alpha$ sur une fonction ELU, SELU garantit que si la moyenne et la variance des activations d'une couche sont proches de $0$ et $1$, elles le restent après passage dans la couche suivante.
:::

::: {.callout-note collapse="true"}
## 🔢 Formule de l'activation Swish

La fonction Swish s'écrit :

$$f(x) = x \cdot \text{sigmoid}(\beta x) = \frac{x}{1 + e^{-\beta x}}$$

Où $\beta$ est un paramètre constant ou entraînable. Lorsque $\beta = 1$, la fonction est également appelée SiLU (Sigmoid Linear Unit).
:::

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

:::: {.card-header}
✨ Simulateur des Fonctions d'Activation Modernes
::::

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

```{ojs}
//| echo: false
viewof x_modern = Inputs.range([-3, 3], { value: 0, step: 0.1, label: "Valeur de x" })
```

::::

:::: {.row .g-3 .px-3 .pb-2}

::::: {.col-md-7}
:::::: {.card .border .m-0}
::::::: {.card-header .font-monospace .text-uppercase .text-muted .py-2 .small}
📈 Courbes d'Activation (Modernes)
:::::::
::::::: {#modern-plotly-container .card-body .p-2 .activation-chart-wrapper}
:::::::
::::::
:::::

::::: {.col-md-5}
:::::: {#modern-vars-container .list-group .m-0}
::::::
:::::

::::

:::

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

_updateModern = {
  updateModernActivation(x_modern, {
    chartEl: document.getElementById("modern-plotly-container"),
    varsEl:  document.getElementById("modern-vars-container")
  });
}
```