Python 有人能解释tf.keras.layers.BatchNormalization的行为吗?

Python 有人能解释tf.keras.layers.BatchNormalization的行为吗?,python,tensorflow,keras,Python,Tensorflow,Keras,从tensorflow文档中: “规范化每批前一层的激活,即应用转换,使平均激活接近0,激活标准偏差接近1。” 因此,我希望该层首先计算前一层输出的平均值和标准偏差,减去平均值,再除以批次中每个样品的标准偏差。但显然我错了 import numpy as np import tensorflow as tf if __name__ == "__main__": # flattened tensor, batch size of 2 xnp = np.ar

从tensorflow文档中:

“规范化每批前一层的激活,即应用转换,使平均激活接近0,激活标准偏差接近1。”

因此,我希望该层首先计算前一层输出的平均值和标准偏差,减去平均值,再除以批次中每个样品的标准偏差。但显然我错了

import numpy as np
import tensorflow as tf


if __name__ == "__main__":
    # flattened tensor, batch size of 2
    xnp = np.array([[1,2,3],[4,5,6]])
    xtens = tf.constant(xnp,dtype=tf.float32)

    nbatchnorm = tf.keras.layers.BatchNormalization()(xtens)

    # tensorflow output
    print(nbatchnorm)

    # what I expect to see
    xmean = np.mean(xnp,axis=1)
    xstd = np.std(xnp,axis=1)
    # set the mean to 0 and the standard deviation to 1 for each sample
    normalized = (xnp - xmean.reshape(-1,1)) / xstd.reshape(-1,1)

    print(normalized)

输出:

tf.Tensor(
[[0.9995004 1.9990008 2.9985013]                                                                                                     
 [3.9980016 4.997502  5.9970026]], shape=(2, 3), dtype=float32)                                                 

[[-1.22474487  0.          1.22474487]           
 [-1.22474487  0.          1.22474487]]   

有人能给我解释一下为什么这些输出不相同或至少不相似吗?我看不出这是如何规范化任何东西的。

好吧,
批量规范化
取决于其算法的许多因素,下面将对此进行解释

  • μB是输入平均值的向量,在整个mini上进行评估- 批次B(每个输入包含一个平均值)
  • σB是输入标准偏差的向量,也在 整个小批量(每批包含一个标准偏差) 输入)
  • mB是小批量中的实例数
  • X̂(i)是用于 实例一
  • γ是层的输出比例参数向量(它包含一个 每个输入的比例参数)
  • 表示元素乘法(每个输入都是 乘以其相应的输出比例参数)
  • β是层(it)的输出移位(偏移)参数向量 每个输入包含一个偏移参数)。每个输入由 它对应的移位参数
  • ε是一个很小的数字,可以避免被零除(通常为10–5)。 这称为平滑项
  • z(i)是BN操作的输出。这是一个重新缩放和移动的 输入的版本

请阅读BatchNorm的方程式。请注意,最后,
x_hat
gamma
缩放,这是一个可学习的参数。您的代码中缺少它。我看到它添加了按gamma和beta缩放的值,但它也表示这些值分别初始化为1和0,由默认的kwargs显示:beta_initializer='零',gamma_initializer='一',在我看来,它应该使该计算与我的numpy计算相同。您需要使用
training=True
(注意——在调用中,而不是在层构造函数中)调用batchnorm。因此,我这样调用层nbatchnorm=tf.keras.layers.BatchNormalization()(xtens,training=True)正确吗?这改变了输出,但现在都接近1,这就产生了输出:tf.Tensor([[-0.999779-0.999778-0.999779][0.999778 0.9997703 0.999778]],shape=(2,3),dtype=float32)仍然不是我所期望的