Introduction aux réseaux de neurones artificiels

CSI 4506 - automne 2026

Marcel Turcotte

Version : 20 oct. 2026 15h33

Préambule

Message du jour

Message du jour

Message du jour (suite)

Message du jour (2024)

Objectifs d’apprentissage

  • Expliquer comment les poids, les biais et les activations déterminent le calcul de propagation avant d’un réseau.
  • Expliquer pourquoi des couches cachées avec des activations non linéaires peuvent représenter XOR.
  • Comparer la forme et l’ensemble des valeurs de sortie de la sigmoïde, de tanh et de ReLU.
  • Énoncer les hypothèses et les limites du théorème d’approximation universelle.
  • Construire et évaluer un classificateur Keras sur Fashion-MNIST avec un prétraitement cohérent et des ensembles d’entraînement, de validation et de test distincts.

Introduction

TensorFlow Playground

Réseaux de neurones (NN)

Les réseaux de neurones artificiels sont des modèles d’apprentissage automatique composés d’unités de calcul interconnectées, inspirées des neurones biologiques.

  • Calcul : avec des paramètres fixés, un réseau associe des sorties aux entrées.
  • Apprentissage : l’entraînement utilise des exemples pour ajuster les paramètres.

Problèmes d’apprentissage automatique

  • Apprentissage supervisé : classification, régression

  • Apprentissage non supervisé : autoencodeurs, apprentissage autosupervisé (self-supervised learning)

  • Apprentissage par renforcement : les réseaux y occupent désormais une place importante

Un neurone

Neurones interconnectés

Neural Mind

Lakoff et Narayanan (2025)

Les neurones ne sont que des cellules. Seuls, ils sont incapables de penser. Mais, réunis en circuits reliés à notre corps de manière appropriée, ils ont permis aux êtres humains de survivre, de penser, de communiquer et de créer toute la culture.

Connexionnisme

Hiérarchie des concepts

Notions de base

Calcul avec des unités à seuil

où x_1, x_2 \in \{0,1\} et f(z) est une fonction de seuil (step function) :

f(z)= \begin{cases}0, & z<\theta \\ 1, & z \geq \theta\end{cases}

Calcul avec des unités à seuil

f(x_1 + x_2)= \begin{cases}0, & x_1 + x_2 <\theta \\ 1, & x_1 + x_2 \geq \theta\end{cases}

  • Avec \theta = 2, l’unité réalise une porte logique ET.

  • Avec \theta = 1, l’unité réalise une porte logique OU.

Les réseaux calculent des fonctions

  • Des réseaux d’unités à seuil peuvent réaliser des fonctions booléennes en composant des opérations logiques.

  • Lorsque les connexions et les seuils sont fixés, le réseau effectue un calcul déterminé.

  • L’apprentissage pose une autre question : comment les données peuvent-elles déterminer les paramètres?

Perceptron

Perceptron

Unité logique à seuil

Fonctions de seuil simples

\text{Heaviside}(t) =

  • 1, si t \geq 0

  • 0, si t < 0

\text{sign}(t) =

  • 1, si t > 0

  • 0, si t = 0

  • -1, si t < 0

Notation

Notation

Perceptron

Perceptron

Notation

Notation

  • X est la matrice des données d’entrée : chaque ligne correspond à un exemple et chaque colonne représente l’un des D attributs.

  • W est la matrice des poids, avec une ligne par entrée (attribut) et une colonne par neurone.

  • Les biais peuvent être représentés séparément; les deux approches existent dans la littérature. Ici, b est un vecteur dont la longueur est égale au nombre de neurones.

Du calcul à l’apprentissage

  • La propagation avant utilise les poids et les biais actuels pour produire une prédiction.
  • L’entraînement ajuste ces paramètres à partir d’exemples et de leurs sorties cibles.
  • Le perceptron de Rosenblatt a marqué ce passage vers l’apprentissage à partir des données.

Une limite : XOR

Composition de portes logiques

Au moins une entrée est vraie, et elles ne sont pas toutes les deux vraies :

