加权准确率WA,未加权平均召回率UAR和未加权UF1

1.加权准确率WA,未加权平均召回率UAR和未加权UF1

from sklearn.metrics import classification_report
from sklearn.metrics import precision_recall_curve, average_precision_score,roc_curve, auc, precision_score, recall_score, f1_score, confusion_matrix, accuracy_score

import torch
from torchmetrics import MetricTracker, F1Score, Accuracy, Recall, Precision, Specificity, ConfusionMatrix
import warnings
warnings.filterwarnings("ignore")  # 忽略告警


pred_list  =  [2, 0, 4, 1, 4, 2, 4, 2, 2, 0, 4, 1, 4, 2, 2, 0, 4, 1, 4, 2, 4, 2]
target_list = [1, 1, 4, 1, 3, 1, 2, 1, 1, 1, 4, 1, 3, 1, 1, 1, 4, 1, 3, 1, 2, 1]


print(classification_report(target_list, pred_list))

# Accuracy # WA(weighted accuracy)加权准确率,其实就是我们sklearn日常跑代码出来的acc
# 在多分类问题中,加权准确率(Weighted Accuracy)是一种考虑每个类别样本数量的准确率计算方式。
# 对于样本不均衡的情况,该方式比较适用。其计算方式是将每个类别的准确率乘以该类别在总样本中的比例(权重),然后求和。
test_acc_en = Accuracy(task="multiclass",num_classes=5, threshold=1. / 5, average="weighted")

# Recall macro表示加权的
# UAR(unweighted average recall)未加权平均召回率
# 是一种性能评估指标,主要用于多分类问题。它表示各类别的平均召回率(Recall),在计算时,不对各类别进行加权。对于每个类别,召回率是该类别中真正被正确预测的样本数与该类别中所有样本数的比值。
# UAR在评估一个分类器时,对每个类别都给予相同的重要性,而不考虑各类别的样本数量。这使得UAR在处理不平衡数据集时具有一定的优势,因为它不会受到数量较多的类别的影响。
test_rcl_en = Recall(task="multiclass",num_classes=5, threshold=1. / 5, average="macro") # UAR

# F1 score
# F1分数是精确率(Precision)和召回率(Recall)的调和平均值。
# 在多分类问题中,通常会计算每个类别的F1分数,然后取平均值作为总体的F1分数。
# 平均方法可以是简单的算术平均(Macro-F1)(常用),也可以是根据每个类别的样本数量进行加权的平均(Weighted-F1)
test_f1_en = F1Score(task="multiclass", num_classes=5, threshold=1. / 5, average="macro") # UF1

preds  = torch.tensor(pred_list)
target = torch.tensor(target_list)
print("sklearn vs torchmetrics: ")
print("Accuracy-W_ACC")
print(accuracy_score(y_true=target_list, y_pred=pred_list))
print(test_acc_en(preds, target))

print("recall-UAR")
print(recall_score(y_true=target_list,y_pred=pred_list,average='macro')) # 也可以指定micro模式
print(test_rcl_en(preds, target))

print("F1-score-UF1")
print(f1_score(y_true=target_list, y_pred=pred_list, average='macro'))
print(test_f1_en(preds, target))

在这里插入图片描述

2.Pytorch模型中的评价指标实现

from torchmetrics import MetricCollection, Accuracy, F1Score, Recall

def eva_sd():
    metric_collection = MetricCollection(
        {
            'WAC': Accuracy(task="multiclass", num_classes=10, threshold=1. / 5, average="weighted"),  # WA
            'UAR': Recall(task="multiclass", num_classes=10, threshold=1. / 5, average="macro"),  # UAR
            'UF1': F1Score(task="multiclass", num_classes=10, threshold=1. / 5, average="macro")  # UF1
        }
    )
    return metric_collection


'''
1.加载必要的库
'''
import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim
from torchvision import transforms, datasets
import torchmetrics
from torchmetrics import MetricCollection, Accuracy, F1Score, Recall
from evaluationsd import eva_sd
metric_collection = eva_sd()

# metric_collection = MetricCollection(
#     {
#         'WAC':Accuracy(task="multiclass", num_classes=10, average="weighted"), # WA
#         'UAR':Recall(task="multiclass", num_classes=10, average="macro"), # UAR
#         'UF1':F1Score(task="multiclass", num_classes=10,  average="macro")  # UF1
#     }
# )

valid_accuracy = torchmetrics.Accuracy(task="multiclass", num_classes=10, average="weighted")


'''
2.定义超参数
'''
BATCH_SIZE = 64  # 每批处理的数据
DEVICE = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")  # 判断使用gpu还是cpu
EPOCHS = 50  # 训练数据集的轮数
print(DEVICE)

'''
3.下载、加载数据集
'''
from torch.utils.data import DataLoader

pipeline = transforms.Compose(
    [transforms.ToTensor(),
     transforms.Normalize((0.1307,), (0.3081,))
     ]
)


# 下载数据集
train_set = datasets.MNIST("data", train=True, download=True, transform=pipeline)

test_set = datasets.MNIST("data", train=False, download=True, transform=pipeline)

# 加载数据
train_loader = DataLoader(train_set, batch_size=BATCH_SIZE, shuffle=True)

