这不是你要找的确切损失函数,但我希望它可以给你写函数提供一些提示(还可以在这里查看Github讨论):
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
该函数计算预测输出的所有值(除了真实输出中对应值等于掩码值(例如-1)的元素)的MSE损失。
两个注意点:
- 计算均值时,分母必须是非遮蔽值的数量,而不是数组的维度,这就是为什么我不使用
K.mean(masked_squared_error, axis=1)
而是手动平均的原因。
- 掩蔽值必须是有效的数字(即
np.nan
或
np.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')
预期输出为:
[ 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