A\oplus B=(A\lor B)\land\neg(A\land B)

  • OU détecte si au moins une entrée est vraie.
  • ET détecte si les deux entrées sont vraies.
  • La combinaison de leurs sorties donne XOR.

Perceptron multicouche

XOR : calculs intermédiaires

A B Cible y o_1 : ET o_2 : OU o_3 : XOR
0 0 0 0 0 0
0 1 1 0 1 1
1 0 1 0 1 1
1 1 0 1 1 0

RN à propagation avant (FNN)

Somme pondérée et activation

Chaque unité de calcul effectue deux opérations :

z_j=\sum_{i\to j} w_{i,j}o_i+b_j, \qquad o_j=\varphi(z_j).

  • z_j : somme pondérée plus biais, avant l’activation.
  • o_j : sortie de l’unité, après application de l’activation \varphi.

Propagation avant (calcul)

o_3 = \sigma(w_{1,3}x^{(1)}+w_{2,3}x^{(2)}+b_3)

o_4 = \sigma(w_{1,4}x^{(1)}+w_{2,4}x^{(2)}+b_4)

o_5 = \sigma(w_{1,5}x^{(1)}+w_{2,5}x^{(2)}+b_5)

o_6 = \sigma(w_{3,6}o_3+w_{4,6}o_4+w_{5,6}o_5+b_6)

o_7 = \sigma(w_{3,7}o_3+w_{4,7}o_4+w_{5,7}o_5+b_7)

Exemple numérique

Code
import numpy as np
from scipy.special import expit as sigmoid

rng = np.random.default_rng(42)
x1, x2 = 0.5, 0.9

w13, w14, w15, w23, w24, w25 = rng.uniform(-1, 1, size=6)
w36, w46, w56, w37, w47, w57 = rng.uniform(-1, 1, size=6)
b3, b4, b5, b6, b7 = np.zeros(5)
z3 = w13 * x1 + w23 * x2 + b3
o3 = sigmoid(z3)
z4 = w14 * x1 + w24 * x2 + b4
o4 = sigmoid(z4)
z5 = w15 * x1 + w25 * x2 + b5
o5 = sigmoid(z5)
z6 = w36 * o3 + w46 * o4 + w56 * o5 + b6
o6 = sigmoid(z6)
z7 = w37 * o3 + w47 * o4 + w57 * o5 + b7
o7 = sigmoid(z7)

(o6, o7)
(np.float64(0.48638976530233274), np.float64(0.6254814695767328))

Propagation avant

Propagation avant avec biais

Pourquoi des activations non linéaires?

  • Les couches cachées transforment leurs entrées en représentations intermédiaires.
  • Sans activation non linéaire entre les couches, leur composition reste une seule transformation affine.
  • Les activations non linéaires permettent au réseau de représenter des relations plus complexes entre les entrées et les sorties.

Activations et entraînement

  • La rétropropagation (backpropagation) calcule les gradients; un optimiseur les utilise pour mettre à jour les paramètres.
  • Les dérivées d’une fonction de seuil discontinue ne fournissent pas de signal utile pour l’entraînement usuel par gradient.
  • Les réseaux modernes utilisent des activations comme la sigmoïde, tanh et ReLU.

Sigmoïde

\sigma(z)=\frac{1}{1+e^{-z}}

Ensemble des valeurs de sortie : (0,1).

Code
import matplotlib.pyplot as plt


def relu(z):
    return np.maximum(0, z)


def plot_activation(activation, name, output_limits):
    z = np.linspace(-6, 6, 400)
    fig, ax = plt.subplots(figsize=(5, 3.5))
    ax.plot(z, activation(z), color="black", linewidth=2)
    ax.set(xlabel="$z$", ylabel="Sortie", title=name, ylim=output_limits)
    ax.grid(True)
    fig.patch.set_alpha(0)
    plt.show()


plot_activation(sigmoid, "Sigmoïde", (-0.1, 1.1))

Tangente hyperbolique (tanh)

\tanh(z)=2\sigma(2z)-1

Ensemble des valeurs de sortie : (-1,1).

Code
plot_activation(np.tanh, "Tanh", (-1.1, 1.1))

