TensorFlow 2 自定义损失:“没有为任何变量提供梯度”错误
Posted
技术标签:
【中文标题】TensorFlow 2 自定义损失:“没有为任何变量提供梯度”错误【英文标题】:TensorFlow 2 custom loss: "No gradients provided for any variable" error 【发布时间】:2020-04-05 03:51:07 【问题描述】:我有一个必须在 TensorFlow 2 中解决的图像分割问题。
特别是我有一个训练集,由航空图像及其各自的蒙版组成。在蒙版中,地形以黑色着色,建筑物以白色着色。目的是预测测试集中图像的掩码。
我使用带有最终 Conv2DTranspose 的 UNet,带有 1 个过滤器和 sigmoid 激活函数。在最终的 sigmoid 层的输出上通过以下方式进行预测:如果 y_pred>0.5,则为建筑物,否则为背景。
我想实现一个骰子损失,所以我写了以下函数
def dice_loss(y_true, y_pred):
print("[dice_loss] y_pred=",y_pred,"y_true=",y_true)
y_pred = tf.cast(y_pred > 0.5, tf.float32)
y_true = tf.cast(y_true, tf.float32)
numerator = 2 * tf.reduce_sum(y_true * y_pred)
denominator = tf.reduce_sum(y_true + y_pred)
return 1 - numerator / denominator
我通过以下方式传递给 TensorFlow:
loss = dice_loss
optimizer = tf.keras.optimizers.Adam(learning_rate=config.learning_rate)
metrics = [my_IoU, 'acc']
model.compile(optimizer=optimizer, loss=loss, metrics=metrics)
但在训练时 TensorFlow 向我抛出以下错误:
ValueError:没有为任何变量提供渐变:
【问题讨论】:
【参考方案1】:问题在于您的损失函数(显然)。特别是下面的操作。
y_pred = tf.cast(y_pred > 0.5, tf.float32)
这不是可微分运算。这导致渐变为无。将您的损失函数更改为以下内容,它将起作用。
def dice_loss(y_true, y_pred):
print("[dice_loss] y_pred=",y_pred,"y_true=",y_true)
y_true = tf.cast(y_true, tf.float32)
numerator = 2 * tf.reduce_sum(y_true * y_pred)
denominator = tf.reduce_sum(y_true + y_pred)
return 1 - numerator / denominator
【讨论】:
以上是关于TensorFlow 2 自定义损失:“没有为任何变量提供梯度”错误的主要内容,如果未能解决你的问题,请参考以下文章
AttributeError:“Tensor”对象在自定义损失函数中没有属性“numpy”(Tensorflow 2.1.0)
Tensorflow:实现新的损失函数返回“ValueError:没有为任何变量提供梯度”
TensorFlow2 入门指南 | 15 默认损失函数 & 自定义损失函数