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
,就是这样。
我一直在尝试了解我的 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
,就是这样。