我想对两个图像实施傅立叶环相关损失,以训练GAN。因此,我想循环特定的时间并计算损失。这对于正常的Python循环来说效果很好。为了加快此过程,我想使用tf.while_loop
,但不幸的是,我无法通过while循环跟踪渐变。我构建了一个虚拟示例,只是为了在while循环中计算梯度,但是它不起作用。首先,有效的python循环:
x = tf.constant(3.0)
y = tf.constant(2.0)
for i in range(3):
y = y * x
grad = tf.gradients(y, x)
with tf.Session() as ses:
print("output : ", ses.run(grad))
这有效并提供了输出
[54]
如果我对tf.while_loop做同样的操作,将无法正常工作:
a = tf.constant(0, dtype = tf.int64)
b = tf.constant(3, dtype = tf.int64)
x = tf.constant(3.0)
y = tf.constant(2.0)
def cond(a,b,x,y):
return tf.less(a,b)
def body(a,b,x,y):
y = y * x
with tf.control_dependencies([y]):
a = a + 1
return [a,b,x,y]
results = tf.while_loop(cond, body, [a,b,x,y], back_prop = True)
grad = tf.gradients(y, results[2])
with tf.Session() as ses:
print("grad : ", ses.run(grad))
输出为:
TypeError:获取参数None具有无效的类型'<'class'NoneType'>
所以我猜想tensorflow无法以某种方式进行反向传播。
如果使用tf.GradientTape()而不是tf.gradients(),问题仍然会出现。
答案 0 :(得分:0)
我更改了代码,以便现在可以输出渐变:
import tensorflow as tf
a = tf.constant(0, dtype = tf.int64)
b = tf.constant(3, dtype = tf.int64)
x = tf.Variable(3.0, tf.float32)
y = tf.Variable(2.0, tf.float32)
dy = tf.Variable(0.0, tf.float32)
def cond(a,b,x,y,dy):
return tf.less(a,b)
def body(a,b,x,y,dy):
y = y * x
dy = tf.gradients(y, x)[0]
with tf.control_dependencies([y]):
a = a + 1
return [a,b,x,y,dy]
init = tf.global_variables_initializer()
with tf.Session() as ses:
ses.run(init)
results = ses.run(tf.while_loop(cond, body, [a,b,x,y,dy], back_prop = True))
print("grad : ", results[-1])
我修改过的东西
x
和y
制成了变量,并添加了它们的初始化init
。dy
的变量,它将包含y的梯度。tf.while_loop
。我认为以前的问题是,当您定义grad = tf.gradients(y, results[2])
时,循环尚未运行,因此y不是x的函数。因此,没有渐变。
希望这会有所帮助。