Machine learning 如何在Keras中实现稀疏均方误差损失

Machine learning 如何在Keras中实现稀疏均方误差损失,machine-learning,neural-network,computer-vision,keras,conv-neural-network,Machine Learning,Neural Network,Computer Vision,Keras,Conv Neural Network,我想修改以下keras均方误差损失(MSE),以便仅稀疏地计算损失 def均方误差(y_真,y_pred): 返回K.mean(K.square(y\u pred-y\u true),轴=-1) 我的输出y是一个3通道图像,其中第3通道仅在要计算损耗的像素处非零。您知道如何修改上述内容以计算稀疏损耗吗?这不是您要寻找的确切损耗,但我希望它能给您一个编写函数的提示(另请参阅Github讨论): 该函数计算预测输出所有值的MSE损失,但真实输出中对应值等于掩蔽值(例如-1)的元素除外 注二: 计算

我想修改以下keras均方误差损失(MSE),以便仅稀疏地计算损失

def均方误差(y_真,y_pred):
返回K.mean(K.square(y\u pred-y\u true),轴=-1)


我的输出
y
是一个3通道图像,其中第3通道仅在要计算损耗的像素处非零。您知道如何修改上述内容以计算稀疏损耗吗?

这不是您要寻找的确切损耗,但我希望它能给您一个编写函数的提示(另请参阅Github讨论):

该函数计算预测输出所有值的MSE损失,但真实输出中对应值等于掩蔽值(例如-1)的元素除外

注二:

  • 计算平均值时,分母必须是非屏蔽值的计数,而不是 数组的维数,这就是为什么我不使用
    K.mean(掩蔽的平方误差,轴=1)
    的原因 而不是手动平均
  • 屏蔽值必须是一个有效的数字(即
    np.nan
    np.inf
    将不起作用),这意味着您必须调整数据,使其不包含
    mask\u值
在本例中,目标输出总是
[1,1,1,1]
,但一些预测值会逐渐被屏蔽

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[i], pred[i], loss[i], sep='\t')
预期产出为:

[ 1.  1.  1.  1.]  [ 1.  1.  1.  1.]  0.0
[ 1.  1.  1.  1.]  [ 1.  1.  1.  3.]  1.0
[-1.  1.  1.  1.]  [ 1.  1.  1.  3.]  1.33333
[-1. -1.  1.  1.]  [ 1.  1.  1.  3.]  2.0
[-1. -1. -1.  1.]  [ 1.  1.  1.  3.]  4.0
[-1. -1. -1. -1.]  [ 1.  1.  1.  3.]  nan

要防止出现
nan
,请按照说明操作。以下假设您希望遮罩值(背景)等于零:

 # Copied almost character-by-character (only change is default mask_value=0)
 # from https://github.com/keras-team/keras/issues/7065#issuecomment-394401137
 def masked_mse(mask_value=0):
    """
    Made default mask_value=0; not sure this is necessary/helpful
    """
    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))
        # in case mask_true is 0 everywhere, the error would be nan, therefore divide by at least 1
        # this doesn't change anything as where sum(mask_true)==0, sum(masked_squared_error)==0 as well
        masked_mse = K.sum(masked_squared_error, axis=-1) / K.maximum(K.sum(mask_true, axis=-1), 1)
        return masked_mse
    f.__name__ = str('Masked MSE (mask_value={})'.format(mask_value))
    return f

@baldassarreFe我注意到你的答案也在上面的位置;我建议根据这一观察对你的答案进行编辑。
 # Copied almost character-by-character (only change is default mask_value=0)
 # from https://github.com/keras-team/keras/issues/7065#issuecomment-394401137
 def masked_mse(mask_value=0):
    """
    Made default mask_value=0; not sure this is necessary/helpful
    """
    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))
        # in case mask_true is 0 everywhere, the error would be nan, therefore divide by at least 1
        # this doesn't change anything as where sum(mask_true)==0, sum(masked_squared_error)==0 as well
        masked_mse = K.sum(masked_squared_error, axis=-1) / K.maximum(K.sum(mask_true, axis=-1), 1)
        return masked_mse
    f.__name__ = str('Masked MSE (mask_value={})'.format(mask_value))
    return f