Les keras BatchNormalization
couche utilise axis=-1
comme valeur par défaut et indique que l'axe de la fonction est généralement normalisé. pourquoi est-ce le cas?
Je suppose que cela est surprenant car je suis plus familier avec quelque chose comme StandardScaler
, ce qui équivaudrait à utiliser axis=0
. Cela normaliserait les fonctionnalités individuellement.
Y a-t-il une raison pour laquelle les échantillons sont normalisés individuellement par défaut (c'est-à-dire axis=-1
) en keras par opposition aux fonctionnalités?
Edit: exemple de concrétisation
Il est courant de transformer des données de telle sorte que chaque entité ait une moyenne et une variance d'unité nulles. Prenons simplement la partie "zéro moyenne" avec cet ensemble de données fictif, où chaque ligne est un échantillon:
>>> data = np.array([[ 1, 10, 100, 1000],
[ 2, 20, 200, 2000],
[ 3, 30, 300, 3000]])
>>> data.mean(axis=0)
array([ 2., 20., 200., 2000.])
>>> data.mean(axis=1)
array([ 277.75, 555.5 , 833.25])
Ne serait-il pas plus logique de soustraire le axis=0
signifie, par opposition à axis=1
signifier? En utilisant axis=1
, les unités et les échelles peuvent être complètement différentes.
Modifier 2:
La première équation de la section 3 dans cet article semble impliquer que axis=0
doit être utilisé pour calculer les attentes et les variances pour chaque entité individuellement, en supposant que vous avez un ensemble de données en forme (m, n) où m est le nombre d'échantillons et n est le nombre d'entités.
Edit 3: un autre exemple
Je voulais voir les dimensions des moyennes et des variances BatchNormalization
calculait sur un jeu de données jouet:
import pandas as pd
import numpy as np
from sklearn.datasets import load_iris
from keras.optimizers import Adam
from keras.models import Model
from keras.layers import BatchNormalization, Dense, Input
iris = load_iris()
X = iris.data
y = pd.get_dummies(iris.target).values
input_ = Input(shape=(4, ))
norm = BatchNormalization()(input_)
l1 = Dense(4, activation='relu')(norm)
output = Dense(3, activation='sigmoid')(l1)
model = Model(input_, output)
model.compile(Adam(0.01), 'categorical_crossentropy')
model.fit(X, y, epochs=100, batch_size=32)
bn = model.layers[1]
bn.moving_mean # <tf.Variable 'batch_normalization_1/moving_mean:0' shape=(4,) dtype=float32_ref>
L'entrée X a une forme (150, 4) et la couche BatchNormalization
a calculé 4 signifie, ce qui signifie qu'elle a fonctionné sur axis=0
.
Si BatchNormalization
a une valeur par défaut de axis=-1
alors ne devrait-il pas y avoir 150 moyens?
La confusion est due à la signification de axis
dans np.mean
Par rapport à BatchNormalization
.
Lorsque nous prenons la moyenne le long d'un axe, nous réduisons cette dimension et préservons toutes les autres dimensions. Dans votre exemple, data.mean(axis=0)
réduit le 0-axis
, Qui est la dimension verticale de data
.
Lorsque nous calculons un BatchNormalization
le long d'un axe, nous préservons les dimensions du tableau et nous normalisons par rapport à la moyenne et l'écart type sur tous les deux axes. Ainsi, dans votre exemple 2D
BatchNormalization
avec axis=1
is en soustrayant la moyenne de axis=0
, Comme vous vous y attendez. C'est pourquoi bn.moving_mean
A la forme (4,)
.
Je sais que ce message est ancien, mais j'y réponds toujours car la confusion persiste dans la documentation Keras. J'ai dû parcourir le code pour comprendre cela:
si votre mini-batch est une matrice [~ # ~] a [~ # ~] mxn , c'est-à-dire m échantillons et n caractéristiques, l'axe de normalisation doit être axe = 0 . Comme vous l'avez dit, ce que nous voulons, c'est normaliser chaque fonctionnalité individuellement, l'axe par défaut = -1 en keras car quand il est utilisé dans la couche de convolution, les dimensions du jeu de données des figures sont généralement (échantillons, largeur, hauteur, canal) , et les échantillons de lot sont normalisés le long de axe canalaire (le dernier axe) .