我一直在尝试了解Keras NN模型中的Keras BatchNorm层行为。我遇到的一个问题是BN层如何计算“方差”的移动平均值。我的理解是Keras正在使用指数加权平均法来计算训练迷你批次的均值和方差的移动平均值。但是无论如何,在经过非常大量的时期之后,该移动平均值应该接近训练数据集的均值/方差。但是在我的简单示例中,“方差”移动平均值始终与训练数据“方差”不同。下面是我的代码和输出:
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(方差)则不同。谁能帮忙吗?谢谢。
答案 0 :(得分:0)
如果查看source code of batchnorm,您会发现使用了人口方差的无偏估计量,这是相关行:
variance *= sample_size / (sample_size - (1.0 + self.epsilon))
根据您的情况,样本大小为5,因此您应该有train_var * 5./4 == moving_var
。