keras/tensorflow 中语义图像分割的多 class 加权损失
Multi-class weighted loss for semantic image segmentation in keras/tensorflow
给定批处理 RGB 图像作为输入,shape=(batch_size, width, height, 3)
多类目标表示为 one-hot,shape=(batch_size, width, height, n_classes)
最后一层有 softmax 激活的模型(Unet、DeepLab)。
我正在 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
此问题可能类似于:,其中有一个已接受的答案。
我会回答我的问题:
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)
我正在使用广义骰子损失。在我的案例中,它比加权分类交叉熵更好。我的实现是在 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
给定批处理 RGB 图像作为输入,shape=(batch_size, width, height, 3)
多类目标表示为 one-hot,shape=(batch_size, width, height, n_classes)
最后一层有 softmax 激活的模型(Unet、DeepLab)。
我正在 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
此问题可能类似于:
我会回答我的问题:
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)
我正在使用广义骰子损失。在我的案例中,它比加权分类交叉熵更好。我的实现是在 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