Machine learning 如何在Keras中实现稀疏均方误差损失
我想修改以下keras均方误差损失(MSE),以便仅稀疏地计算损失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)的元素除外 注二: 计算
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