在具有不同真实和输出通道的多类分割问题中如何计算损失?(UNET,骰子丢失)



我试图理解在UNET的情况下如何计算损失,该数据集具有21个类(1个掩码,21种不同颜色,每种颜色表示一个类(。因此,真实形状为 N * M * 1(灰度图像,每个像素值代表类颜色(黑色代表背景,绿色代表树木等((。但输出形状为 N*M*21(它返回 21 张与输入大小相同的图像(。我的问题是,在这种情况下如何计算损失?当您的目标形状为 N * M * 1 并且输出形状(预测张量(为 N * M * 21 时。

我的解释是,N * M 是每个类标签的预测图像(第 0 个(假设背景(标签的第 1 个 N * M 预测图像,第一个标签(假设树(的第 2 个 N * M 预测图像(等等。有点像一个与休息的方法。

我正在使用在此库中实现的UNET segmentation_models。 我真的很困惑,请帮忙。

是的,你的解释很好。

实际上,掩码(基本实况ys(的创建方式是,如果你有K个类,那么你将有K个维度为H x W的矩阵。

假设您有一个问题,即树木,行人和汽车的细分。这里 K = 3,例如,树的输入掩码是一个维度为 H x W 的矩阵,其中基本事实仅在树所在的位置标记为 1,否则标记为 0。然后,对于与行人对应的第二个掩码,仅在行人所在的地方用 1 标记地面实况,否则用 0 标记。这就是我们构建数据集的方式,因为我们具有多类分割而不是多标签分割,其中 1 在不同掩码上重叠是可能的。

是的,输入图像确实像您描述的那样是灰度的,值介于 [0,number_of_classes] 之间,但网络并没有像您可能怀疑的那样接收到输入的地面事实。

事实上,如果你仔细查看教程中的这些代码行(Keras 和 PyTorch 也是如此(,你可以看到以下代码片段:

# extract certain classes from mask (e.g. cars)
masks = [(mask == v) for v in self.class_values]
mask = np.stack(masks, axis=-1).astype('float')

我上面描述的过程发生其中。

现在我们已经准备好了,继续执行损失函数很简单:它的工作原理就好像你只有一个带有 1 和 0 的掩码,但它适应了 H x W x K 的情况,而不是 H x W x K。

请记住:

gt: ground truth 4D keras tensor (B, H, W, C) or (B, C, H, W)
pr: prediction 4D keras tensor (B, H, W, C) or (B, C, H, W)

通过检查这些代码行,您将解决您的困境:

backend = kwargs['backend']
gt, pr = gather_channels(gt, pr, indexes=class_indexes, **kwargs)
pr = round_if_needed(pr, threshold, **kwargs)
axes = get_reduce_axes(per_image, **kwargs)
# score calculation
intersection = backend.sum(gt * pr, axis=axes)
union = backend.sum(gt + pr, axis=axes) - intersection
score = (intersection + smooth) / (union + smooth)
score = average(score, per_image, class_weights, **kwargs)

最新更新