Python利用Pytorch實(shí)現(xiàn)繪制ROC與PR曲線圖
Pytorch 多分類模型繪制 ROC, PR 曲線(代碼 親測(cè) 可用)
ROC曲線
示例代碼
import torch
import torch.nn as nn
import os
import numpy as np
from torchvision.datasets import ImageFolder
from utils.transform import get_transform_for_test
from senet.se_resnet import FineTuneSEResnet50
from scipy import interp
import matplotlib.pyplot as plt
from itertools import cycle
from sklearn.metrics import roc_curve, auc, f1_score, precision_recall_curve, average_precision_score
os.environ['CUDA_VISIBLE_DEVICES'] = "0"
data_root = r'D:\TJU\GBDB\set113\set113_images\test1' # 測(cè)試集路徑
test_weights_path = r"C:\Users\admin\Desktop\fsdownload\epoch_0278_top1_70.565_'checkpoint.pth.tar'" # 預(yù)訓(xùn)練模型參數(shù)
num_class = 113 # 類別數(shù)量
gpu = "cuda:0"
# mean=[0.948078, 0.93855226, 0.9332005], var=[0.14589554, 0.17054074, 0.18254866]
def test(model, test_path):
# 加載測(cè)試集和預(yù)訓(xùn)練模型參數(shù)
test_dir = os.path.join(data_root, 'test_images')
class_list = list(os.listdir(test_dir))
class_list.sort()
transform_test = get_transform_for_test(mean=[0.948078, 0.93855226, 0.9332005],
var=[0.14589554, 0.17054074, 0.18254866])
test_dataset = ImageFolder(test_dir, transform=transform_test)
test_loader = torch.utils.data.DataLoader(
test_dataset, batch_size=1, shuffle=False, drop_last=False, pin_memory=True, num_workers=1)
checkpoint = torch.load(test_path)
model.load_state_dict(checkpoint['state_dict'])
model.eval()
score_list = [] # 存儲(chǔ)預(yù)測(cè)得分
label_list = [] # 存儲(chǔ)真實(shí)標(biāo)簽
for i, (inputs, labels) in enumerate(test_loader):
inputs = inputs.cuda()
labels = labels.cuda()
outputs = model(inputs)
# prob_tmp = torch.nn.Softmax(dim=1)(outputs) # (batchsize, nclass)
score_tmp = outputs # (batchsize, nclass)
score_list.extend(score_tmp.detach().cpu().numpy())
label_list.extend(labels.cpu().numpy())
score_array = np.array(score_list)
# 將label轉(zhuǎn)換成onehot形式
label_tensor = torch.tensor(label_list)
label_tensor = label_tensor.reshape((label_tensor.shape[0], 1))
label_onehot = torch.zeros(label_tensor.shape[0], num_class)
label_onehot.scatter_(dim=1, index=label_tensor, value=1)
label_onehot = np.array(label_onehot)
print("score_array:", score_array.shape) # (batchsize, classnum)
print("label_onehot:", label_onehot.shape) # torch.Size([batchsize, classnum])
# 調(diào)用sklearn庫(kù),計(jì)算每個(gè)類別對(duì)應(yīng)的fpr和tpr
fpr_dict = dict()
tpr_dict = dict()
roc_auc_dict = dict()
for i in range(num_class):
fpr_dict[i], tpr_dict[i], _ = roc_curve(label_onehot[:, i], score_array[:, i])
roc_auc_dict[i] = auc(fpr_dict[i], tpr_dict[i])
# micro
fpr_dict["micro"], tpr_dict["micro"], _ = roc_curve(label_onehot.ravel(), score_array.ravel())
roc_auc_dict["micro"] = auc(fpr_dict["micro"], tpr_dict["micro"])
# macro
# First aggregate all false positive rates
all_fpr = np.unique(np.concatenate([fpr_dict[i] for i in range(num_class)]))
# Then interpolate all ROC curves at this points
mean_tpr = np.zeros_like(all_fpr)
for i in range(num_class):
mean_tpr += interp(all_fpr, fpr_dict[i], tpr_dict[i])
# Finally average it and compute AUC
mean_tpr /= num_class
fpr_dict["macro"] = all_fpr
tpr_dict["macro"] = mean_tpr
roc_auc_dict["macro"] = auc(fpr_dict["macro"], tpr_dict["macro"])
# 繪制所有類別平均的roc曲線
plt.figure()
lw = 2
plt.plot(fpr_dict["micro"], tpr_dict["micro"],
label='micro-average ROC curve (area = {0:0.2f})'
''.format(roc_auc_dict["micro"]),
color='deeppink', linestyle=':', linewidth=4)
plt.plot(fpr_dict["macro"], tpr_dict["macro"],
label='macro-average ROC curve (area = {0:0.2f})'
''.format(roc_auc_dict["macro"]),
color='navy', linestyle=':', linewidth=4)
colors = cycle(['aqua', 'darkorange', 'cornflowerblue'])
for i, color in zip(range(num_class), colors):
plt.plot(fpr_dict[i], tpr_dict[i], color=color, lw=lw,
label='ROC curve of class {0} (area = {1:0.2f})'
''.format(i, roc_auc_dict[i]))
plt.plot([0, 1], [0, 1], 'k--', lw=lw)
plt.xlim([0.0, 1.0])
plt.ylim([0.0, 1.05])
plt.xlabel('False Positive Rate')
plt.ylabel('True Positive Rate')
plt.title('Some extension of Receiver operating characteristic to multi-class')
plt.legend(loc="lower right")
plt.savefig('set113_roc.jpg')
plt.show()
if __name__ == '__main__':
# 加載模型
seresnet = FineTuneSEResnet50(num_class=num_class)
device = torch.device(gpu)
seresnet = seresnet.to(device)
test(seresnet, test_weights_path)運(yùn)行結(jié)果:

