我在TensorFlow 2中必须解决图像分割问题。
特别是我有一个训练集,它由航空影像和它们各自的遮罩组成。戴着面具,地形被涂成黑色,建筑物被涂成白色。目的是预测测试集中图像的遮罩。
我使用带有最终Conv2DTranspose的UNet,该Conv2DTranspose具有1个过滤器和S型激活函数。在最终的S型层输出上以以下方式进行预测:如果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:没有为任何变量提供渐变:
答案 0 :(得分: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