图像多label分割的dice损失函数
⽬标:
实现图像中多个物体的分割,多个物体的标注⽅式为0,1,2,3,,,,,0表⽰背景,1表⽰⼀种物体,2表⽰另⼀种物体,假设我们现在的分割任务⾥⾯有5个⽬标需要,如肺叶分割,5个肺叶的标注⽅式为:0表⽰背景,1表⽰右上叶,2表⽰右中叶,3表⽰右下叶,4表⽰左上页,5表⽰左下叶。
前提:
⾸先我们拿到的标注应该是单通道的,如⼤⼩为96*96*64*1,但在⽹络模型设计中输出通道数应该是分割类别数,即⽹络模型最后的输出⼤⼩为96*96*64*6(这⾥最后⼀维6指背景+5个⽬标),这样在训练的时候⽹络输出和标注之间⼤⼩不匹配,不能进⾏损失值计算,所以需要将原来单通道的标注图像变成6个通道,这就需要⽤到One-hot编码,在每个通道上(即将每⼀类进⾏⼆值化)。
正⽂:
One-hot编码:
以上是肺叶的标注图像,可以看到背景像素值是0,其余叶标注值分别为1,2,3,4,5,以矩阵表⽰⼤概为(⼆维图像举例,并不是这个图的真正矩阵):
[00000000
01211110
01222330
01123340
01223440
01233550
02234450
02334550]
经过One-hot编码后变成6个通道:
[11111111
10000001
10000001
10000001
10000001
10000001
10000001viber是什么
10000001]
[00000000
01011110
01000000
01100000
01000000
01000000
00000000
00000000]
[00000000
00100000
00111000
00010000
00110000
00100000
01100000
01000000]
[00000000
00000000
00000110
00001100
00001000
00011000
00010000
00110000]
[00000000
00000000
00000000
00000010
00000110
公司名称翻译
00000000
00001100
00001000]
[00000000
00000000
英语作文介绍自己00000000
00000000barely
controlled
00000000
00000110
00000010
00000110]
One-hot代码实现:
def mask_to_onehot(mask, palette):
"""
Converts a gmentation mask (H, W, C) to (H, W, K) where the last dim is a one
hot encoding vector, C is usually 1, and K is the number of gmented class.
eg:
mask:单通道的标注图像
palette:[[0],[1],[2],[3],[4],[5]]
"""
菜单翻译mantic_map = []
for colour in palette:
一是一 二是二equality = np.equal(mask, colour)
class_map = np.all(equality, axis=-1)
mantic_map.append(class_map)
mantic_map = np.stack(mantic_map, axis=-1).astype(np.float32)
return mantic_map
多label分割dice损失函数代码实现:
将背景通道的权重设置为0
def categorical_dice(lf, Y_pred, Y_gt, weight_loss):
"""
multi label dice loss with weighted
Y_pred: [None, lf.image_depth, lf.image_height, lf.image_width,
lf.numclass],Y_pred is softmax result
Y_gt:[None, lf.image_depth, lf.image_height, lf.image_width,日语语法
lf.numclass],Y_gt is one hot result
男士如何祛斑
weight_loss: numpy array of shape (C,) where C is the number of class,eg:[0,1,1,1,1,1]
:return:
"""
# print('Y_pred.shape',Y_pred.shape)
# print('Y_gt.shape',Y_gt.shape)
weight_loss = np.array(weight_loss)
smooth = 1.e-5
smooth_tf = tf.constant(smooth, tf.float32)
Y_pred = tf.cast(Y_pred, tf.float32)
Y_gt = tf.cast(Y_gt, tf.float32)
# Compute gen dice coef:
numerator = Y_gt * Y_pred
# print('interction shape',numerator.shape) interction shape (?, 64, 96, 96, 6)
numerator = tf.reduce_sum(numerator, axis=(1, 2, 3))
# print('after reduce_sum interction shape', numerator.shape) after reduce_sum interction shape (?, 6) denominator = Y_gt + Y_pred
denominator = tf.reduce_sum(denominator, axis=(1, 2, 3))
gen_dice_coef = tf.reduce_mean(2. * (numerator + smooth_tf) / (denominator + smooth_tf), axis=0)
# print('gen_dice_coef',gen_dice_coef.shape) gen_dice_coef (6,)
loss = -tf.reduce_mean(weight_loss * gen_dice_coef)
iciba翻译
return loss
最后可视化预测结果的时候,需要将6个通道的预测结果再转为单通道:
One-hot实现:
def onehot_to_mask(lf, mask, palette):
"""
Converts a mask (H, W, K) to (H, W, C)
K is the number of gmented class,C is usually 1
"""
x = np.argmax(mask, axis=-1)
colour_codes = np.array(palette)
x = np.uint8(colour_codes[x.astype(np.uint8)])
return x