gpt4 book ai didi

python - Tensorflow:对前向和后向传递使用不同的表达式

转载 作者:太空宇宙 更新时间:2023-11-03 15:46:15 26 4
gpt4 key购买 nike

我有一个 tensorflow 表达式,我想在其中使用不同的表达式,具体取决于我是在计算前向还是后向(梯度)传递。具体来说,我想忽略在向后传递过程中添加到网络中的一些随机性(噪声)的影响。

这是一个简单的例子

import numpy as np
import tensorflow as tf

x = tf.placeholder(tf.float32)
y = x**2
u = tf.random_uniform(tf.shape(x), minval=0.9, maxval=1.1)
yu = y * u
z = tf.sqrt(yu)
g = tf.gradients(z, x)[0]

with tf.Session() as sess:
yv, yuv, zv, gv = sess.run([y,yu,z,g], {x: [-2, -1, 1]})

print(yv)
print(yuv)
print(zv)
print(gv)

输出类似

[4. 1. 1.]
[4.1626534 0.9370764 1.0806011]
[2.0402582 0.96802706 1.0395197 ]
[-1.0201291 -0.96802706 1.0395197 ]

此处的最后一个值是 z 相对于 x 的导数。我希望它们不包括乘法噪声项 u,即对于 x 的这些输入值,它们应该始终为 [-1, -1, 1]

有没有办法只使用 Python 来做这样的事情?我知道我可以在 C 中创建自定义运算符并为其定义自定义渐变,但我想尽可能避免这种情况。

此外,我希望将其用作 Keras 层的一部分,因此基于 Keras 的解决方案将是一种替代方案(即,如果可以为通过 Keras 层的前向和后向传递定义不同的表达式)。这确实意味着仅定义第二个表达式 z2 = tf.sqrt(y) 并在其上调用 gradients 对我来说不是解决方案,因为我不我不知道如何将其放入 Keras(因为在 Keras 中,它将成为非常长的计算图的一部分)。

最佳答案

简短的回答是,您在上面提到的 Sergey Ioffe 的技巧只有在图形的最后应用时才有效,就在梯度计算之前。

我假设您尝试了以下方法,但不会起作用:

yu_fixed = tf.stop_gradient(yu - y) + y
z = tf.sqrt(yu_fixed)

这仍然会输出随机污染的梯度。

为了了解原因,让我们继续进行梯度计算。让我们使用 s 作为 tf.stop_gradient 的简写。它的工作方式是,当 TensorFlow 需要计算 s(expr) 时,它只返回 expr,但是当它需要计算 s(expr) 的梯度时),它返回 0。

我们要计算 z = sqrt(s(yu - y) + y) 的梯度。现在,因为 \frac{\partial \sqrt{f(x)}}{\partial x} = \frac{1}{2\sqrt{f(x)}} \frac{\partial f(x)}{\partial x} ,我们发现 z 的梯度既包含 s() 的导数项,也包含 s() 本身的项。后一项不会将 s() 部分归零,因此 z 的计算导数将取决于(以某种奇怪且不正确的方式)值 yu 。这就是为什么上述解决方案在梯度中仍然包含随机性。

据我所知,解决此问题的唯一方法是将 Ioffe 的技巧应用为 tf.gradient 之前的最后阶段。换句话说,如果您执行以下操作,您将获得预期的结果:

x = tf.placeholder(tf.float32)
y = x**2
u = tf.random_uniform(tf.shape(x), minval=0.9, maxval=1.1)
yu = y * u
z = tf.sqrt(yu)
z_fixed = tf.stop_gradient(z - tf.sqrt(y)) + tf.sqrt(y)
g = tf.gradients(z_fixed, x)[0]

with tf.Session() as sess:
yv, yuv, zv, gv = sess.run([y,yu,z_fixed,g], {x: [-2, -1, 1]})

print(yv)
print(yuv)
print(zv)
print(gv)

输出:

[ 4.  1.  1.]
[ 3.65438652 1.07519293 0.94398856]
[ 1.91164494 1.03691506 0.97159076]
[-1. -1. 1.]

关于python - Tensorflow:对前向和后向传递使用不同的表达式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49757285/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com