使用TensorFlow 2实现梯度惩罚损失函数

4

早上好,

我正在尝试按照这篇论文描述的方式,实现改进的WGAN来处理1D数据: https://arxiv.org/pdf/1704.00028.pdf

keras-contrib github中有一个示例实现: https://github.com/keras-team/keras-contrib/blob/master/examples/improved_wgan.py 然而,使用tf2时梯度惩罚损失的这个实现已经不再有效。K.gradients()返回[None]。

ValueError: in user code:

    /usr/local/lib/python3.6/dist-packages/tensorflow/python/keras/engine/training.py:505 train_function  *
        outputs = self.distribute_strategy.run(
    /usr/local/lib/python3.6/dist-packages/tensorflow/python/distribute/distribute_lib.py:951 run  **
        return self._extended.call_for_each_replica(fn, args=args, kwargs=kwargs)
    /usr/local/lib/python3.6/dist-packages/tensorflow/python/distribute/distribute_lib.py:2290 call_for_each_replica
        return self._call_for_each_replica(fn, args, kwargs)
    /usr/local/lib/python3.6/dist-packages/tensorflow/python/distribute/distribute_lib.py:2649 _call_for_each_replica
        return fn(*args, **kwargs)
    /usr/local/lib/python3.6/dist-packages/tensorflow/python/keras/engine/training.py:467 train_step  **
        y, y_pred, sample_weight, regularization_losses=self.losses)
    /usr/local/lib/python3.6/dist-packages/tensorflow/python/keras/engine/compile_utils.py:204 __call__
        loss_value = loss_obj(y_t, y_p, sample_weight=sw)
    /usr/local/lib/python3.6/dist-packages/tensorflow/python/keras/losses.py:143 __call__
        losses = self.call(y_true, y_pred)
    /usr/local/lib/python3.6/dist-packages/tensorflow/python/keras/losses.py:246 call
        return self.fn(y_true, y_pred, **self._fn_kwargs)
    <ipython-input-7-4f0896d0107b>:104 gradient_penalty_loss
        gradients_sqr = K.square(gradients)
    /usr/local/lib/python3.6/dist-packages/tensorflow/python/keras/backend.py:2189 square
        return math_ops.square(x)
    /usr/local/lib/python3.6/dist-packages/tensorflow/python/ops/gen_math_ops.py:9964 square
        "Square", x=x, name=name)
    /usr/local/lib/python3.6/dist-packages/tensorflow/python/framework/op_def_library.py:488 _apply_op_helper
        (input_name, err))

    ValueError: Tried to convert 'x' to a tensor and failed. Error: None values not supported.

这里是问题的完整示例: https://colab.research.google.com/drive/11dcMKoiCigTnEn7QvmjqLNrJdmFztByT 有人知道发生了什么变化吗?有什么解决方法吗?
更新:忽略构建计算图时出现的错误,然后它似乎可以运行。
def gradient_penalty_loss(y_true, y_pred, averaged_samples):
  gradients = K.gradients(y_pred, averaged_samples)[0]
  try:
    gradients_sqr = K.square(gradients)
  except ValueError:
    print("Gradients returned None")
    return 0
  gradients_sqr_sum = K.sum(gradients_sqr, axis=np.arange(1, len(gradients_sqr.shape)))
  gradient_l2_norm = K.sqrt(gradients_sqr_sum)

  gradient_penalty = K.square(1 - gradient_l2_norm)

  return K.mean(gradient_penalty)

然而,我的损失函数越来越高,是否忽略了gradient_penalty_loss? 损失函数

1
我正在研究非常相似的问题。承诺任何事情都为时过早,但是我刚刚通过禁用急切执行(tensorflow.compat.v1.disable_eager_execution())成功消除了相关错误。如果您确实需要急切执行,则需要使用gradienttape。我暂时不会将此写成答案,但是我想如果这仍然阻止您,那么您可能更喜欢一些即将可行而不是稍后可行的东西。 - Josiah
1
你好,Josiah!感谢你的回答,问题似乎朝着那个方向解决了。我设法通过捕获错误来解决它,看起来只有在构建计算图时才会产生错误。(我将在帖子中发布代码)。然后它似乎运行得很好!我不知道的是,忽略构建图时的错误是否会使tensorflow忽略损失函数。 - Pablo Martín Redondo
1个回答

0
如果按照更新中提出的方法进行操作,tf将会忽略损失函数。
在Tensorflow 2中,以前的方式似乎不再可行。我最终改变了代码,使其适应这种创建模型的方式。我的建议是:
1. 使用keras创建生成器和鉴别器模型。 2. 扩展tf.keras.Model类,将它们合并起来,就像WGAN一样:https://github.com/timsainb/tensorflow2-generative-models

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接