我正在使用以 dice_loss 作为训练损失函数的 U-Net 模型进行图像分割(多类)。用平滑项分别计算每个类的骰子分数,然后取所有类的平均骰子分数来计算损失。下面是我如何计算张量流中的骰子损失。
def dice_loss(y_true, y_pred, smooth=1e-7):
# y_true : shape=(BATCH_SIZE, HIEGHT, WIDTH, CHANNELS)
# y_pred : shape=(BATCH_SIZE, HIEGHT, WIDTH, CHANNELS)
nom = tf.reduce_sum(y_true*y_pred, axis=(1,2))
denom = tf.reduce_sum(y_true, axis=(1,2)) + tf.reduce_sum(y_pred, axis=(1,2))
dice_score = (2 * nom + smooth) / (denom + smooth)
mean_dice_score = tf.reduce_mean(dice_score, axis=-1)
return 1 - mean_dice_score
最后将批次中所有图像的平均值作为损失。
现在,在推理过程中,我以类似的方式计算骰子得分,但每个班级的骰子得分是单独报告的,而不是所有班级的平均值。下面是如何计算 tensorflow 中单个类的骰子分数
def compute_dice_score(y_true, y_pred, num_classes, class_idx, smooth=1e-7):
# y_true : shape=(BATCH_SIZE, HIEGHT, WIDTH, CHANNELS)
# y_pred : shape=(BATCH_SIZE, HIEGHT, WIDTH, CHANNELS)
y_pred = tf.one_hot(tf.argmax(y_pred, axis=3), num_classes)
y_pred = y_pred[..., class_idx]
y_true = y_true[..., class_idx]
nom = tf.reduce_sum(y_true*y_pred, axis=(1,2))
denom = tf.reduce_sum(y_true, axis=(1,2)) + tf.reduce_sum(y_pred, axis=(1,2))
dice_score = (2 * nom + smooth) / (denom + smooth)
return dice_score
最后计算批次中所有图像的平均骰子分数。
在训练时,我取单个图像的平均骰子得分,然后对批次进行平均,因为这对我的数据集更有效,而不是一起计算整个批次的所有骰子得分。
我的问题是在推理期间
- 我应该分别计算每个图像的骰子分数,然后对批次取平均值还是一起计算整个批次的骰子分数?哪个是正确的方法?
- 同样在推理过程中,骰子分数计算中的平滑项是否应该存在?