【问题标题】:Confusion matrix as the metric for the optimization in a machine learning regression problem混淆矩阵作为机器学习回归问题中优化的度量
【发布时间】:2021-11-30 12:14:57
【问题描述】:

我正在训练一个模型来分割图像,以预测图像每个像素的损坏程度(范围从 0:无损坏到 5:严重损坏)。我是这样处理的:

def simple_loss(pred, mask):   # regression case
    pred = torch.sigmoid(pred)
    return (F.mse_loss(pred, mask, reduce='none')).mean()


def structure_loss(pred, mask):   # binary case: damaged vs undamaged
    weit = 1 + 5 * torch.abs(F.avg_pool2d(mask, kernel_size=31, stride=1, padding=15) - mask)
    wbce = F.binary_cross_entropy_with_logits(pred, mask, reduce='none')
    wbce = (weit * wbce).sum(dim=(2, 3)) / weit.sum(dim=(2, 3))

    pred = torch.sigmoid(pred)
    inter = ((pred * mask) * weit).sum(dim=(2, 3))
    union = ((pred + mask) * weit).sum(dim=(2, 3))
    wiou = 1 - (inter + 1) / (union - inter + 1)

    return (wbce + wiou).mean()

二元情况下的 IoU > 0.6,但回归模型不准确。我的数据集不平衡 (100:1),大部分像素属于未损坏的类别。因此,优化是朝着准确预测未损坏像素的方向发展的。 (1..5) 区域的混淆矩阵显示标签和预测值之间没有相关性。

我无法平衡这组,因为受损区域旁边的未受损区域对人类来说是信息丰富的,经过训练可以检查损坏。

如何修改损失函数以将更高的成本分配给与损坏程度有关的回归错误?

【问题讨论】:

    标签: pytorch loss-function


    【解决方案1】:

    我们可以用 -1 对不相关的像素进行编码。然后用这种方式修改损失函数以忽略不相关的类:

    from keras import backend as K
    
    def masked_mse(mask_value):
        def f(y_true, y_pred):
            mask_true = K.cast(K.not_equal(y_true, mask_value), K.floatx())
            masked_squared_error = K.square(mask_true * (y_true - y_pred))
            masked_mse = K.sum(masked_squared_error, axis=-1) / K.sum(mask_true, axis=-1)
            return masked_mse
        f.__name__ = 'Masked MSE (mask_value={})'.format(mask_value)
        return f
        
    
    y_pred = K.constant([[ 1, 1, 1, 1], 
                         [ 1, 1, 1, 3],
                         [ 1, 1, 1, 3],
                         [ 1, 1, 1, 3],
                         [ 1, 1, 1, 3],
                         [ 1, 1, 1, 3]])
    y_true = K.constant([[ 1, 1, 1, 1],
                         [ 1, 1, 1, 1],
                         [-1, 1, 1, 1],
                         [-1,-1, 1, 1],
                         [-1,-1,-1, 1],
                         [-1,-1,-1,-1]])
    
    true = K.eval(y_true)
    pred = K.eval(y_pred)
    loss = K.eval(masked_mse(-1)(y_true, y_pred))
    
    for i in range(true.shape[0]):
        print(true[3], pred[3], loss[3], sep='\t')
    
    # [-1. -1.  1.  1.]  [ 1.  1.  1.  3.]  2.0
    

    【讨论】:

      猜你喜欢
      • 2019-04-05
      • 2020-07-25
      • 2013-08-25
      • 2019-06-11
      • 2020-07-08
      • 2019-01-22
      • 2021-11-30
      • 2021-02-01
      • 2019-05-23
      相关资源
      最近更新 更多