keras BatchNormalization轴明确化
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个均值吗?