没有为任何变量提供渐变来增加tf.while_loop中的Loss值

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了没有为任何变量提供渐变来增加tf.while_loop中的Loss值相关的知识,希望对你有一定的参考价值。

我有一个CNN架构,包括一些层 - 卷积,完全连接和解卷积 - (用第一个过程称它)。最后一个反卷积层给了我作为输出的点,我需要用这个输出做一些处理(用第二个过程调用它)来得到Loss值。

在第二个过程中,我正在使用tf.while_loop来计算Loss值,因为Loss值是通过在Loss中添加每次迭代的所有tf.while_loop值来实现的。我在循环之前给tf.constant(0)初始化Loss

当我试图训练并最小化那个Loss时,它向我显示了第一个过程的输出和损失张量之间提供的无梯度误差。

第二个过程如下所示:

loss = tf.constant(0)
i = tf.constant(0)

def cond(i, loss):
    return tf.less(i, tf.size(xy))

def body(i, loss):
    # xy is the output from the first process
    xy = tf.cast(xy, tf.float32)
    x = tf.reduce_mean(xy) 
    loss = tf.add(loss, x)
    return [tf.add(i,1), loss]
r = tf.while_loop(cond, body, [i, loss])

optimizer.minimize(r[1])

我也在第二个过程中做了一些处理(我从许多帖子中读到,特别是here)不提供渐变。

任何帮助将非常感激。

答案

您将收到该错误的原因有多种。如果没有真正看到原始代码,可能很难调试,但这里至少有两个原因:为什么没有提供渐变:

  1. 存在一些张量流操作,梯度不能流动或不能发生反向传播。例如tf.casttf.assign等。在您链接的帖子中,有一条评论提及this。因此,在您提供tf.cast的示例中肯定会导致问题。 解决此问题的方法是重构代码,使您不使用不允许渐变通过它们的tensorflow操作。
  2. 可能发生这种情况的第二个原因是当您尝试使用未在这些变量上计算的损失来优化变量时。例如,如果您在conv1变量的第一个过程中计算了损失,然后在第二个过程中尝试更新/优化conv2变量。这不起作用,因为将为conv1变量而不是conv2计算梯度。

看起来在你的情况下,它很可能是第一个问题,而不是第二个问题。

以上是关于没有为任何变量提供渐变来增加tf.while_loop中的Loss值的主要内容,如果未能解决你的问题,请参考以下文章

简单的 TensorFlow LSTM 网络:ValueError:没有为任何变量提供梯度

Tensorflow ValueError:没有为任何变量提供梯度

Tensorflow Autoencoder ValueError:没有为任何变量提供梯度

ValueError:没有为任何变量提供梯度 - Tensorflow 2.0/Keras

Tensorflow:实现新的损失函数返回“ValueError:没有为任何变量提供梯度”

TensorFlow 2 自定义损失:“没有为任何变量提供梯度”错误