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

del*_*fer 2 machine-learning computer-vision neural-network conv-neural-network keras

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

def mean_squared_error(y_true, y_pred): return K.mean(K.square(y_pred - y_true), axis=-1)

我的输出y是3通道图像,其中第3通道仅在要计算损耗的那些像素处不为零。知道如何修改以上内容以计算稀疏损失吗?

bal*_*eFe 6

这不是您要查找的确切损失,但我希望它会给您提示以编写函数:

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
Run Code Online (Sandbox Code Playgroud)

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

有两个注意事项:-计算均值时,分母必须是非掩码值的计数,而不是数组的维数,这就是为什么我不使用K.mean(masked_squared_error, axis=1),而是手动求平均值。-掩蔽值必须是一个有效的数字(即np.nannp.inf不会做的工作),这意味着你必须去适应你的数据,以便它不包含mask_value

在此示例中,目标输出始终为[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')
Run Code Online (Sandbox Code Playgroud)

预期的输出是:

[ 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
Run Code Online (Sandbox Code Playgroud)