Keras 后端:random_normal 和 random_normal_variable 之间的区别

Keras Backend: Difference between random_normal and random_normal_variable

我的神经网络有一个自定义层,它接受一个输入向量 x,生成一个正态分布的张量 A 和 returns 都 A(用于后续层)和产品 Ax。假设我想在自定义层的输出中重用存储在 A 中的值,在第二个不同的层中,在确定哪个 Keras 后端函数(K.backend.random_normal 时我需要考虑任何微妙的方面或 K.backend.random_normal_variable) 我应该使用以生成 A?

a) 后端函数 random_normal returns 一个张量,在每次调用后存储不同的值(参见下面的代码片段)。对我来说,这表明 random_normal 充当正态分布值的生成器。这是否意味着如果他们想在调用后保持其值,就不应该使用 random_normal 来生成正态分布的张量?

b) 后端函数 random_normal_variable 看起来更安全(请参阅下面的代码片段),因为它在调用之间保留值。

我的概念理解正确吗?还是我缺少一些基本的东西? 我正在使用 Keras 2.1.2 和 Tensorflow 1.4.0。

使用 random_normal 进行试验(调用时值会发生变化):

In [5]: A = K.random_normal(shape = (2,2), mean=0.0, stddev=0.5) 
In [6]: K.get_value(A)
Out[6]: array([[ 0.4459489 , -0.82019573],
   [-0.39853573, -0.33919844]], dtype=float32)
In [7]: K.get_value(A)
Out[7]: array([[-0.37467018,  0.42445764],
   [-0.573843  , -0.3468301 ]], dtype=float32)

使用 random_normal_variable 进行试验(跨调用保持值):

In [9]: B = K.random_normal_variable(shape=(2,2), mean=0., scale=0.5)
In [10]: K.get_value(B)
Out[10]: array([[ 0.07700552,  0.28008622],
   [-0.69484973, -1.32078779]], dtype=float32)
In [11]: K.get_value(B)
Out[11]: array([[ 0.07700552,  0.28008622],
   [-0.69484973, -1.32078779]], dtype=float32)

据我了解,这是由于 random_normal_variable returns 实例化 Variablerandom_normal returns 实例化 Tensor .

K.random_normal(shape=(2,2), mean=0.0, stddev=0.5) 
<tf.Tensor 'random_normal:0' shape=(2, 2) dtype=float32>

K.random_normal_variable(shape=(2,2), mean=0.0, scale=0.5)
<tf.Variable 'Variable:0' shape=(2, 2) dtype=float32_ref> 

至于为什么 Tensor 的值不同而 Variable 的值不同,我认为这个 的答案总结得很好:

Variable is basically a wrapper on Tensor that maintains state across multiple calls to run [...]

答案还提到需要初始化变量才能对其求值,正如您注意到的那样(因为您没有初始化变量来求值)。事实上,由于在 random_normal_variable 函数中调用了 tensorflow.random_normal_initializer,返回的变量已经被初始化。希望这可以澄清为什么您的代码有这种行为。