Keras自定义损失函数报错:无法遍历tf.Tensor,求解决方案
解决TensorFlow自定义损失函数的OperatorNotAllowedInGraphError错误
你遇到的OperatorNotAllowedInGraphError确实是因为在TensorFlow图模式下,不能用Python列表推导式遍历tf.Tensor对象——AutoGraph会将损失函数转换为计算图,而Python的迭代逻辑无法被正确转换为图兼容的操作。
解决方案:用TensorFlow原生张量操作替代列表推导式
你的张量形状为(None, 7, 3),最后一个维度对应需要拆分的3个部分,直接通过张量索引或tf.split即可完成拆分,这两种操作都是图兼容的:
方法1:直接张量索引(推荐,更简洁)
直接通过维度索引提取最后一维的三个分量,保持张量形状为(None, 7):
# 替换原来的列表推导式部分 upper_b_true = y_true[:, :, 0] y_med_true = y_true[:, :, 1] lower_b_true = y_true[:, :, 2] upper_b_pred = y_pred[:, :, 0] y_med_pred = y_pred[:, :, 1] lower_b_pred = y_pred[:, :, 2]
方法2:使用tf.split拆分
如果需要更灵活的维度拆分,可以用tf.split,之后用tf.squeeze去掉多余的单维度:
# 按最后一维拆分为3个张量,每个形状为(None,7,1) upper_b_true, y_med_true, lower_b_true = tf.split(y_true, 3, axis=-1) # 去掉最后一维,变为(None,7) upper_b_true = tf.squeeze(upper_b_true, axis=-1) y_med_true = tf.squeeze(y_med_true, axis=-1) lower_b_true = tf.squeeze(lower_b_true, axis=-1) # 对y_pred执行同样操作 upper_b_pred, y_med_pred, lower_b_pred = tf.split(y_pred, 3, axis=-1) upper_b_pred = tf.squeeze(upper_b_pred, axis=-1) y_med_pred = tf.squeeze(y_med_pred, axis=-1) lower_b_pred = tf.squeeze(lower_b_pred, axis=-1)
修改后的完整损失函数代码
class new_loss(tf.keras.losses.Loss): def __init__(self, tr1, tr2): super(new_loss, self).__init__() self.tr1 = tr1 self.tr2 = tr2 def call(self, y_true, y_pred): #pre-determined value tr1 = tf.constant(self.tr1) tr2 = tf.constant(self.tr2) # 改用张量索引拆分,替代列表推导式 upper_b_true = y_true[:, :, 0] y_med_true = y_true[:, :, 1] lower_b_true = y_true[:, :, 2] upper_b_pred = y_pred[:, :, 0] y_med_pred = y_pred[:, :, 1] lower_b_pred = y_pred[:, :, 2] #MSE part err = y_med_true - y_med_pred mse_loss = tf.math.reduce_mean(tf.math.square(err)) #Narrow bound bound_dif = upper_b_pred - lower_b_pred bound_loss = tf.math.reduce_mean(bound_dif) #Prob metric in_upper = y_med_pred <= upper_b_pred in_lower = y_med_pred >= lower_b_pred prob = tf.logical_and(in_upper,in_lower) prob = tf.math.reduce_mean(tf.where(prob,1.0,0.0)) return mse_loss + tf.multiply(tr1, bound_loss) + tf.multiply(tr2, prob)
内容的提问来源于stack exchange,提问作者SeungB
相关产品推荐
相关产品推荐

