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

TensorFlow自定义指标函数始终输出0问题求助

问题分析与解决方案

核心问题

你的LSTM模型最后一层是Dense(1, activation='sigmoid'),输出的y_pred形状为(batch_size, 1)。但自定义指标up_profit_metric中使用了tf.argmax(y_pred, axis=-1)——对长度为1的维度取argmax,结果永远是0,导致y_pred_class全为0,后续所有“预测类别为1”的判断条件都无法触发,最终利润总和始终为0。

另外你构造的测试示例中y_pred_example是(3,2)的形状,和模型实际输出形状不匹配,这也是测试正常但训练异常的关键原因。

修复后的指标函数

针对二分类场景(损失用binary crossentropy),应该基于sigmoid输出的阈值判断类别,而非argmax。修改后的代码如下:

def up_profit_metric(y_true, y_pred):
    # 基于阈值(如0.5)将sigmoid输出转为类别1/0
    y_pred_class = tf.cast(y_pred > 0.5, tf.int32)
    # 挤压维度,从(batch_size,1)转为(batch_size,)
    y_pred_class = tf.squeeze(y_pred_class, axis=-1)
    
    answer = tf.cast(y_true[:, 0], tf.int32)
    go_high = y_true[:, 1]
    price_now = y_true[:, 2]
    perc_inH = y_true[:, 3]
    
    q_to_buy = tf.cast(tf.round(1000 / price_now), tf.float32)
    deal_amt = q_to_buy * price_now
    
    # 正样本预测正确的利润计算
    condition1 = tf.logical_and(tf.equal(answer, y_pred_class), tf.equal(y_pred_class, 1))
    profit1 = deal_amt * go_high / 100
    # 正样本预测错误的利润计算
    condition2 = tf.logical_and(tf.not_equal(answer, y_pred_class), tf.equal(y_pred_class, 1))
    profit2 = deal_amt * perc_inH / 100
    
    # 根据条件选择对应利润值
    profit = tf.where(condition1, profit1, tf.where(condition2, profit2, tf.cast(0, dtype=tf.float32)))
    total_profit = tf.reduce_sum(profit)
    return total_profit

额外修正点

  • 模型编译时的EarlyStopping监控的val_precision未在metrics中声明,会导致报错,建议改为监控val_up_profit_metric或添加precision指标
  • fit函数中重复传入了y_tr_h,应修正为:
lstm_up2.fit(
    X_train_reshaped, y_tr_h,
    validation_data=(X_val_reshaped, y_val_h), 
    epochs=70, batch_size=24, shuffle=False
)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 17:07:37