我正在尝试训练序列标签模型(LSTM),其中序列标签为1
(第一类),2
(第二类)或0
(不不在乎)。
我试图编写自己的忽略零的损失函数:
import keras.backend as K
def my_loss(y_true, y_pred):
"""(sum([(t-p)**2 for t,p in zip(y_true, y_pred)])/n_nonzero)**0.5"""
return K.sqrt(K.sum(K.square(y_pred*K.cast(y_true>0, "float32") - y_true), axis=-1) / K.sum(K.cast(y_true>0, "float32") ))
本质上仅计算非零值的均方误差。
但是,训练模型时我得到loss=nan
。
我做错了什么?
在训练过程中忽略某些标签的标准方法是什么?
答案 0 :(得分:1)
它无法正常工作的原因是:
K.sqrt(K.sum(K.square(y_pred*K.cast(y_true>0, "float32") - y_pred), axis=-1) / K.sum(K.cast(y_true>0, "float32") ))
代替:
K.sqrt(K.sum(K.square(y_pred*K.cast(y_true>0, "float32") - y_true), axis=-1) / K.sum(K.cast(y_true>0, "float32") ))
因为您要用y_true
减去y_true
而不是y_pred
。
答案 1 :(得分:0)
它通过删除axis = -1的参数对我有用:
K.sqrt(K.sum(K.square(y_pred*K.cast(y_true>0, "float32") - y_true), axis=-1) / K.sum(K.cast(y_true>0, "float32") ))
当y_true
大于0时,用y_pred
减去y_true
。特别是,当y_true
等于零时,项y_pred*K.cast(y_true>0, "float32") - y_true)
也等于零,因为它将0减去0,例如对于y_true>0
,项K.cast(y_true>0, "float32")
取值为1,否则为0。