You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Keras自定义损失函数报错InvalidArgumentError:输入需为标量但形状为[64]

问题原因

你遇到的报错核心是tf.cond仅支持标量布尔值作为判断条件,而你传入的判断条件是对应整批样本的布尔张量(shape为[64],和你的batch size一致),不符合输入要求。前两次调用成功是eager模式下的测试调用,进入图模式执行训练时就会触发校验报错。

修复方案

将损失函数中逐样本判断的逻辑从tf.cond替换为支持逐元素判断的tf.where,同时调整MSE损失的降维策略,适配逐样本加权的需求。

修改后的自定义损失函数

def custom_loss(y_true, y_pred):
    # 设置MSE不做全局降维,保留逐样本的损失值
    mse = tf.keras.losses.MeanSquaredError(reduction=tf.keras.losses.Reduction.NONE)
    penalty = 10

    # 逐样本判断真实值与预测值符号是否相反
    sign_opposite = tf.logical_or(
        tf.logical_and(tf.greater(y_true, 0.0), tf.less(y_pred, 0.0)),
        tf.logical_and(tf.less(y_true, 0.0), tf.greater(y_pred, 0.0))
    )
    # 符号相反样本应用高惩罚,其余应用低惩罚
    base_loss = mse(y_true, y_pred)
    loss = tf.where(sign_opposite, base_loss * penalty, base_loss * penalty / 4)

    # 逐样本判断预测值是否超出真实值幅值
    exceed_amplitude = tf.logical_or(
        tf.logical_and(tf.greater(y_true, 0.0), tf.greater(y_pred, y_true)),
        tf.logical_and(tf.less(y_true, 0.0), tf.less(y_pred, y_true))
    )
    # 超出幅值样本额外加惩罚
    loss = tf.where(exceed_amplitude, loss * penalty / 5, loss * penalty / 10)

    # 对整批损失求平均返回标量,适配模型训练要求
    return tf.reduce_mean(loss)
其他需要修正的代码问题
  • 原代码中MODEL_NAME的f字符串缺少右括号,修正为:MODEL_NAME = f"MODEL 01-{str(int(time.time()))}"
  • ModelCheckpoint的mode参数设置错误,你监控的是均方误差(值越小模型效果越好),需要将mode='max'修改为mode='min',否则会错误保存误差更大的模型。

内容的提问来源于stack exchange,提问作者iKey

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 15:15:04