Unité linéaire rectifiée (ReLU)

\operatorname{ReLU}(z)=\max(0,z)

Ensemble des valeurs de sortie : [0,\infty).

Code
plot_activation(relu, "ReLU", (-0.5, 6.5))

Comparaison des fonctions d’activation

Code
z = np.linspace(-4, 4, 401)
fig, ax = plt.subplots(figsize=(7, 4))
ax.step(z, (z >= 0).astype(int), where="post", label="Seuil")
ax.plot(z, sigmoid(z), label="Sigmoïde")
ax.plot(z, np.tanh(z), label="Tanh")
ax.plot(z, relu(z), label="ReLU")
ax.set(xlabel="$z$", ylabel="Sortie", ylim=(-1.2, 4.2))
ax.grid(True)
ax.legend()
plt.show()

Approximation universelle

Définition

Le théorème d’approximation universelle (universal approximation theorem, UAT) établit que, sur un domaine d’entrée compact, un réseau ayant une seule couche cachée suffisamment large, des activations sigmoïdes et une sortie linéaire peut approximer toute fonction cible continue donnée avec la précision souhaitée.

Effet de w : sigmoïde

Code
def plot_parameter_effect(activation, name, weights, biases, title):
    x = np.linspace(-10, 10, 400)
    fig, ax = plt.subplots(figsize=(6, 4))
    for w in weights:
        for b in biases:
            ax.plot(x, activation(w * x + b), label=f"w = {w}, b = {b}")
    ax.set(xlabel="$x$", ylabel=f"{name}(wx + b)", title=title)
    ax.grid(True)
    ax.legend()
    plt.show()


plot_parameter_effect(sigmoid, "Sigmoïde", weights=[0.5, 1, 2, 5], biases=[0],
                      title="Variation de w, avec b = 0")

Effet de b : sigmoïde

Code
plot_parameter_effect(
    sigmoid, "Sigmoïde", weights=[1], biases=[-5, -2, 0, 2, 5],
    title="Variation de b, avec w = 1"
)

Effet de w : ReLU

Code
plot_parameter_effect(relu, "ReLU", weights=[0.5, 1, 2, 5], biases=[0],
                      title="Variation de w, avec b = 0")

Effet de b : ReLU

Code
plot_parameter_effect(relu, "ReLU", weights=[1], biases=[-5, -2, 0, 2, 5],
                      title="Variation de b, avec w = 1")

Démonstration par le code

Approximer la même courbe cible avec des réseaux ayant des nombres différents d’unités cachées.

# Définition de la fonction à approximer

def f(x):
    return 2 * x**3 + 4 * x**2 - 5 * x + 1

# Génération des données : x dans [-4,2), avec f(x) définie ci-dessus

approximation_rng = np.random.default_rng(42)
X = approximation_rng.uniform(-4, 2, size=(1000, 1))

y = f(X.flatten())

Augmenter le nombre de neurones

from sklearn.neural_network import MLPRegressor
from sklearn.model_selection import train_test_split

X_train, X_valid, y_train, y_valid = train_test_split(
    X, y, test_size=0.1, random_state=42
)

models = []

sizes = [1, 2, 3, 5, 50]

for n in sizes:
    regressor = MLPRegressor(
        hidden_layer_sizes=(n,), max_iter=5000, random_state=42
    )
    regressor.fit(X_train, y_train)
    models.append(regressor) 

Comparaison des courbes ajustées

Code
colors = plt.colormaps["cool"].resampled(len(sizes))
plot_inputs = np.sort(X_valid, axis=0)

fig, ax = plt.subplots(figsize=(7, 4))
for i, n in enumerate(sizes):
    predictions = models[i].predict(plot_inputs)
    ax.plot(plot_inputs, predictions, color=colors(i),
            label=f"Unités cachées = {n}")
ax.plot(plot_inputs, f(plot_inputs), "r.", label="Cible")
ax.set(xlabel="$x$", ylabel="Sortie")
ax.legend()
plt.show()

Comparaison des pertes d’entraînement