PR曲線
示例代碼
import torch
import torch.nn as nn
import os
import numpy as np
from torchvision.datasets import ImageFolder
from utils.transform import get_transform_for_test
from senet.se_resnet import FineTuneSEResnet50
import matplotlib.pyplot as plt
from sklearn.metrics import roc_curve, auc, f1_score, precision_recall_curve, average_precision_score
os.environ['CUDA_VISIBLE_DEVICES'] = "0"
data_root = r'D:\TJU\GBDB\set113\set113_images\test1' # 測(cè)試集路徑
test_weights_path = r"C:\Users\admin\Desktop\fsdownload\epoch_0278_top1_70.565_'checkpoint.pth.tar'" # 預(yù)訓(xùn)練模型參數(shù)
num_class = 113 # 類別數(shù)量
gpu = "cuda:0"
# mean=[0.948078, 0.93855226, 0.9332005], var=[0.14589554, 0.17054074, 0.18254866]
def test(model, test_path):
# 加載測(cè)試集和預(yù)訓(xùn)練模型參數(shù)
test_dir = os.path.join(data_root, 'test_images')
class_list = list(os.listdir(test_dir))
class_list.sort()
transform_test = get_transform_for_test(mean=[0.948078, 0.93855226, 0.9332005],
var=[0.14589554, 0.17054074, 0.18254866])
test_dataset = ImageFolder(test_dir, transform=transform_test)
test_loader = torch.utils.data.DataLoader(
test_dataset, batch_size=1, shuffle=False, drop_last=False, pin_memory=True, num_workers=1)
checkpoint = torch.load(test_path)
model.load_state_dict(checkpoint['state_dict'])
model.eval()
score_list = [] # 存儲(chǔ)預(yù)測(cè)得分
label_list = [] # 存儲(chǔ)真實(shí)標(biāo)簽
for i, (inputs, labels) in enumerate(test_loader):
inputs = inputs.cuda()
labels = labels.cuda()
outputs = model(inputs)
# prob_tmp = torch.nn.Softmax(dim=1)(outputs) # (batchsize, nclass)
score_tmp = outputs # (batchsize, nclass)
score_list.extend(score_tmp.detach().cpu().numpy())
label_list.extend(labels.cpu().numpy())
score_array = np.array(score_list)
# 將label轉(zhuǎn)換成onehot形式
label_tensor = torch.tensor(label_list)
label_tensor = label_tensor.reshape((label_tensor.shape[0], 1))
label_onehot = torch.zeros(label_tensor.shape[0], num_class)
label_onehot.scatter_(dim=1, index=label_tensor, value=1)
label_onehot = np.array(label_onehot)
print("score_array:", score_array.shape) # (batchsize, classnum) softmax
print("label_onehot:", label_onehot.shape) # torch.Size([batchsize, classnum]) onehot
# 調(diào)用sklearn庫(kù),計(jì)算每個(gè)類別對(duì)應(yīng)的precision和recall
precision_dict = dict()
recall_dict = dict()
average_precision_dict = dict()
for i in range(num_class):
precision_dict[i], recall_dict[i], _ = precision_recall_curve(label_onehot[:, i], score_array[:, i])
average_precision_dict[i] = average_precision_score(label_onehot[:, i], score_array[:, i])
print(precision_dict[i].shape, recall_dict[i].shape, average_precision_dict[i])
# micro
precision_dict["micro"], recall_dict["micro"], _ = precision_recall_curve(label_onehot.ravel(),
score_array.ravel())
average_precision_dict["micro"] = average_precision_score(label_onehot, score_array, average="micro")
print('Average precision score, micro-averaged over all classes: {0:0.2f}'.format(average_precision_dict["micro"]))
# 繪制所有類別平均的pr曲線
plt.figure()
plt.step(recall_dict['micro'], precision_dict['micro'], where='post')
plt.xlabel('Recall')
plt.ylabel('Precision')
plt.ylim([0.0, 1.05])
plt.xlim([0.0, 1.0])
plt.title(
'Average precision score, micro-averaged over all classes: AP={0:0.2f}'
.format(average_precision_dict["micro"]))
plt.savefig("set113_pr_curve.jpg")
# plt.show()
if __name__ == '__main__':
# 加載模型
seresnet = FineTuneSEResnet50(num_class=num_class)
device = torch.device(gpu)
seresnet = seresnet.to(device)
test(seresnet, test_weights_path)運(yùn)行結(jié)果:

