Keras Batchnorm слой скользящего среднего для дисперсии - PullRequest
0 голосов
/ 03 июля 2018

Я пытался понять поведение слоя 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 (дисперсия) - нет. Может кто-нибудь, пожалуйста, помогите здесь? Спасибо.

1 Ответ

0 голосов
/ 03 июля 2018

Если вы посмотрите на исходный код * * * * * * * * * * * * * * * * * *, вы видите, что используется несмещенная оценка дисперсии населения, вот соответствующая строка:

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

В вашем случае размер выборки равен 5, поэтому у вас должно быть train_var * 5./4 == moving_var, что имеет место.

...