Code
fig, ax = plt.subplots(figsize=(7, 4))
for i, n in enumerate(sizes):
    ax.plot(models[i].loss_curve_, color=colors(i),
            label=f"Unités cachées = {n}")
ax.set(title="Perte d'entraînement", xlabel="Itération", ylabel="Perte")
ax.legend()
plt.show()

Approximation universelle

Codons

Bibliothèques et environnements

PyTorch, TensorFlow et JAX fournissent des outils de calcul numérique et de différentiation automatique.

Keras fournit une API de haut niveau pour construire et entraîner des modèles avec ces moteurs de calcul (backends).

Keras

Les principales étapes sont :

  1. Définir les couches du réseau.
  2. Compiler avec une perte, un optimiseur et des métriques d’évaluation.
  3. Ajuster le modèle aux données d’entraînement et suivre ses performances sur l’ensemble de validation.
  4. Évaluer le modèle sur l’ensemble de test et produire des prédictions.

Jeu de données Fashion-MNIST

Fashion-MNIST contient des images de vêtements et d’accessoires :

  • 60 000 images d’entraînement et 10 000 images de test.
  • Chaque image comporte 28 × 28 pixels en niveaux de gris.
  • Chaque image possède une étiquette entière, parmi 10 classes.

Chargement et partitionnement

import tensorflow as tf

(X_train_full, y_train_full), (X_test, y_test) = (
    tf.keras.datasets.fashion_mnist.load_data()
)

X_train, y_train = X_train_full[:-5000], y_train_full[:-5000]
X_valid, y_valid = X_train_full[-5000:], y_train_full[-5000:]

Inspection et mise à l’échelle des entrées

X_train.shape, X_train.dtype
((55000, 28, 28), dtype('uint8'))

Convertissez les intensités des pixels, des entiers de 0 à 255, en nombres flottants de 0 à 1, dans chaque partition.

X_train = X_train.astype("float32") / 255.0
X_valid = X_valid.astype("float32") / 255.0
X_test = X_test.astype("float32") / 255.0

Images et étiquettes

Code
class_names = ["T-shirt/haut", "Pantalon", "Pull", "Robe", "Manteau",
               "Sandale", "Chemise", "Espadrille", "Sac", "Bottine"]

plt.figure(figsize=(2, 2))
plt.imshow(X_train[0], cmap="binary")
plt.title(class_names[y_train[0]])
plt.axis("off")
plt.show()

Les 40 premières images

Code
fig, axes = plt.subplots(4, 10, figsize=(12, 4.8))
for index, ax in enumerate(axes.flat):
    ax.imshow(X_train[index], cmap="binary", interpolation="nearest")
    ax.set_title(class_names[y_train[index]], fontsize=10)
    ax.axis("off")
plt.tight_layout()
plt.show()

Création d’un modèle

tf.keras.utils.set_random_seed(42)

model = tf.keras.Sequential([
    tf.keras.Input(shape=(28, 28)),
    tf.keras.layers.Flatten(),
    tf.keras.layers.Dense(300, activation="relu"),
    tf.keras.layers.Dense(100, activation="relu"),
    tf.keras.layers.Dense(10, activation="softmax")
])

Structure du modèle et paramètres

model.summary()
Model: "sequential"
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓
┃ Layer (type)                    ┃ Output Shape           ┃       Param # ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩
│ flatten (Flatten)               │ (None, 784)            │             0 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ dense (Dense)                   │ (None, 300)            │       235,500 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ dense_1 (Dense)                 │ (None, 100)            │        30,100 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ dense_2 (Dense)                 │ (None, 10)             │         1,010 │
└─────────────────────────────────┴────────────────────────┴───────────────┘
 Total params: 266,610 (1.02 MB)
 Trainable params: 266,610 (1.02 MB)
 Non-trainable params: 0 (0.00 B)

Compilation du modèle

model.compile(
    loss="sparse_categorical_crossentropy",
    optimizer=tf.keras.optimizers.SGD(learning_rate=0.01),
    metrics=["accuracy"]
)

Entraînement du modèle