到此這篇關(guān)于Python利用Pytorch實(shí)現(xiàn)繪制ROC與PR曲線圖的文章就介紹到這了,更多相關(guān)Python繪制ROC PR曲線圖內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
詳解Python中sorted()和sort()的使用與區(qū)別
眾所周知,在Python中常用的排序函數(shù)為sorted()和sort()。本文將詳細(xì)介紹sorted()和sort()方法的代碼示例,并解釋兩者之間的區(qū)別,感興趣的可以了解一下2022-03-03
淺談python出錯(cuò)時(shí)traceback的解讀
這篇文章主要介紹了淺談python出錯(cuò)時(shí)traceback的解讀,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-07-07
Keras 切換后端方式(Theano和TensorFlow)
這篇文章主要介紹了Keras 切換后端方式(Theano和TensorFlow),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-06-06
關(guān)于python中plt.hist參數(shù)的使用詳解
今天小編就為大家分享一篇關(guān)于python中plt.hist參數(shù)的使用詳解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2019-11-11
一步步講解利用Flask開(kāi)發(fā)一個(gè)Web程序
這篇文章主要介紹了使用Flask框架在Linux系統(tǒng)上開(kāi)發(fā)一個(gè)簡(jiǎn)單的WatchList?Web程序的過(guò)程,包括了實(shí)現(xiàn)的詳細(xì)步驟,最終實(shí)現(xiàn)了一個(gè)包含登錄界面的Web程序,需要的朋友可以參考下2025-02-02
Python Barbershop實(shí)現(xiàn)照片換發(fā)型功能
這篇文章主要為大家介紹了一個(gè)開(kāi)源項(xiàng)目(Barbershop),可以將照片中的發(fā)型更換成另一個(gè),文中實(shí)現(xiàn)過(guò)程講解詳細(xì),感興趣的可以學(xué)習(xí)一下2022-01-01
使用Python自動(dòng)化創(chuàng)建和掃描二維碼
二維碼(Quick Response code)已成為在物理和數(shù)字領(lǐng)域之間架起橋梁的多功能工具,從分享聯(lián)系信息和網(wǎng)站鏈接到促進(jìn)支付和跟蹤庫(kù)存,二維碼在各個(gè)行業(yè)中找到了應(yīng)用,本文將展示如何使用Python自動(dòng)化創(chuàng)建和掃描二維碼,感興趣的朋友可以參考下2024-07-07

