Я пытался понять поведение слоя Keras BatchNorm в моей модели Keras NN. Один вопрос, с которым я столкнулся, заключался в том, как слой BN вычисляет скользящее среднее «дисперсии». Насколько я понимаю, Керас использует метод экспоненциально-взвешенного среднего для вычисления скользящего среднего как для среднего значения, так и для отклонения от обучающих мини-пакетов. Но независимо от этого, после действительно большого количества эпох, это скользящее среднее должно приближаться к среднему значению / дисперсии набора обучающих данных. Но в моем простом примере скользящее среднее «дисперсия» всегда отличается от «дисперсии» обучающих данных. Ниже мой код и вывод:
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 (дисперсия) - нет. Может кто-нибудь, пожалуйста, помогите здесь? Спасибо.