如何在具有不同地面实况和输出通道的 multi class 分割问题中计算损失? (UNET,骰子损失)
How the loss is computed in multi class segmentation problem which has different ground truth and output channels? (UNET, dice loss)
我试图了解在 UNET 的情况下如何计算损失,以在具有 21 classes 的数据集上进行训练(1 个掩码具有 21 种不同的颜色,每种颜色表示 class ).因此,真值形状为 N * M * 1(灰度图像,每个像素值代表 class 颜色(黑色代表背景,绿色代表树木等))。但是输出形状是 N*M*21(它 returns 21 个与输入大小相同的图像)。我的问题是,在这种情况下如何计算损失?当你的目标形状为 N * M * 1 并且输出形状(预测张量)为 N * M * 21.
我的解释是,N * M 是每个 class 标签的预测图像(第 0 个(比方说背景)标签的第 1 个 N * M 预测图像,第 1 个标签的第 2 个 N * M 预测图像标签(比方说树)等等。有点像 one vs rest 方法。
我正在使用在此库中实现的 UNET segmentation_models。
我真的很困惑,请帮助。
是的,你的解读很好
实际上,masks(ground truth ys) 的创建方式是,如果你有 K classes,那么你就会有 K 个维度为 H x W 的矩阵。
假设您有一个关于树木、行人和汽车的分割问题。这里 K = 3,例如,树的输入掩码是一个维度为 H x W 的矩阵,其中仅在树所在的地方标记为 1,否则标记为 0。然后,对于对应于行人的第二个掩码,仅在行人所在的地方将 ground truth 标记为 1,否则标记为 0。这是我们构建数据集的方式,因为我们有 multi-class segmentation 而不是 multi-label segmentation,其中 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 宽 x 宽
考虑到:
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)
我试图了解在 UNET 的情况下如何计算损失,以在具有 21 classes 的数据集上进行训练(1 个掩码具有 21 种不同的颜色,每种颜色表示 class ).因此,真值形状为 N * M * 1(灰度图像,每个像素值代表 class 颜色(黑色代表背景,绿色代表树木等))。但是输出形状是 N*M*21(它 returns 21 个与输入大小相同的图像)。我的问题是,在这种情况下如何计算损失?当你的目标形状为 N * M * 1 并且输出形状(预测张量)为 N * M * 21.
我的解释是,N * M 是每个 class 标签的预测图像(第 0 个(比方说背景)标签的第 1 个 N * M 预测图像,第 1 个标签的第 2 个 N * M 预测图像标签(比方说树)等等。有点像 one vs rest 方法。
我正在使用在此库中实现的 UNET segmentation_models。 我真的很困惑,请帮助。
是的,你的解读很好
实际上,masks(ground truth ys) 的创建方式是,如果你有 K classes,那么你就会有 K 个维度为 H x W 的矩阵。
假设您有一个关于树木、行人和汽车的分割问题。这里 K = 3,例如,树的输入掩码是一个维度为 H x W 的矩阵,其中仅在树所在的地方标记为 1,否则标记为 0。然后,对于对应于行人的第二个掩码,仅在行人所在的地方将 ground truth 标记为 1,否则标记为 0。这是我们构建数据集的方式,因为我们有 multi-class segmentation 而不是 multi-label segmentation,其中 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 宽 x 宽
考虑到:
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)