keras BatchNormalization轴澄清

时间:2017-11-28 18:19:01

标签: python machine-learning deep-learning keras

keras BatchNormalization layer使用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:

this paper中第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  # <tf.Variable 'batch_normalization_1/moving_mean:0' shape=(4,) dtype=float32_ref>

输入X具有形状(150,4),BatchNormalization层计算4意味着,这意味着它在axis=0上运行。

如果BatchNormalization的默认值为axis=-1,则不应该有150种手段?

3 个答案:

答案 0 :(得分:8)

混淆是由于axisnp.meanBatchNormalization的含义所致。

当我们沿着轴取平均值时,我们会折叠该维度并保留所有其他维度。在您的示例中data.mean(axis=0)折叠0-axis,这是data的垂直维度。

当我们沿着轴计算BatchNormalization时,我们保留数组的尺寸,并且相对于每个其他轴的平均值和标准偏差进行标准化。因此,在2D示例BatchNormalization中,axis=1 减去axis=0的均值,正如您所期望的那样。这就是bn.moving_mean具有(4,)形状的原因。

答案 1 :(得分:3)

我知道这篇文章很老,但仍在回答,因为混乱仍然存在于Keras文档中。我必须遍历代码才能弄清楚:

  1. 记录为整数的axis变量实际上可以是表示多个轴的整数列表。所以例如如果我的输入具有NHWC或NCHW格式的图像,则如果我想以OP希望的方式执行BatchNormalization(即仅跨批次尺寸进行标准化),则提供axis = [1,2,3]。
  2. 轴列表(或整数)应包含您在计算均值和方差时不希望 减小的轴。换句话说,它是您要标准化的轴的补码,这与文档中按照“轴”的常规定义所显示的内容完全相反。所以例如如果输入的我的形状为(N,H,W,C)或(N,C,H,W)-即第一个维度是批次维度,而您只希望在整个批次维度上计算均值和方差您应该提供axis = [1,2,3]。这将使Keras分别计算形状为(1,H,W,C)或(1,C,H,W)的均值M和方差V张量-即由于聚合(即均值),批处理尺寸将被边缘化/减少或在第一个维度上计算出方差)。在后来的(I-M)和(I-M)/ V等操作中,M和V的第一个维度将广播到该批次的N个样本中。
  3. 在此示例中,BatchNorm层最终以轴=(1,)调用tf.nn.moments!之所以这样,是因为tf.nn.moments中的轴定义是正确的。
  4. 类似地,tf.nn.moments调用tf.nn.reduce_mean,其中轴的定义再次是正确的(即与tf.keras.layers.BatchNormalization相反)。
  5. 也就是说,BatchNormalization论文建议对HxW空间地图进行归一化处理,此外还要添加批处理尺寸(N)。因此,如果遵循该建议,则轴将仅包括通道尺寸(C),因为这是您不希望减小的唯一剩余尺寸。尽管很神秘,但Keras文档可能暗示了这一点。

答案 2 :(得分:0)

如果您的小批量生产是矩阵 A mxn ,即 m 样本和 n 功能,归一化轴应为 axis = 0 。就像您说的,我们想要的是单独标准化每个功能,即keras中的默认 axis = -1 ,因为在卷积层中使用时,图形数据集通常是 (样本,宽度,高度,通道) ,并且批样本在 通道轴(最后一个轴)< / em>