多类分割One-hot 编码实现方式(转)

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了多类分割One-hot 编码实现方式(转)相关的知识,希望对你有一定的参考价值。

参考技术A

原链接: 数据预处理 One-hot 编码的两种实现方式

最直观的理解就是,比如说现在有三个类别 A、B、C ,它们对应的标签值分别为 [1, 2, 3] ,如果对这三个类别使用One-hot编码,得到的结果则是, [[1, 0, 0], [0, 1, 0], [0, 0, 1]] ,相当于:

分割任务 中,网络模型最后的输出shape为 [N, C, H, W] (以pytoch为例, 其中N为batch_size, C为预测的类别数),而我们给的的gt(ground truth)的shape一般为 [H, W, 3](彩色图或rgb图)或 [H, W] (灰度图)。
假设我们现在的分割任务里面有5个目标需要分割,给定的gt是彩色的。则网络模型最后的输出shape为 [N, 5, H, W] ,这和gt的shape不匹配,在训练的时候它们两者之间不能进行损失值计算。因此,就需要使用One-hot编码对gt进行编码,将其编码为 [H, W, 5] ,最后再对维度进行transpose即可。

编码前和编码后的变化类似图中所示(上图对应编码前,下图对应编码后)。

mask_to_onehot 用来将标签进行one-hot, onehot_to_mask 用来恢复one-hot,在可视化的时候使用。

方法一在使用的时候需要先定义好颜色表palette(根据自己的数据集来定义就行了)。下面演示两个例子。

假设gt是灰度图,需要分割两个目标(正常器官和肿瘤)(加上背景就是3分类任务),正常器官的灰度值为128,肿瘤的灰度值为255, 背景的灰度值为0。

假设gt彩色图,需要分割5个目标(加上背景就是6分类任务),颜色值如下。 和灰度图的处理方法类似。

为了以示区别,名字不要起的一样。

用法:如果gt是灰度图,如上面的例子,用起来就比较简单。

如果gt是彩色图,要先把rgb颜色值映射为标签,再进行one-hot编码,相对来说就比较繁琐了。直接用方法一就行了。

医学图像分割多目标分割(多分类)实践

二分类和多分类基本差不多,二分类的标签图像像素值处理成0和1组成的矩阵,多分类(N类)的标签图像处理成N层0和1组成的矩阵,即one-hot编码。二分类最后一层的激活函数activation是sigmoid函数,多分类的则是softmax函数。然后对应的损失函数loss分别是binary_crossentropy和categorical_crossentropy。其他的包括基本原理是相同的。

keras/tensorflow中语义图像分割的多类加权损失

【中文标题】keras/tensorflow中语义图像分割的多类加权损失【英文标题】:Multi-class weighted loss for semantic image segmentation in keras/tensorflow 【发布时间】:2020-04-18 14:35:24 【问题描述】:

给定批处理 RGB 图像作为输入,shape=(batch_size, width, height, 3)

一个多类目标表示为 one-hot,shape=(batch_size, width, height, n_classes)

还有一个模型(Unet、DeepLab)在最后一层激活了 softmax。

我正在寻找 kera/tensorflow 中的加权分类交叉熵损失函数。

fit_generator 中的class_weight 参数似乎不起作用,我在这里或https://github.com/keras-team/keras/issues/2115 中都没有找到答案。

def weighted_categorical_crossentropy(weights):
    # weights = [0.9,0.05,0.04,0.01]
    def wcce(y_true, y_pred):
        # y_true, y_pred shape is (batch_size, width, height, n_classes)
        loos = ?...
        return loss

    return wcce

【问题讨论】:

多类目标是指考虑了超过 1 个可能的结果吗? “结果”是什么意思? Multiclass=不同的像素值表示不同的类别。你可以有两个以上的课程。 (2 类=二元分类) 多类分类是一种不同类型的分类问题,其中不止一个类是真实的,我对此感到困惑。 【参考方案1】:

我会回答我的问题:

def weighted_categorical_crossentropy(weights):
    # weights = [0.9,0.05,0.04,0.01]
    def wcce(y_true, y_pred):
        Kweights = K.constant(weights)
        if not K.is_tensor(y_pred): y_pred = K.constant(y_pred)
        y_true = K.cast(y_true, y_pred.dtype)
        return K.categorical_crossentropy(y_true, y_pred) * K.sum(y_true * Kweights, axis=-1)
    return wcce

用法:

loss = weighted_categorical_crossentropy(weights)
optimizer = keras.optimizers.Adam(lr=0.01)
model.compile(optimizer=optimizer, loss=loss)

【讨论】:

【参考方案2】:

我正在使用广义骰子损失。在我的情况下,它比加权分类交叉熵更好。我的实现是在 PyTorch 中,但是,它应该很容易翻译。

class GeneralizedDiceLoss(nn.Module):
    def __init__(self):
        super(GeneralizedDiceLoss, self).__init__()

    def forward(self, inp, targ):
        inp = inp.contiguous().permute(0, 2, 3, 1)
        targ = targ.contiguous().permute(0, 2, 3, 1)

        w = torch.zeros((targ.shape[-1],))
        w = 1. / (torch.sum(targ, (0, 1, 2))**2 + 1e-9)

        numerator = targ * inp
        numerator = w * torch.sum(numerator, (0, 1, 2))
        numerator = torch.sum(numerator)

        denominator = targ + inp
        denominator = w * torch.sum(denominator, (0, 1, 2))
        denominator = torch.sum(denominator)

        dice = 2. * (numerator + 1e-9) / (denominator + 1e-9)

        return 1. - dice

【讨论】:

【参考方案3】:

此问题可能类似于:Unbalanced data and weighted cross entropy,其答案已被接受。

【讨论】:

不,不是。我问的是像素分类。

以上是关于多类分割One-hot 编码实现方式(转)的主要内容,如果未能解决你的问题,请参考以下文章

keras/tensorflow中语义图像分割的多类加权损失

机器学习One-Hot编码

one-hot编码(pytorch实现)

np.eye实现one-hot编码

np.eye实现one-hot编码

np.eye实现one-hot编码