Une couche qui recentre et remet à l'échelle les signaux d'un réseau de neurones, lot par lot, avant de les passer à la couche suivante. Les couches profondes reçoivent des entrées stables, ce qui autorise un pas d'apprentissage plus grand et un entraînement plus rapide. Elle est présente dans la plupart des réseaux de vision.
Une chaîne de traitement où chaque poste recalibre la pièce qu'il reçoit avant de travailler dessus. Même si le poste précédent change ses réglages, le suivant travaille toujours sur une pièce aux bonnes cotes.
Pour chaque neurone, on calcule la moyenne et l'écart-type de ses valeurs sur le lot de données en cours, par exemple 256 contrats.
Chaque valeur devient (valeur - moyenne) / écart-type. Tous les neurones sortent des signaux centrés sur 0, d'écart-type 1.
Deux paramètres appris par neurone, une échelle et un décalage, lui permettent de retrouver la distribution qui l'arrange. La normalisation ne bride pas ce que le réseau peut représenter.
En prédiction, on n'a pas de lot : la couche utilise les moyennes et écarts-types mémorisés pendant l'entraînement. Une prédiction ne dépend donc pas des autres lignes.
Âge du conducteur, puissance, zone, bonus-malus, exposition en années et nombre de sinistres. On modélise la fréquence de sinistres avec un réseau de 6 couches et une perte de Poisson pondérée par l'exposition.
Le nombre de sinistres attendu par année assurée, base de la prime pure. Le même réseau est entraîné avec et sans batch normalization, à pas égal, pour comparer la stabilité de l'apprentissage.
On suit la déviance de Poisson sur des contrats jamais vus. La batch normalization doit la faire baisser plus vite et plus régulièrement. Pour la tarification, on compare ensuite le réseau au GLM de Poisson, la référence de l'actuariat.
La couche marche bien par défaut. Les décisions portent sur son emploi.
Entre la couche dense ou convolutive et l'activation, comme dans le ResNet d'origine. La couche précédente peut alors se passer de biais (use_bias=False) : le décalage appris le remplace.
Le réglage caché. En dessous de 8 à 16 lignes par lot, les statistiques du lot deviennent trop bruitées et la performance se dégrade.
La vitesse de mise à jour des moyennes mémorisées pour la prédiction (0,99 par défaut en Keras). À baisser si les performances de validation sont instables en début d'entraînement.
# Fréquence de sinistres auto : batch normalization en R (keras3)
library(keras3)
sinistres <- read.csv("sinistres.csv")
X <- scale(model.matrix(~ age_conducteur + puissance_cv + zone + bonus_malus, data = sinistres)[, -1])
frequence <- sinistres$nb_sinistres / sinistres$exposition # sinistres par année assurée
exposition <- sinistres$exposition
set.seed(42)
idx <- sample(nrow(X), round(0.7 * nrow(X)))
reseau <- function(avec_bn) {
set_random_seed(42)
modele <- keras_model_sequential(input_shape = ncol(X))
for (i in 1:6) { # 6 couches cachées
modele <- layer_dense(modele, units = 64, use_bias = !avec_bn)
if (avec_bn) modele <- layer_batch_normalization(modele) # recentre chaque neurone sur le lot
modele <- layer_activation(modele, "relu")
}
modele <- layer_dense(modele, units = 1, activation = "exponential") # fréquence toujours positive
compile(modele, optimizer = optimizer_adam(learning_rate = 0.01), loss = "poisson")
histo <- fit(modele, X[idx, ], frequence[idx], sample_weight = exposition[idx], epochs = 20, batch_size = 256,
validation_data = list(X[-idx, ], frequence[-idx], exposition[-idx]), verbose = 0)
round(histo$metrics$val_loss[c(1, 6, 11, 16)], 4)
}
cat("Perte test passes 1, 6, 11, 16, sans BN :", reseau(FALSE), "\n")
cat("Perte test passes 1, 6, 11, 16, avec BN :", reseau(TRUE), "\n")
# Fréquence de sinistres auto : batch normalization en Python (Keras)
import pandas as pd
import keras
from keras import layers
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
sinistres = pd.read_csv("sinistres.csv")
X = pd.get_dummies(sinistres[["age_conducteur", "puissance_cv", "zone", "bonus_malus"]], dtype=float)
frequence = (sinistres["nb_sinistres"] / sinistres["exposition"]).values # sinistres par année assurée
exposition = sinistres["exposition"].values
X_train, X_test, f_train, f_test, e_train, e_test = train_test_split(X, frequence, exposition, test_size=0.3, random_state=42)
echelle = StandardScaler().fit(X_train)
X_train, X_test = echelle.transform(X_train), echelle.transform(X_test)
def reseau(avec_bn):
keras.utils.set_random_seed(42)
modele = keras.Sequential([keras.Input((X_train.shape[1],))])
for _ in range(6): # 6 couches cachées
modele.add(layers.Dense(64, use_bias=not avec_bn))
modele.add(layers.BatchNormalization() if avec_bn else layers.Identity()) # recentre chaque neurone sur le lot
modele.add(layers.Activation("relu"))
modele.add(layers.Dense(1, activation="exponential")) # fréquence toujours positive
modele.compile(optimizer=keras.optimizers.Adam(learning_rate=0.01), loss="poisson")
histo = modele.fit(X_train, f_train, sample_weight=e_train, epochs=20, batch_size=256,
validation_data=(X_test, f_test, e_test), verbose=0)
return [round(v, 4) for v in histo.history["val_loss"][::5]]
for avec_bn in (False, True):
print("Perte test passes 1, 6, 11, 16,", "avec BN :" if avec_bn else "sans BN :", reseau(avec_bn))
L'explication d'origine (2015) parlait de réduire le décalage des distributions entre couches. Des travaux ultérieurs montrent plutôt qu'elle lisse le paysage de l'erreur : les gradients sont plus prévisibles, ce qui autorise des pas plus grands. Dans les deux cas, l'effet pratique est un entraînement plus rapide et plus stable.
La batch normalization calcule moyenne et écart-type sur les lignes du lot, neurone par neurone. La layer normalization les calcule sur les neurones d'une même ligne. Elle ne dépend donc pas de la taille du lot, ce qui en fait le choix des Transformers et des réseaux récurrents.
Oui, c'est recommandé. La batch normalization agit entre les couches, pas forcément sur l'entrée. Standardiser les variables reste une étape simple qui facilite le travail de la première couche.
Éteint des neurones au hasard. Les deux se combinent mal dans les mêmes couches : on choisit selon l'architecture.
Voir la fiche → l'usage de référenceChaque bloc enchaîne convolution, batch normalization et activation. Les deux idées ensemble ont permis des réseaux de 150 couches.
Voir la fiche → l'optimiseur associéPas adaptatif par poids. Avec la batch normalization, il supporte des pas plus grands.
Voir la fiche →Dataistudio forme les équipes au machine learning et à l'IA, sur des cas concrets.
Nous utilisons des cookies de mesure d'audience et de suivi publicitaire pour comprendre la fréquentation du site et l'efficacité de nos annonces. Rien n'est déposé sans votre accord. En savoir plus