多类分割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 编码实现方式(转)的主要内容,如果未能解决你的问题,请参考以下文章