我正在使用 BatchNormalization 层,但我不太清楚所得到的数值结果。
让我们考虑将BatchNormalization用于计算机视觉。
我们有4D张量。
尺寸包括:批量大小,图像高度,图像宽度,通道。
如果我理解正确,那么BatchNormalization将执行以下操作:
现在,我的问题来了...
首先,我只对推断时发生的事情感兴趣。 我不在乎训练,我认为MÛ,SIĜMA, GAMMA 和 BETA 是固定参数
我写了一段python在(1、3、4、1)张量上测试BatchNormalization。 由于只有一个频道,所以MÛ,SIĜMA, GAMMA 和 BETA 分别只有1个元素。>
我选择了MÛ= 0.0 ,SIĜMA= 1.0 , GAMMA = 1.0 和 BETA = 0.0 , BatchNormalization无效。
代码如下:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import numpy
import keras
import math
input_batch = numpy.array(
[[
[[ 1.0], [ 2.0], [ 3.0], [ 4.0]],
[[ 5.0], [ 6.0], [ 7.0], [ 8.0]],
[[ 9.0], [10.0], [11.0], [12.0]]
]],
dtype=numpy.float32
)
MU = 0.0
SIGMA = 1.0
GAMMA = 1.0
BETA = 0.0
input_layer = keras.layers.Input(
shape = (
None,
None,
1
)
)
BatchNormalization_layer = keras.layers.BatchNormalization(
axis=-1,
#epsilon=0.0,
center=True,
scale=True
)(
input_layer
)
model = keras.models.Model(
inputs = [input_layer],
outputs = [BatchNormalization_layer]
)
model.layers[1].set_weights(
(
numpy.array([GAMMA], dtype=numpy.float32),
numpy.array([BETA], dtype=numpy.float32),
numpy.array([MU], dtype=numpy.float32),
numpy.array([SIGMA], dtype=numpy.float32),
)
)
print model.predict(input_batch)
print ((((input_batch - MU) / math.sqrt(SIGMA)) * GAMMA) + BETA)
当我使用numpy明确编写计算((((input_batch - MU) / math.sqrt(SIGMA)) * GAMMA) + BETA)
时,我得到了预期的结果。
但是,当我使用keras.layers.BatchNormalization层执行计算时,我得到类似的结果,只是存在某种舍入误差或不精确性:
Using TensorFlow backend.
[[[[ 0.9995004]
[ 1.9990008]
[ 2.9985013]
[ 3.9980016]]
[[ 4.997502 ]
[ 5.9970026]
[ 6.996503 ]
[ 7.996003 ]]
[[ 8.995503 ]
[ 9.995004 ]
[10.994504 ]
[11.994005 ]]]]
[[[[ 1.]
[ 2.]
[ 3.]
[ 4.]]
[[ 5.]
[ 6.]
[ 7.]
[ 8.]]
[[ 9.]
[10.]
[11.]
[12.]]]]
当我使用MU *,SIGMA *,GAMMA和BETA的值时,输出会受到预期的影响,因此我相信我会正确地为该层提供参数。
我还尝试将图层的超参数epsilon设置为0.0。它会稍微改变结果,但是并不能解决问题。
Using TensorFlow backend.
[[[[ 0.999995 ]
[ 1.99999 ]
[ 2.999985 ]
[ 3.99998 ]]
[[ 4.999975 ]
[ 5.99997 ]
[ 6.9999647]
[ 7.99996 ]]
[[ 8.999955 ]
[ 9.99995 ]
[10.999945 ]
[11.99994 ]]]]
[[[[ 1.]
[ 2.]
[ 3.]
[ 4.]]
[[ 5.]
[ 6.]
[ 7.]
[ 8.]]
[[ 9.]
[10.]
[11.]
[12.]]]]
有人可以解释发生了什么事吗?
谢谢
朱利安
答案 0 :(得分:1)
我挖掘了张量流代码(被keras称为后端)。 在batch_normalization代码中,我读到:
# Set a minimum epsilon to 1.001e-5, which is a requirement by CUDNN to
# prevent exception (see cudnn.h).
min_epsilon = 1.001e-5
epsilon = epsilon if epsilon > min_epsilon else min_epsilon
解释为什么在喀拉拉邦设置 epsilon = 0.0 不起作用。
在脚本中考虑epsilon时,我得到了正确的结果...
((((input_batch - MU) / math.sqrt(SIGMA + EPSILON)) * GAMMA) + BETA)
Using TensorFlow backend.
[[[[ 0.99503714]
[ 1.9900743 ]
[ 2.9851115 ]
[ 3.9801486 ]]
[[ 4.975186 ]
[ 5.970223 ]
[ 6.96526 ]
[ 7.960297 ]]
[[ 8.955335 ]
[ 9.950372 ]
[10.945409 ]
[11.940446 ]]]]
[[[[ 0.99503714]
[ 1.9900743 ]
[ 2.9851115 ]
[ 3.9801486 ]]
[[ 4.975186 ]
[ 5.970223 ]
[ 6.96526 ]
[ 7.960297 ]]
[[ 8.955335 ]
[ 9.950372 ]
[10.945409 ]
[11.940446 ]]]]