自定义损失函数时,显示没有梯度

自定义了一个损失函数 报错显示没有可获得梯度:

def R_lab_enmin(y_true, y_pred):
y_true = tf.cast(y_true, dtype=tf.float32)

out = tf.clip_by_value(y_true, -10, 10)

y_pred = tf.sigmoid(out)
loss1 = Rlab_loss1(y_true, y_pred)       # Rlab损失

# 熵最小化损失
y_true, y_pred = tf.reshape(y_true, (len(y_true),)), tf.reshape(y_pred, (len(y_pred),))
scores = tf.gather(y_pred, tf.where(y_true != 1))

loss2 = -tf.reduce_mean(scores * tf.math.log(scores) + (1 - scores) * tf.math.log(1 - scores))

loss=loss1 + 0.004 * loss2
return loss

ValueError: No gradients provided for any variable: ['dense/kernel:0', 'dense/bias:0', 'batch_normalization/gamma:0', 'batch_normalization/beta:0', 'dense_1/kernel:0', 'dense_1/bias:0', 'batch_normalization_1/gamma:0', 'batch_normalization_1/beta:0', 'dense_2/kernel:0', 'dense_2/bias:0', 'batch_normalization_2/gamma:0', 'batch_normalization_2/beta:0', 'dense_3/kernel:0', 'dense_3/bias:0', 'batch_normalization_3/gamma:0', 'batch_normalization_3/beta:0', 'dense_4/kernel:0', 'dense_4/bias:0'].

“Devil组”引证GPT后的撰写:

  • 这个错误通常表示TensorFlow无法计算损失函数的梯度。这可能是由于损失函数中使用了不可微分的操作或没有正确设置梯度计算方式等原因引起的。
  • 在这个特定的例子中,你可能需要检查损失函数R_lab_enmin中的Rlab_loss1和tf.clip_by_value操作是否可微分,如果不可微分,则需要将它们替换为可微分的操作或使用其它方式实现该操作。
  • 此外,你也可以尝试显式指定梯度计算方式,比如使用tf.GradientTape或设置损失函数的可训练变量。

例如,你可以将损失函数定义为:

def R_lab_enmin(y_true, y_pred):
    y_true = tf.cast(y_true, dtype=tf.float32)
    with tf.GradientTape() as tape:
        tape.watch(y_pred)
        out = tf.clip_by_value(y_true, -10, 10)
        y_pred = tf.sigmoid(out)
        loss1 = Rlab_loss1(y_true, y_pred)
        scores = tf.gather(y_pred, tf.where(y_true != 1))
        loss2 = -tf.reduce_mean(scores * tf.math.log(scores) + (1 - scores) * tf.math.log(1 - scores))
        loss = loss1 + 0.004 * loss2
    gradients = tape.gradient(loss, y_pred)
    return loss, gradients


然后在训练时调用该函数并传递梯度到优化器中。

谢谢您的回答,我找到了原因. 因为和模型相关的y_pred,即模型的输出并没有用在损失函数中,导致没有梯度
out = tf.clip_by_value(y_true, -10, 10)这里出现错误
应该改为 out = tf.clip_by_value(y_pred, -10, 10)