使用 tf.numpy_function loss 时没有为任何变量提供梯度

问题描述 投票:0回答:1

我想编写一个自定义损失函数,该函数使用与 scipy 的 Wasserstein 距离:

from scipy.stats import wasserstein_distance

我使用

tf.numpy_function
进行了编码,因为我需要将 numpy 数组传递给
wasserstein_distance
函数:

@tf.numpy_function(Tout=tf.float32)
def distance(y_true, y_pred):
    dist = np.abs(wasserstein_distance(y_true.ravel(), y_pred.ravel()))
    return dist.astype(np.float32)

@tf.function(input_signature=[tf.TensorSpec(None, tf.float32), tf.TensorSpec(None, tf.float32)])
def wasserstein_loss(y_true, y_pred):
    loss = tf.numpy_function(distance, [y_true, y_pred], tf.float32)
    return loss

当我急切地评估

distance
玩具数据时:

y_true = np.random.random((10,1)).astype(np.float32)
y_pred = np.random.random((10,1)).astype(np.float32)

它的评价很好:

distance(y_true, y_pred).numpy()

0.070802614

此外,两个函数都返回一个张量:

distance(y_true, y_pred)

<tf.Tensor: shape=(), dtype=float32, numpy=0.070802614>
wasserstein_loss(tf.Variable(y_true, tf.float32), tf.Variable(y_pred, tf.float32))

<tf.Tensor: shape=(), dtype=float32, numpy=0.070802614>

但是当我在

wasserstein_loss
中使用
model.compile()
作为损失函数,然后尝试执行
model.fit()
时,我收到错误:

ValueError: No gradients provided for any variable

任何帮助将不胜感激!

python numpy tensorflow keras
1个回答
0
投票

您遇到的自定义损失函数 wasserstein_loss 在训练期间不提供优化梯度的问题可能源于在 tf.function 中使用 tf.numpy_function 。 TensorFlow 的自动微分机制无法通过使用 tf.numpy_function 定义的操作自动微分。

要解决此问题,您可以使用 TensorFlow 运算直接在 TensorFlow 中实现 Wasserstein 距离,或者使用梯度带 (tf.GradientTape) 手动计算梯度。以下是如何在 TensorFlow 中实现 Wasserstein 距离的示例:

import tensorflow as tf

def wasserstein_distance(y_true, y_pred):
    return tf.reduce_mean(tf.abs(y_true - y_pred))

def wasserstein_loss(y_true, y_pred):
    loss = wasserstein_distance(y_true, y_pred)
    return loss

# Example usage:
y_true = tf.constant([[1.0], [2.0], [3.0]], dtype=tf.float32)
y_pred = tf.constant([[1.5], [2.5], [3.5]], dtype=tf.float32)

loss = wasserstein_loss(y_true, y_pred)
print(loss.numpy())  # Output: 0.5
© www.soinside.com 2019 - 2024. All rights reserved.