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

TensorFlow Addons的F1 Score为何对正确预测输出0值?

TensorFlow Addons F1Score 计算异常问题分析

问题场景

训练CNN模型使用F1 Score时出现计算结果不符合预期的情况,以下是测试代码:

import tensorflow_addons as tfa
import numpy as np
metric = tfa.metrics.F1Score(
    num_classes=4, threshold=0.5)
y_true = np.array([
    [0, 1, 0, 0],
    # [0, 1, 0, 0],
    # [1, 0, 0, 0]
], np.int32)
y_pred = np.array([
    [0, 1, 0, 0],
    # [0.2, 0.6, 0.2, 0.2],
    # [0.6, 0.2, 0.2, 0.2]
], np.float32)
metric.update_state(y_true, y_pred)
result = metric.result()
result.numpy()

预期输出:

[1, 1, 1, 1]

按此计算宏平均F1 Score应为1,但实际得到:

[0, 1, 0, 0]

设置average=macro时,结果为0.25。


补充测试情况

给y_true添加一行数据后,结果恢复符合预期(原本以为会报错),测试代码如下:

import tensorflow_addons as tfa
import numpy as np
metric = tfa.metrics.F1Score(
    num_classes=4, threshold=0.5)
y_true = np.array([
    [0, 1, 0, 0],
    [1, 0, 0, 0]
    # [0, 1, 0, 0],
    # [1, 0, 0, 0]
], np.int32)
y_pred = np.array([
    [0, 1, 0, 0],
    # [0.2, 0.6, 0.2, 0.2],
    # [0.6, 0.2, 0.2, 0.2]
], np.float32)
metric.update_state(y_true, y_pred)
result = metric.result()
result.numpy()

问题原因

这不是TensorFlow Addons的bug,是F1Score的计算逻辑导致的:

  • F1 Score由精确率和召回率推导而来,而召回率的计算依赖真实标签中存在该类别的正样本(即该类别在y_true中至少有一个1)。
  • 第一个测试用例里,只有索引为1的类别有正样本,其余3个类别在y_true中全为0。对于这类没有正样本的类别,tfa.metrics.F1Score会默认返回0——因为没有正样本时,召回率的分母为0,为避免除以0错误,指标直接置0。
  • 宏平均会对所有类别的F1值取平均,所以(0+1+0+0)/4=0.25,和实际结果一致。
  • 补充测试中添加了索引为0的类别正样本,该类别有了有效计算依据,若预测正确则F1为1,符合预期。

解决办法

如果需要对没有正样本的类别返回1(即认为无样本时预测正确),可以通过两种方式处理:

  1. 手动修正结果:
result = metric.result().numpy()
# 标记每个类别是否有正样本
has_positive_samples = np.any(y_true == 1, axis=0)
# 对无正样本的类别,将F1设为1
result[~has_positive_samples] = 1
  1. 设置zero_division参数(需确认TensorFlow Addons版本支持):
    初始化F1Score时指定zero_division=1,控制分母为0时返回1:
metric = tfa.metrics.F1Score(
    num_classes=4, threshold=0.5, zero_division=1)

内容的提问来源于stack exchange,提问作者Jason Rich Darmawan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 14:40:37