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

编译模型时如何正确指定precision、recall等评估指标?

解决Keras中添加Precision/Recall/F1指标失败的问题

核心原因

你用mean_squared_error(MSE)作为损失函数时,模型输出是连续数值,但Precision、Recall这类指标默认是为**分类任务(离散类别标签/概率分布)**设计的,两者输入格式不匹配,导致指标无法正常计算。而accuracy和AUC能生效,是因为它们对连续输出有兼容处理(比如AUC可以处理概率值,accuracy会自动做阈值判断)。


推荐解决方案:调整为对应分类任务的损失与指标

根据你的任务类型(二分类/多分类),改用分类专用的损失函数和匹配的指标,这是最规范的做法:

1. 二分类任务

输出层用sigmoid激活,搭配BinaryCrossentropy损失,使用BinaryPrecision/BinaryRecall指标:

from tensorflow.keras import models, layers, metrics, losses

# 构建二分类模型
model = models.Sequential([
    layers.Dense(64, activation='relu', input_shape=(你的输入维度,)),
    layers.Dense(1, activation='sigmoid')  # 二分类输出
])

model.compile(
    loss=losses.BinaryCrossentropy(),
    optimizer='adam',
    metrics=[
        'accuracy',
        metrics.BinaryPrecision(threshold=0.5),  # 可自定义分类阈值
        metrics.BinaryRecall(threshold=0.5)
    ]
)

2. 多分类任务

  • 若标签是One-Hot编码:用CategoricalCrossentropy损失,搭配Precision/Recall并指定平均方式:
model = models.Sequential([
    layers.Dense(64, activation='relu', input_shape=(你的输入维度,)),
    layers.Dense(类别数量, activation='softmax')  # 多分类输出
])

model.compile(
    loss=losses.CategoricalCrossentropy(),
    optimizer='adam',
    metrics=[
        'accuracy',
        metrics.Precision(average='macro'),  # 宏平均,可选micro/weighted
        metrics.Recall(average='macro')
    ]
)
  • 若标签是整数格式:用SparseCategoricalCrossentropy损失,搭配SparseCategoricalPrecision/SparseCategoricalRecall:
model.compile(
    loss=losses.SparseCategoricalCrossentropy(),
    optimizer='adam',
    metrics=[
        'accuracy',
        metrics.SparseCategoricalPrecision(),
        metrics.SparseCategoricalRecall()
    ]
)

特殊场景:坚持使用MSE损失

如果因为业务需求必须保留MSE损失,需要手动将连续预测值转换为类别标签,再自定义指标:

import tensorflow as tf

def custom_precision(y_true, y_pred):
    # 将连续预测值转为0/1标签(以0.5为阈值,可自行调整)
    y_pred = tf.cast(y_pred >= 0.5, tf.float32)
    true_positives = tf.reduce_sum(tf.round(tf.clip_by_value(y_true * y_pred, 0, 1)))
    predicted_positives = tf.reduce_sum(tf.round(tf.clip_by_value(y_pred, 0, 1)))
    # 添加epsilon避免除以0
    return true_positives / (predicted_positives + tf.keras.backend.epsilon())

def custom_recall(y_true, y_pred):
    y_pred = tf.cast(y_pred >= 0.5, tf.float32)
    true_positives = tf.reduce_sum(tf.round(tf.clip_by_value(y_true * y_pred, 0, 1)))
    possible_positives = tf.reduce_sum(tf.round(tf.clip_by_value(y_true, 0, 1)))
    return true_positives / (possible_positives + tf.keras.backend.epsilon())

# 编译时使用自定义指标
model.compile(
    loss='mean_squared_error',
    optimizer='adam',
    metrics=['accuracy', custom_precision, custom_recall]
)

内容的提问来源于stack exchange,提问作者Adria de Juan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 23:30:42