混淆矩阵作为机器学习回归问题中优化的度量

Posted

技术标签:

【中文标题】混淆矩阵作为机器学习回归问题中优化的度量【英文标题】: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) 区域的混淆矩阵显示标签和预测值之间没有相关性。

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

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

【问题讨论】:

【参考方案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

【讨论】:

以上是关于混淆矩阵作为机器学习回归问题中优化的度量的主要内容,如果未能解决你的问题,请参考以下文章

机器学习-分类评估方法(召回率ROC与混淆矩阵)

机器学习实战笔记(Python实现)-07-分类性能度量指标

机器学习100天(十九):019 分类模型评价指标-混淆矩阵

机器学习100天(十九):019 分类模型评价指标-混淆矩阵

机器学习模型评估指标汇总

机器学习框架及评估指标详解