我正在实现一个自定义的损失函数:
def wmse(y_true, y_pred): gt_bin_dict = {"0.0": 4, "0.1": 16, "0.2": 75, "0.3": 62} # 等等直到1.0 weight_freq = [] for i in y_true: # y_true中的i可以是0到1之间的值,我们取str(i)的前3个字符 # 例如,如果i是0.15,那么str(i)[:3] == 0.1,这将作为键(在gt_bin_dict中)返回16。 weight_freq.append(1./gt_bin_dict[str(i.numpy())[:3]]) loss = 0 for i in range(len(y_true)): loss += weight_freq[i] * K.square(y_true[i].numpy() - y_pred[i].numpy()) return loss
当我在虚拟数据上运行上述函数时,它能正常运行且没有错误,给我正确的输出。
a = tf.constant([0.15, 0.2, 0.33])b = tf.constant([0.43, 0.57, 0.68])loss = wmse(a, b)print(loss)# 输出:# tf.Tensor(0.008043971, shape=(), dtype=float32)
但是当我开始训练我的模型(使用model.fit_generator()
)时,我得到了以下错误:
OperatorNotAllowedInGraphError: 对`tf.Tensor`进行迭代是不允许的:AutoGraph没有转换这个函数。尝试直接用@tf.function装饰它。
任何帮助将不胜感激。
顺便提一下,我已经从keras切换到tf.keras(tf版本2.2.0),我确定我不再混合使用keras和tf.keras。(我会继续双重检查是否这是问题所在)
谢谢
回答:
你的损失函数是一个加权MSE…你也可以直接使用TF功能来实现这个
model.compile('adam', 'mse')
在拟合时,你可以设置样本权重参数
model.fit(X_train, y_train, sample_weight=weight_freq, ...)
其中weight_freq
是一个与你的X_train长度相同的数组
有了gt_bin_dict
作为一个固定的字典,你可以简单地以这种方式获取样本的权重
y_true = np.random.uniform(0,1, 1000) # 仅为示例W_dict = {1:10,2:83,3:23,4:43,5:42,6:24,7:34,8:23,9:12,10:99} # 仅为示例y_true_bin = np.digitize(a, bins=np.linspace(0,1, 11))weight_freq = [W_dict[i] for i in y_true_bin]weight_freq = np.asarray(weight_freq)
然后在训练过程中按上文介绍的方式应用这些权重