TensorFlow 2 自定义损失:“没有为任何变量提供梯度"错误 [英] TensorFlow 2 custom loss: "No gradients provided for any variable" error

查看:32
本文介绍了TensorFlow 2 自定义损失:“没有为任何变量提供梯度"错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我必须在 TensorFlow 2 中解决一个图像分割问题.

I have an image segmentation problem I have to solve in TensorFlow 2.

特别是我有一个由航拍图像与各自的面具配对组成的训练集.在面具中,地形为黑色,建筑物为白色.目的是预测测试集中图像的掩码.

In particular I have a training set composed by aerial images paired with their respective masks. In a mask the terrain is colored in black and the buildings are colored in white. The purpose is to predict the mask for the images in the test set.

我使用带有最终 Conv2DTranspose 的 UNet,带有 1 个过滤器和一个 sigmoid 激活函数.对最终sigmoid层的输出按以下方式进行预测:如果y_pred>0.5,则为建筑物,否则为背景.

I use a UNet with a final Conv2DTranspose with 1 filter and a sigmoid activation function. The prediction is made in the following way on the output of the final sigmoid layer: if y_pred>0.5, then it's a building, otherwise it's the background.

我想实现一个骰子的损失,所以我写了下面的函数

I want to implement a dice loss, so I wrote the following function

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:

which I pass to TensorFlow in the following way:

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 抛出以下错误:

but at training time TensorFlow throw me the following error:

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

ValueError: No gradients provided for any variable:

推荐答案

问题出在你的损失函数上(显然).特别是以下操作.

The problem is in your loss function (obviously). Particularly, the following operation.

y_pred = tf.cast(y_pred > 0.5, tf.float32)

这不是可微分操作.这导致梯度为无.将您的损失函数更改为以下内容,它将起作用.

This is not a differentiable operation. Which results in Gradients being None. Change your loss function to the following and it will work.

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 自定义损失:“没有为任何变量提供梯度"错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