keras BatchNormalization轴明确化

7 浏览
0 Comments

keras BatchNormalization轴明确化

keras中的BatchNormalization层默认使用axis=-1,并指出特征轴通常被归一化。为什么会这样呢?

我认为这令人惊讶,因为我更熟悉使用类似于StandardScaler的东西,这相当于使用axis=0。这将对特征进行单独归一化。

为什么默认情况下keras中的样本是单独归一化的(即axis=-1),而不是特征?

编辑:具体例子

通常会对数据进行转换,使得每个特征具有零均值和单位方差。让我们用这个模拟数据集只考虑"零均值"部分,其中每行是一个样本:

>>> data = np.array([[   1,   10,  100, 1000],
                     [   2,   20,  200, 2000],
                     [   3,   30,  300, 3000]])
>>> data.mean(axis=0)
array([    2.,    20.,   200.,  2000.])
>>> data.mean(axis=1)
array([ 277.75,  555.5 ,  833.25])

axis=0的均值减去,而不是axis=1的均值,难道不更合理吗?使用axis=1,单位和尺度可以完全不同。

编辑2:

这篇论文中第3节的第一个公式似乎暗示应该使用axis=0来计算每个特征的期望和方差,假设你有一个形状为(m, n)的数据集,其中m是样本数量,n是特征数量。

编辑3:另一个例子

我想看看BatchNormalization在一个玩具数据集上计算的均值和方差的维度:

import pandas as pd
import numpy as np
from sklearn.datasets import load_iris
from keras.optimizers import Adam
from keras.models import Model
from keras.layers import BatchNormalization, Dense, Input
iris = load_iris()
X = iris.data
y = pd.get_dummies(iris.target).values
input_ = Input(shape=(4, ))
norm = BatchNormalization()(input_)
l1 = Dense(4, activation='relu')(norm)
output = Dense(3, activation='sigmoid')(l1)
model = Model(input_, output)
model.compile(Adam(0.01), 'categorical_crossentropy')
model.fit(X, y, epochs=100, batch_size=32)
bn = model.layers[1]
bn.moving_mean  # 

输入X的形状为(150, 4),BatchNormalization层计算了4个均值,这意味着它在axis=0上操作。

如果BatchNormalization的默认值是axis=-1,那么应该有150个均值吗?

0