我想编写一个自定义损失函数,该函数使用与 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
任何帮助将不胜感激!
您遇到的自定义损失函数 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