history = model.fit(
    X_train, y_train, epochs=30, batch_size=32,
    validation_data=(X_valid, y_valid), verbose=2
)
Epoch 1/30
1719/1719 - 1s - 825us/step - accuracy: 0.7616 - loss: 0.7239 - val_accuracy: 0.8298 - val_loss: 0.5026
Epoch 2/30
1719/1719 - 1s - 669us/step - accuracy: 0.8299 - loss: 0.4894 - val_accuracy: 0.8418 - val_loss: 0.4472
Epoch 3/30
1719/1719 - 1s - 685us/step - accuracy: 0.8448 - loss: 0.4434 - val_accuracy: 0.8480 - val_loss: 0.4233
Epoch 4/30
1719/1719 - 1s - 682us/step - accuracy: 0.8548 - loss: 0.4154 - val_accuracy: 0.8550 - val_loss: 0.4088
Epoch 5/30
1719/1719 - 1s - 673us/step - accuracy: 0.8607 - loss: 0.3951 - val_accuracy: 0.8584 - val_loss: 0.3970
Epoch 6/30
1719/1719 - 1s - 665us/step - accuracy: 0.8667 - loss: 0.3790 - val_accuracy: 0.8594 - val_loss: 0.3889
Epoch 7/30
1719/1719 - 1s - 673us/step - accuracy: 0.8713 - loss: 0.3656 - val_accuracy: 0.8616 - val_loss: 0.3824
Epoch 8/30
1719/1719 - 1s - 677us/step - accuracy: 0.8748 - loss: 0.3539 - val_accuracy: 0.8642 - val_loss: 0.3780
Epoch 9/30
1719/1719 - 1s - 680us/step - accuracy: 0.8783 - loss: 0.3432 - val_accuracy: 0.8666 - val_loss: 0.3740
Epoch 10/30
1719/1719 - 1s - 690us/step - accuracy: 0.8817 - loss: 0.3336 - val_accuracy: 0.8678 - val_loss: 0.3684
Epoch 11/30
1719/1719 - 1s - 674us/step - accuracy: 0.8851 - loss: 0.3247 - val_accuracy: 0.8702 - val_loss: 0.3641
Epoch 12/30
1719/1719 - 1s - 678us/step - accuracy: 0.8875 - loss: 0.3165 - val_accuracy: 0.8726 - val_loss: 0.3601
Epoch 13/30
1719/1719 - 1s - 664us/step - accuracy: 0.8898 - loss: 0.3089 - val_accuracy: 0.8736 - val_loss: 0.3578
Epoch 14/30
1719/1719 - 1s - 670us/step - accuracy: 0.8922 - loss: 0.3017 - val_accuracy: 0.8724 - val_loss: 0.3554
Epoch 15/30
1719/1719 - 1s - 667us/step - accuracy: 0.8942 - loss: 0.2951 - val_accuracy: 0.8736 - val_loss: 0.3543
Epoch 16/30
1719/1719 - 1s - 667us/step - accuracy: 0.8962 - loss: 0.2887 - val_accuracy: 0.8734 - val_loss: 0.3520
Epoch 17/30
1719/1719 - 1s - 674us/step - accuracy: 0.8983 - loss: 0.2829 - val_accuracy: 0.8738 - val_loss: 0.3522
Epoch 18/30
1719/1719 - 1s - 692us/step - accuracy: 0.9002 - loss: 0.2771 - val_accuracy: 0.8746 - val_loss: 0.3495
Epoch 19/30
1719/1719 - 1s - 684us/step - accuracy: 0.9021 - loss: 0.2717 - val_accuracy: 0.8758 - val_loss: 0.3478
Epoch 20/30
1719/1719 - 1s - 697us/step - accuracy: 0.9043 - loss: 0.2664 - val_accuracy: 0.8760 - val_loss: 0.3465
Epoch 21/30
1719/1719 - 1s - 665us/step - accuracy: 0.9060 - loss: 0.2615 - val_accuracy: 0.8754 - val_loss: 0.3465
Epoch 22/30
1719/1719 - 1s - 669us/step - accuracy: 0.9081 - loss: 0.2565 - val_accuracy: 0.8772 - val_loss: 0.3449
Epoch 23/30
1719/1719 - 1s - 686us/step - accuracy: 0.9102 - loss: 0.2519 - val_accuracy: 0.8782 - val_loss: 0.3454
Epoch 24/30
1719/1719 - 1s - 666us/step - accuracy: 0.9121 - loss: 0.2471 - val_accuracy: 0.8780 - val_loss: 0.3445
Epoch 25/30
1719/1719 - 1s - 678us/step - accuracy: 0.9145 - loss: 0.2427 - val_accuracy: 0.8790 - val_loss: 0.3437
Epoch 26/30
1719/1719 - 1s - 666us/step - accuracy: 0.9158 - loss: 0.2384 - val_accuracy: 0.8792 - val_loss: 0.3446
Epoch 27/30
1719/1719 - 1s - 662us/step - accuracy: 0.9172 - loss: 0.2341 - val_accuracy: 0.8810 - val_loss: 0.3445
Epoch 28/30
1719/1719 - 1s - 664us/step - accuracy: 0.9193 - loss: 0.2299 - val_accuracy: 0.8804 - val_loss: 0.3441
Epoch 29/30
1719/1719 - 1s - 677us/step - accuracy: 0.9210 - loss: 0.2260 - val_accuracy: 0.8808 - val_loss: 0.3445
Epoch 30/30
1719/1719 - 1s - 679us/step - accuracy: 0.9223 - loss: 0.2220 - val_accuracy: 0.8800 - val_loss: 0.3440

