- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试在 PyTorch 中本地实现宏 F1 分数(F 度量),而不是使用已经广泛使用的 sklearn.metrics.f1_score以便直接在 GPU 上计算测量值。
据我了解,为了计算宏观 F1 分数,我需要计算所有标签的 F1 分数以及灵敏度和精度,然后取所有这些的平均值。
我目前的实现是这样的:
def confusion_matrix(y_pred: torch.Tensor, y_true: torch.Tensor, n_classes: int):
conf_matrix = torch.zeros([n_classes, n_classes], dtype=torch.int)
y_pred = torch.argmax(y_pred, 1)
for t, p in zip(y_true.view(-1), y_pred.view(-1)):
conf_matrix[t.long(), p.long()] += 1
return conf_matrix
def forward(self, y_pred: torch.Tensor, y_true: torch.Tensor) -> torch.Tensor:
conf_matrix = confusion_matrix(y_pred, y_true, self.classes)
TP = conf_matrix.diag()
f1_scores = torch.zeros(self.classes, dtype=torch.float)
for c in range(self.classes):
idx = torch.ones(self.classes, dtype=torch.long)
idx[c] = 0
FP = conf_matrix[c, idx].sum()
FN = conf_matrix[idx, c].sum()
sensitivity = TP[c] / (TP[c] + FN + self.epsilon)
precision = TP[c] / (TP[c] + FP + self.epsilon)
f1_scores[c] += 2.0 * ((precision * sensitivity) / (precision + sensitivity + self.epsilon))
return f1_scores.mean()
self.classes
是标签的数量,self.epsilon
是一个非常小的值,设置为 10-e12
可以防止 DivisionByZeroError
.
训练时,我计算每个批处理的度量值,并将所有度量值的平均值作为最终分数。
问题是,当我将自定义 F1 分数与 sklearn 的宏观 F1 分数进行比较时,它们很少相等。
# example 1
eval_cce 0.5203, eval_f1 0.8068, eval_acc 81.5455, eval_f1_sci 0.8023,
test_cce 0.4784, test_f1 0.7975, test_acc 82.6732, test_f1_sci 0.8097
# example 2
eval_cce 0.3304, eval_f1 0.8211, eval_acc 87.4955, eval_f1_sci 0.8626,
test_cce 0.3734, test_f1 0.8183, test_acc 85.4996, test_f1_sci 0.8424
# example 3
eval_cce 0.4792, eval_f1 0.7982, eval_acc 81.8482, eval_f1_sci 0.8001,
test_cce 0.4722, test_f1 0.7905, test_acc 82.6533, test_f1_sci 0.8139
虽然我尝试浏览互联网,但大多数案例都涉及二进制分类。我还没有找到一个例子来尝试做我想做的事情。
我的尝试有什么明显的问题吗?
我还没有弄清楚我的错误。由于时间限制,我决定只使用 sklearn 提供的 F1 宏分数。虽然它不能直接与 GPU 张量一起使用,但它对于我的情况来说已经足够快了。
但是,如果有人能解决这个问题,那就太棒了,这样任何其他可能偶然发现这个问题的人都可以解决他们的问题。
最佳答案
我前段时间用Pytorch写了自己的实现:
from typing import Tuple
import torch
class F1Score:
"""
Class for f1 calculation in Pytorch.
"""
def __init__(self, average: str = 'weighted'):
"""
Init.
Args:
average: averaging method
"""
self.average = average
if average not in [None, 'micro', 'macro', 'weighted']:
raise ValueError('Wrong value of average parameter')
@staticmethod
def calc_f1_micro(predictions: torch.Tensor, labels: torch.Tensor) -> torch.Tensor:
"""
Calculate f1 micro.
Args:
predictions: tensor with predictions
labels: tensor with original labels
Returns:
f1 score
"""
true_positive = torch.eq(labels, predictions).sum().float()
f1_score = torch.div(true_positive, len(labels))
return f1_score
@staticmethod
def calc_f1_count_for_label(predictions: torch.Tensor,
labels: torch.Tensor, label_id: int) -> Tuple[torch.Tensor, torch.Tensor]:
"""
Calculate f1 and true count for the label
Args:
predictions: tensor with predictions
labels: tensor with original labels
label_id: id of current label
Returns:
f1 score and true count for label
"""
# label count
true_count = torch.eq(labels, label_id).sum()
# true positives: labels equal to prediction and to label_id
true_positive = torch.logical_and(torch.eq(labels, predictions),
torch.eq(labels, label_id)).sum().float()
# precision for label
precision = torch.div(true_positive, torch.eq(predictions, label_id).sum().float())
# replace nan values with 0
precision = torch.where(torch.isnan(precision),
torch.zeros_like(precision).type_as(true_positive),
precision)
# recall for label
recall = torch.div(true_positive, true_count)
# f1
f1 = 2 * precision * recall / (precision + recall)
# replace nan values with 0
f1 = torch.where(torch.isnan(f1), torch.zeros_like(f1).type_as(true_positive), f1)
return f1, true_count
def __call__(self, predictions: torch.Tensor, labels: torch.Tensor) -> torch.Tensor:
"""
Calculate f1 score based on averaging method defined in init.
Args:
predictions: tensor with predictions
labels: tensor with original labels
Returns:
f1 score
"""
# simpler calculation for micro
if self.average == 'micro':
return self.calc_f1_micro(predictions, labels)
f1_score = 0
for label_id in range(1, len(labels.unique()) + 1):
f1, true_count = self.calc_f1_count_for_label(predictions, labels, label_id)
if self.average == 'weighted':
f1_score += f1 * true_count
elif self.average == 'macro':
f1_score += f1
if self.average == 'weighted':
f1_score = torch.div(f1_score, len(labels))
elif self.average == 'macro':
f1_score = torch.div(f1_score, len(labels.unique()))
return f1_score
您可以通过以下方式进行测试:
from sklearn.metrics import f1_score
import numpy as np
errors = 0
for _ in range(10):
labels = torch.randint(1, 10, (4096, 100)).flatten()
predictions = torch.randint(1, 10, (4096, 100)).flatten()
labels1 = labels.numpy()
predictions1 = predictions.numpy()
for av in ['micro', 'macro', 'weighted']:
f1_metric = F1Score(av)
my_pred = f1_metric(predictions, labels)
f1_pred = f1_score(labels1, predictions1, average=av)
if not np.isclose(my_pred.item(), f1_pred.item()):
print('!' * 50)
print(f1_pred, my_pred, av)
errors += 1
if errors == 0:
print('No errors!')
关于python - 在 PyTorch 中本地测量多类分类的 F1 分数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62265351/
性能优化的重要性不言而喻,Google 的 研究表明 ,当网站达到核心 Web 指标(Core Web Vitals)阈值时,用户放弃加载网页的可能性会降低 24%。 如何
我正在创建一个横幅设计创建器(这样人们就可以使用自己的文本、背景、图像、形状等来制作自己的设计)。我的产品有各种尺寸,例如:800x2000 mm、A4(210 x 297mm)、3300x2200m
我不确定如何使用测量来获取单位的全名。例如“公里”而不是“公里”。 let measurement = Measurement(value: 50, unit: UnitLength.meters)
我有一个自定义 ViewGroup,它有一个子 ViewPager。 ViewPager 由 PagerAdapter 提供,该 LinearLayout 向 ViewPager 提供 LayoutP
我想测量一个大型软件项目在 Linux (make) 中构建过程中的内存消耗是多少内存。理想情况下,消耗会按操作(即编译、链接)拆分,但一开始绘制随时间变化的图表可能就足够了。 我有哪些选择? 最佳答
我正在运行一个 SSIS 包来从一个平面文件加载一百万行,它使用一个脚本任务进行复杂的转换和一个 SQL Server 表目标。我试图找出在数据流处理期间将行数(可能是 1000 的倍数以提高效率)写
我正在尝试检查 Keras 模型不同层的执行速度(使用来自 tensorflow 2.3.0 v 的 keras) 我从这个 repo 中获取了代码并修改它,使用 timer() from from
我有一个旧的应用程序,一个 JAR 文件,它经过了一些增强。基本上必须修改代码的某些部分以及修改一些逻辑。 将旧版本与新版本进行比较,新版本比旧版本慢约 2 倍。 我试图缩小导致速度变慢的原因,但我发
我正在尝试测量不同 Silverlight 图表库(例如 Silverlight Control Toolkit、Visifire、Telerik)在屏幕上加载所需的时间。 我的问题是我只能测量加载控
由于 TTFB 会因每个请求而异,因此我想对其进行统计并获取平均值。有谁知道我如何通过 PHP 进行测量?bytecheck.com 网站能够分析这些数据:这是 example.com 的示例:htt
我正在使用 .NET 4.0 C# 编写应用程序。我将对象放在 .net httpruntime 缓存中,并希望在其上生成一些统计信息。我想知道对象在放入缓存之前的大小以及它在缓存中的大小。我该如何衡
我正在寻找某种方法来测量应用程序的启动时间。从点击应用程序图标的那一刻到用户可以看到例如登录页面的那一刻。 最佳答案 跑 flutter run --trace-startup --profile 跟
我正在优化 iPhone 应用程序以实现非常短的加载时间,我想知道: 是否有一种方法可以测量 iPhone 应用程序从用户点击图标到应用程序可用(或至少 –viewDidLoad 被调用)的加载时间?
我无法理解 中的一件事谷歌分析 .我的应用中需要一个功能,例如 一个 用户将我的应用转至 乙用户然后他得到了一些奖励,但我想跟踪 一个 时通过链接的用户 ID乙用户点击该链接然后我可以得到一个 中的用
有没有办法用 DUnit 来衡量代码覆盖率?或者有没有免费的工具可以实现这一点?你用它做什么?您通常追求什么代码覆盖率? Jim McKeeth:感谢您的详细回答。我谈论的是 TDD 方法意义上的单元
当我执行Makefile时,是否可以递归地回荡在make all的每个目标中花费的(系统,用户,实际)时间? 我想以比time make all更细粒度的方式对项目的编译进行基准测试。理想情况下,它将
R 中有衡量函数执行时间的标准化方法吗? 显然我可以在执行之前和之后获取system.time,然后取它们的差异,但我想知道是否有一些标准化的方法或功能(不想发明轮)。 我似乎记得我曾经使用过如下的东
我最近为了好玩而开始学习 Fortran,我想知道是否有任何简单的方法来显示执行我的代码所花费的时间。这只是一个数到一百万的简单循环,我想看看完成这个需要多长时间。 如果有帮助,这是我正在使用的代码:
我正在开发一个 Shiny 的应用程序。 我对计算执行某些代码块(例如 ggplot 等)所需的时间很感兴趣。 出于某种原因,使用通常的时钟方法似乎在响应式(Reactive)调用中不起作用,例如:
我想测量 jpeg 的白色/黄色量(在可调整的容差范围内)。 我正在尝试开发一种质量控制工具来测量杏仁的缺陷。缺陷是棕色杏仁皮上的划痕(见下图)。由于这些缺陷是白色/黄色的,我想要一种简单地将图像加载
我是一名优秀的程序员,十分优秀!