首页 > 解决方案 > 没有为自定义损失函数的任何变量提供梯度

问题描述

我在 Keras 中创建了一个自定义损失函数,如下所示:

import tensorflow as tf
import numpy as np
def custom_loss(y_true, y_pred):
   cce = tf.keras.losses.CategoricalCrossentropy()
   loss = cce(y_true, y_pred).numpy()

   epsilon = np.finfo(np.float32).eps
   confidence = np.clip(y_true.numpy(), epsilon, 1.-epsilon)
   sample_entropy = -1. * np.sum(np.multiply(confidence, np.log(confidence) / np.log(np.e)), axis=-1)
   entropy = np.mean(sample_entropy)
   penalty = 0.1 * -entropy
   
   return loss + penalty

当我使用这个自定义损失函数时,我收到了错误消息

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

现在不知何故可以计算梯度。需要如何更改损失函数才能计算梯度?

标签: pythonmachine-learningkerastensorflow2.0tf.keras

解决方案


Tensorflow 需要tensor存储依赖信息以让梯度flow向后,如果你在损失函数中将张量转换为 numpy 数组,那么你打破了这种依赖关系,因此没有为任何变量提供梯度,所以你需要将np损失函数中的每个操作更改为对应的tfbackend操作,例如:

import tensorflow as tf
import numpy as np

cce = tf.keras.losses.CategoricalCrossentropy()
epsilon = np.finfo(np.float32).eps

def custom_loss(y_true, y_pred):
    loss = cce(y_true, y_pred)
    confidence = tf.clip_by_value(y_true, epsilon, 1.-epsilon)
    sample_entropy = -1. * tf.reduce_sum(tf.math.multiply(confidence, tf.math.log(confidence) / tf.math.log(np.e)), axis=-1)
    entropy = tf.reduce_mean(sample_entropy)
    penalty = 0.1 * -entropy
    return loss + penalty

推荐阅读