Courbes d’entraînement et de validation

Code
epochs = np.arange(1, len(history.history["loss"]) + 1)
fig, axes = plt.subplots(1, 2, figsize=(9, 3.5))
for ax, metric, title in zip(
    axes, ["loss", "accuracy"], ["Perte", "Exactitude"]
):
    ax.plot(epochs, history.history[metric], label="Entraînement")
    ax.plot(epochs, history.history[f"val_{metric}"], label="Validation")
    ax.set(xlabel="Époque", ylabel=title)
    ax.grid(True)
    ax.legend()
axes[1].set_ylim(0, 1)
plt.tight_layout()
plt.show()

Évaluation finale sur l’ensemble de test

test_loss, test_accuracy = model.evaluate(X_test, y_test, verbose=0)
print(f"Perte de test : {test_loss:.3f}")
print(f"Exactitude de test : {test_accuracy:.3f}")
Perte de test : 0.362
Exactitude de test : 0.874

Faire des prédictions

X_new = X_test[:3]
y_proba = model.predict(X_new, verbose=0)
y_proba.round(2)
array([[0.  , 0.  , 0.  , 0.  , 0.  , 0.33, 0.  , 0.01, 0.  , 0.65],
       [0.  , 0.  , 1.  , 0.  , 0.  , 0.  , 0.  , 0.  , 0.  , 0.  ],
       [0.  , 1.  , 0.  , 0.  , 0.  , 0.  , 0.  , 0.  , 0.  , 0.  ]],
      dtype=float32)
y_pred = y_proba.argmax(axis=1)
y_pred
array([9, 2, 1])
y_observed = y_test[:3]
y_observed
array([9, 2, 1], dtype=uint8)

Étiquettes prédites et observées

Code
fig, axes = plt.subplots(1, 3, figsize=(8, 3))
for ax, image, prediction, observed in zip(axes, X_new, y_pred, y_observed):
    ax.imshow(image, cmap="binary", interpolation="nearest")
    ax.set_title(f"Prédit : {class_names[prediction]}\n"
                 f"Observé : {class_names[observed]}", fontsize=10)
    ax.axis("off")
plt.tight_layout()
plt.show()

Performances par classe

from sklearn.metrics import classification_report

y_test_proba = model.predict(X_test, verbose=0)
y_test_pred = y_test_proba.argmax(axis=1)
print(classification_report(y_test, y_test_pred,
                            target_names=class_names, digits=3))
              precision    recall  f1-score   support

