如何实现自定义损失和准确性度量标准以忽略keras语义段中的空标签

时间:2019-08-17 05:48:55

标签: keras loss-function semantic-segmentation

我正在尝试在keras中开发语义分割模型。标签具有三个不同的值,即。 0-背景,1-前景和2-缺少标签或无效标签。由于我们仅对两个类感兴趣,因此我们不希望计算基于void标签(2)的损失,即应忽略它们

最初,我尝试使用自定义的损失和准确性度量标准来掩盖空白标签。但是,在50个历元之后,损失(自定义二进制交叉熵)变为,即使准确性增加。最后一个激活层( Sigmoid )的形状为(None,128,128,1)。具有相同形状的相应目标标签的值为 0,1,2 (uint8)和输入图像(不是蒙版)进行了标准化(/ 255.0)float(0-1)。使用的优化程序-亚当(lr = 1e-3)

这是自定义损失和指标...

def masked_loss_function(y_true, y_pred):
  mask_value=2
  print(y_true.shape)
  print(y_pred.shape)
  mask = K.cast(K.not_equal(y_true, mask_value), K.floatx())
  print(mask.shape)
  return K.binary_crossentropy(y_true * mask, y_pred * mask)

def masked_accuracy(y_true, y_pred):
  mask_value=2
  dtype = K.floatx()
  total = K.sum(K.cast(K.not_equal(y_true, mask_value), dtype))
  correct = K.sum(K.cast(K.equal(y_true, K.round(y_pred)), dtype))
  return correct / total

此外,我还使用keras生成器对图像和蒙版(相同的种子)进行了图像增强。

data_gen_args = dict(
                 width_shift_range=0.2,
                 height_shift_range=0.2,
                 zoom_range=0.2,
                 horizontal_flip=True,
                 validation_split=0.2
                )

似乎蒙版存在一些问题,因为即使我们尝试屏蔽掉void(2)标签,损失也会变成负数,

更新:-

如果我们包含缩放和宽度偏移选项,似乎生成器会以某种方式修改蒙版。

这里是完整的生成器(在我将标签更改为浮点值0.0和255.0以进行测试之后)。

    data_gen_args = dict(rescale=1./255,
                     width_shift_range=0.1,
                     height_shift_range=0.1,
                     zoom_range=0.2,
                     horizontal_flip=True,
                     validation_split=0.2
                    )

image_datagen = ImageDataGenerator(**data_gen_args) 

# Provide the same seed and keyword arguments to the fit and flow methods
seed = 1
batch_sz=32

def generate_train_generator(image_datagen):
    genX1 = image_datagen.flow(
    x_train,
    batch_size=batch_sz,
    shuffle=True,
    subset='training',
    seed=seed)

    genY1 = image_datagen.flow(
    y_train,
    batch_size=batch_sz,
    shuffle=True,
    subset='training',
    seed=seed)

    while True:
            Xi = genX1.next()
            Yi = genY1.next()
            print(Yi.dtype)
            print(np.unique(Yi))
            yield (Xi, Yi)


train_generator=generate_train_generator(image_datagen)

它输出的标签值(唯一)为:- [0.0000000e + 00 2.0307664e-06 1.0561990e-05 ... 9.9996912e-01 9.9997061e-01 1.0000000e + 00] (如果包含宽度偏移);无需移动和缩放即可输出 [0。 1。]

进行价值修改的原因可能是什么? (在Google Colab上使用Keras 2.2.4)

0 个答案:

没有答案