keras batchnorm 层移动平均方差

keras batchnorm layer moving average for variance

我一直在尝试了解我的 Keras NN 模型中的 Keras BatchNorm 层行为。我遇到的一个问题是BN层是如何计算'variance'的移动平均值的。我的理解是 Keras 使用指数加权平均法来计算训练小批量的均值和方差的移动平均值。但不管怎样,经过大量的 epoch 之后,这个移动平均值应该接近训练数据集的 mean/variance。但在我的简单示例中,'variance' 移动平均线始终与训练数据 'variance' 不同。下面是我的代码和输出:

from keras.layers import Input, BatchNormalization
from keras.models import Model
from keras.optimizers import Adam, RMSprop

import numpy as np

X_input = Input(shape=(6,))
X = BatchNormalization(axis=-1)(X_input)

model = Model(inputs=X_input, outputs=X)

model.compile(optimizer=RMSprop(), loss='mean_squared_error')

np.random.seed(3)
train_data = np.random.random((5,6))
train_label = np.random.random((5,6))

model.fit(x=train_data, y=train_label, epochs=10000, batch_size=6, verbose=False)

bn_gamma, bn_beta, bn_mean, bn_var = model.layers[1].get_weights()
train_mean = np.mean(train_data, axis=0)
train_var = np.var(train_data, axis=0)

print("train_mean: {}".format(train_mean))
print("moving_mean: {}".format(bn_mean))
print("train_var: {}".format(train_var))
print("moving_var: {}".format(bn_var))

下面是输出:

train_mean: [0.42588575 0.47785879 0.32170309 0.49151921 0.355046   0.60104636]
moving_mean: [0.4258843  0.47785735 0.32170165 0.49151778 0.35504454 0.60104346]
train_var: [0.03949981 0.05228663 0.04027516 0.02522536 0.10261097 0.0838988 ]
moving_var: [0.04938692 0.06537427 0.05035637 0.03153942 0.12829503 0.10489936]

你看,train_mean和BN层的移动平均均值是一样的,但是train_var(方差)不是。有人可以在这里帮忙吗?谢谢

如果你查看source code of batchnorm,你可以看到使用了人口方差的无偏估计,这里是相关的行:

variance *= sample_size / (sample_size - (1.0 + self.epsilon))

在你的例子中,样本量是5,所以你应该有train_var * 5./4 == moving_var,就是这样。