T-shirt/haut      0.842     0.810     0.826      1000
    Pantalon      0.992     0.964     0.978      1000
        Pull      0.744     0.850     0.793      1000
        Robe      0.824     0.929     0.873      1000
     Manteau      0.806     0.794     0.800      1000
     Sandale      0.885     0.986     0.933      1000
     Chemise      0.777     0.618     0.689      1000
  Espadrille      0.944     0.911     0.927      1000
         Sac      0.961     0.963     0.962      1000
     Bottine      0.983     0.918     0.949      1000

    accuracy                          0.874     10000
   macro avg      0.876     0.874     0.873     10000
weighted avg      0.876     0.874     0.873     10000

Conclusion

Résumé

  • Calcul : la propagation avant associe des sorties aux entrées à l’aide des poids, des biais et des activations.
  • Représentation : des couches cachées non linéaires calculent des attributs intermédiaires qui peuvent rendre XOR séparable.
  • Apprentissage : l’entraînement ajuste les paramètres; la rétropropagation calcule les gradients utilisés par un optimiseur.
  • Approximation universelle : des paramètres appropriés peuvent exister sans garantie que l’entraînement les trouvera.
  • Implémentation : Keras relie ces idées dans une procédure complète de classification sur Fashion-MNIST.
  • Évaluation : appliquer un prétraitement cohérent et distinguer les performances d’entraînement, de validation et de test.

3Blue1Brown sur l’apprentissage profond

Prochaine présentation

  • Nous examinerons l’implémentation d’un réseaux de neurones artificiels.

Références

Cybenko, George V. 1989. « Approximation by superpositions of a sigmoidal function ». Mathematics of Control, Signals and Systems 2: 303‑14. https://api.semanticscholar.org/CorpusID:3958369.
Géron, Aurélien. 2022. Hands-on Machine Learning with Scikit-Learn, Keras, and TensorFlow. 3ᵉ éd. O’Reilly Media, Inc.
Goodfellow, Ian, Yoshua Bengio, et Aaron Courville. 2016. Deep Learning. Adaptive computation et machine learning. MIT Press. https://dblp.org/rec/books/daglib/0040158.
Hornik, Kurt, Maxwell Stinchcombe, et Halbert White. 1989. « Multilayer feedforward networks are universal approximators ». Neural Networks 2 (5): 359‑66. https://doi.org/https://doi.org/10.1016/0893-6080(89)90020-8.
Lakoff, George, et Srini Narayanan. 2025. The Neural Mind: How Brains Think. 1ʳᵉ éd. University of Chicago Press. https://press.uchicago.edu/ucp/books/book/chicago/N/bo243406239.html.
LeCun, Yann, Yoshua Bengio, et Geoffrey Hinton. 2015. « Deep learning ». Nature 521 (7553): 436‑44. https://doi.org/10.1038/nature14539.
LeNail, Alexander. 2019. « NN-SVG: Publication-Ready Neural Network Architecture Schematics ». Journal of Open Source Software 4 (33): 747. https://doi.org/10.21105/joss.00747.
McCulloch, Warren S, et Walter Pitts. 1943. « A logical calculus of the ideas immanent in nervous activity ». The Bulletin of Mathematical Biophysics 5 (4): 115‑33. https://doi.org/10.1007/bf02478259.
Minsky, Marvin, et Seymour Papert. 1969. Perceptrons: An Introduction to Computational Geometry. MIT Press.
Rosenblatt, F. 1958. « The perceptron: A probabilistic model for information storage and organization in the brain. » Psychological Review 65 (6): 386‑408. https://doi.org/10.1037/h0042519.
Rumelhart, David E., Geoffrey E. Hinton, et Ronald J. Williams. 1986. « Learning representations by back-propagating errors ». Nature 323 (6088): 533‑36. https://doi.org/10.1038/323533a0.
Russell, Stuart, et Peter Norvig. 2020. Artificial Intelligence: A Modern Approach. 4ᵉ éd. Pearson. http://aima.cs.berkeley.edu/.

Marcel Turcotte

[email protected]

École de science informatique et de génie électrique (SIGE)

Université d’Ottawa