Python PyTorch转移学习教程的混淆矩阵和测试精度

Python PyTorch转移学习教程的混淆矩阵和测试精度,python,scikit-learn,pytorch,confusion-matrix,transfer-learning,Python,Scikit Learn,Pytorch,Confusion Matrix,Transfer Learning,在Pytorch Transfer学习教程之后,我感兴趣的是只报告训练和测试精度以及混淆矩阵(比如使用sklearn confusionmatrix)。我该怎么做?目前的教程只报告了train/val的准确性,我很难想出如何在那里合并sklearn confusionmatrix代码。此处链接到原始教程: PyTorch社区的ptrblck给出的答案。非常感谢 nb_classes = 9 confusion_matrix = torch.zeros(nb_classes, nb_classe

在Pytorch Transfer学习教程之后,我感兴趣的是只报告训练和测试精度以及混淆矩阵(比如使用sklearn confusionmatrix)。我该怎么做?目前的教程只报告了train/val的准确性,我很难想出如何在那里合并sklearn confusionmatrix代码。此处链接到原始教程:


PyTorch社区的
ptrblck
给出的答案。非常感谢

nb_classes = 9

confusion_matrix = torch.zeros(nb_classes, nb_classes)
with torch.no_grad():
    for i, (inputs, classes) in enumerate(dataloaders['val']):
        inputs = inputs.to(device)
        classes = classes.to(device)
        outputs = model_ft(inputs)
        _, preds = torch.max(outputs, 1)
        for t, p in zip(classes.view(-1), preds.view(-1)):
                confusion_matrix[t.long(), p.long()] += 1

print(confusion_matrix)
要获得每级精度,请执行以下操作:

print(confusion_matrix.diag()/confusion_matrix.sum(1))

另一种获得准确度的简单方法是使用sklearns“准确度评分”。 举个例子:

from sklearn.metrics import accuracy_score
y_pred = y_pred.data.numpy()
accuracy = accuracy_score(labels, np.argmax(y_pred, axis=1))
首先,您需要从变量中获取数据。 “y_pred”是来自模型的预测,标签当然是您的标签


np.argmax返回数组中最大值的索引。我们想要最大的值,因为当使用softmax进行多类分类时,它对应于最高概率类。准确度得分将返回标签和y_pred之间的匹配百分比。

这里是使用sklearn的混淆矩阵稍微修改的(直接)方法:-

from sklearn.metrics import confusion_matrix

nb_classes = 9

# Initialize the prediction and label lists(tensors)
predlist=torch.zeros(0,dtype=torch.long, device='cpu')
lbllist=torch.zeros(0,dtype=torch.long, device='cpu')

with torch.no_grad():
    for i, (inputs, classes) in enumerate(dataloaders['val']):
        inputs = inputs.to(device)
        classes = classes.to(device)
        outputs = model_ft(inputs)
        _, preds = torch.max(outputs, 1)

        # Append batch prediction results
        predlist=torch.cat([predlist,preds.view(-1).cpu()])
        lbllist=torch.cat([lbllist,classes.view(-1).cpu()])

# Confusion matrix
conf_mat=confusion_matrix(lbllist.numpy(), predlist.numpy())
print(conf_mat)

# Per-class accuracy
class_accuracy=100*conf_mat.diagonal()/conf_mat.sum(1)
print(class_accuracy)

我使用下面的方法将torch张量转换为定义预测类的int

x = [torch.max(tensor).item() for tensor in x_data]
y = [torch.max(tensor).item() for tensor in y_data]

我希望这有帮助!我还是个笨蛋,所以请温柔点…

按照上面的答案。。。下面是一个带有一些可视化的答案

nb_classes = 9
confusion_matrix = np.zeros((nb_classes, nb_classes))
with torch.no_grad():
    for i, (inputs, classes) in enumerate(test_loader):
        inputs = inputs.to(DEVICE)
        classes = classes.to(DEVICE)
        outputs = model(inputs)
        _, preds = torch.max(outputs, 1)
        for t, p in zip(classes.view(-1), preds.view(-1)):
                confusion_matrix[t.long(), p.long()] += 1

plt.figure(figsize=(15,10))

class_names = list(label2class.values())
df_cm = pd.DataFrame(confusion_matrix, index=class_names, columns=class_names).astype(int)
heatmap = sns.heatmap(df_cm, annot=True, fmt="d")

heatmap.yaxis.set_ticklabels(heatmap.yaxis.get_ticklabels(), rotation=0, ha='right',fontsize=15)
heatmap.xaxis.set_ticklabels(heatmap.xaxis.get_ticklabels(), rotation=45, ha='right',fontsize=15)
plt.ylabel('True label')
plt.xlabel('Predicted label')
;

那里的
数据加载程序是什么?当我使用我的
test\u loader
时,它是
torch.utils.data.DataLoader
类的一个实例,得到
TypeError:“DataLoader”对象是不可下标的
。为什么要调用t.long()和p.long()?@驴子,因为
只有整数、切片(`:`)、省略号(`…`),None和long或byte变量是插槽的有效索引
(行,列)
-它认为行和预测列,还是相反?请澄清
nb_classes = 9
confusion_matrix = np.zeros((nb_classes, nb_classes))
with torch.no_grad():
    for i, (inputs, classes) in enumerate(test_loader):
        inputs = inputs.to(DEVICE)
        classes = classes.to(DEVICE)
        outputs = model(inputs)
        _, preds = torch.max(outputs, 1)
        for t, p in zip(classes.view(-1), preds.view(-1)):
                confusion_matrix[t.long(), p.long()] += 1

plt.figure(figsize=(15,10))

class_names = list(label2class.values())
df_cm = pd.DataFrame(confusion_matrix, index=class_names, columns=class_names).astype(int)
heatmap = sns.heatmap(df_cm, annot=True, fmt="d")

heatmap.yaxis.set_ticklabels(heatmap.yaxis.get_ticklabels(), rotation=0, ha='right',fontsize=15)
heatmap.xaxis.set_ticklabels(heatmap.xaxis.get_ticklabels(), rotation=45, ha='right',fontsize=15)
plt.ylabel('True label')
plt.xlabel('Predicted label')
;