test_loader = DataLoader(test_set, batch_size=BATCH_SIZE, shuffle=True)

'''
4.构建网络模型
'''
class Digit(nn.Module):
    def __init__(self):
        super().__init__()
        self.conv1 = nn.Conv2d(1, 10, 5)  # 1:灰度图片的通道,10:输出通道,5:kernel
        self.conv2 = nn.Conv2d(10, 20, 3)  # 10:灰度图片的通道,20:输出通道,3:kernel
        self.fc1 = nn.Linear(20 * 10 * 10, 500)  # 20*10*10:输入通道,500:输出通道
        self.fc2 = nn.Linear(500, 10)  # 500:输入通道 10:输出通道

    def forward(self, x):
        input_size = x.size(0)  # batch_size x 1 x 28 x 28
        x = self.conv1(x)  # 输入:batch*1*28*28 ,输出:batch*10*24*24(28-5+1)
        x = F.relu(x)  # 保持shape不变,输出:batch*10*24*24
        x = F.max_pool2d(x, 2, 2)  # 输入:batch*10*24*24 输出:batch*10*12*12

        x = self.conv2(x)  # 输入:batch*10*12*12 输出:batch*20*10*10(12-3+1)
        x = F.relu(x)

        x = x.view(input_size, -1)  # 拉平,-1自动计算维度,20*10*10 = 2000

        x = self.fc1(x)  # 输入:batch*2000 输出:batch*500
        x = F.relu(x)  # 保持shape不变

        x = self.fc2(x)  # 输入batch*500 输出:batch*10

        output = F.log_softmax(x, dim=1)  # 计算分类后每个数字的概率值

        return output

'''
5.定义优化器
'''
model = Digit().to(DEVICE)

optimizer = optim.Adam(model.parameters())

'''
6.定义训练方法
'''
def train_model(model, device, train_loader, optimizer, epoch):
    # 模型训练
    model.train()
    for batch_index, (data, target) in enumerate(train_loader):
        # 部署到device上去
        data, target = data.to(device), target.to(device)
        # 梯度初始化为0
        optimizer.zero_grad()
        # 训练后的结果
        output = model(data)
        # 计算损失
        loss = F.cross_entropy(output, target)  # 适合多分类,二分类用Sigmund函数
        # 反向传播
        loss.backward()
        # 参数优化
        optimizer.step()
        if batch_index % 3000 == 0:
            print("Train Epoch : {}\t Loss : {:.6f}".format(epoch, loss.item()))

'''
7.定义测试方法
'''
def valid_model(model, device, test_loader):
    # 模型验证
    model.eval()
    # 正确率
    correct = 0.0
    # 测试损失
    test_loss = 0.0
    with torch.no_grad():  # 不会计算梯度,也不会进行反向传播
        for data, target in test_loader:
            # 部署到device上
            data, target = data.to(device), target.to(device)
            # 测试数据
            output = model(data)
            # 计算测试损失
            test_loss += F.cross_entropy(output, target).item()
            # 找到概率值最大的下标
            pred = output.max(1, keepdim=True)[1]  # 值,索引

            # 累计正确的值
            correct += pred.eq(target.view_as(pred)).sum().item()

            # print(pred.shape,type(pred),pred.dtype)
            # print(target.shape,type(target),target.dtype)

            # 采用自己的定义求解准确率
            valid_accuracy(torch.squeeze(pred).detach().cpu(),target.detach().cpu())
            metric_collection(torch.squeeze(pred).detach().cpu(),target.detach().cpu())
            # print(f"Metrics on batch : {batch_metrics}")

        total_train_accuracy = valid_accuracy.compute()
        val_metrics = metric_collection.compute()

        test_loss /= len(test_loader.dataset)
        # 所有batch的我的acc

        print("Test--Average loss : {:.4f},Accuracy : {:.4f}\n".format(
            test_loss,  correct / len(test_loader.dataset)
        ))
        print("My_Accuracy : {:.4f}\n".format(
            total_train_accuracy))
        # print(f"Metrics on all data: {val_metrics}")
        print("Metrics on all data: {:.4f}".format(val_metrics['WAC']))
    valid_accuracy.reset()

    metric_collection.reset()

if __name__ == "__main__":
    for epoch in range(1, EPOCHS + 1):
        train_model(model, DEVICE, train_loader, optimizer, epoch)
        valid_model(model, DEVICE, test_loader)

在这里插入图片描述

3.参考链接

  1. 一文看懂机器学习指标:准确率、精准率、召回率、F1、ROC曲线、AUC曲线
  2. 多分类中TP/TN/FP/FN的计算
  3. 多分类中混淆矩阵的TP,TN,FN,FP计算
  4. TP、TN、FP、FN超级详细解析
  5. 一分钟看懂深度学习中的准确率(Accuracy)、精度(Precision)、召回率(Recall)和 mAP
  6. 深度学习评价指标简要综述
  7. 深度学习 数据多分类准确度 多分类的准确率计算
  8. Sklearn和TorchMetrics计算F1、准确率(Accuracy)、召回率(Recall)、精确率(Precision)、敏感性(Sensitivity)、特异性(Specificity)
  9. 【PyTorch】TorchMetrics:PyTorch的指标度量库
    10.使用Torchmetrics快速进行验证指标的计算(附代码)
  • 12
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值