【发布时间】:2019-11-28 21:05:10
【问题描述】:
我有一个经过训练的 10 类机器学习模型,类似于 MNIST 数字分类器。我想确定每个数字类别的正确频率,如果出现错误,它会混淆哪个类别。我想用它来创建一个混淆矩阵等等。
无论如何,每个 pass 的输入是来自验证集的一批图片(形状 (32,3,224,224),其中 3、224 和 224 是图片尺寸,32 是批量大小)和标签(形状 32 ,1) 这些图片匹配的班级编号。模型输出是(形状 32,1),并列出了模型认为最匹配的类号。通过比较标签和输出张量,我可以轻松找到有多少匹配项,但我很难告诉 如何 错过了错误分类。这是主验证循环中的一个 sn-p
# Main validation loop
valid_accuracy = 0.0
model.eval()
device = 'cuda'
raw_counts = torch.zeros((11,11)) # leave room for totals in the last row and column
with torch.no_grad():
for inputs, labels in validloader:
# Run each image through the network to get log probabilities of each class
inputs, labels = inputs.to(device), labels.to(device)
logps = model.forward(inputs)
# Calculate accuracy
ps = torch.exp(logps) # 32 X 10: probability of each label in every case
top_p, top_class = ps.topk(1, dim=1)
equals = top_class == labels.view(*top_class.shape)
valid_accuracy += torch.mean(equals.type(torch.FloatTensor)).item()
# Count confusions
raw_counts[labels[:],top_class[:,0]] += 1 # <<<<---- This is the problem!
# Accumulate letter-by-letter certainties
for i in range(ll):
sum_ps[i,] += sum(ps[labels==i])
letter_counts[i] += len(ps[labels==i])
# Print validation accuracy
valid_accuracy = valid_accuracy/len(validloader)
print(f"Validation accuracy: {valid_accuracy:.3f}")
问题是我试图计算混乱的地方。只有 10 个类和 32 个批量大小,我保证有重复的标签。但是说raw_counts[labels[:],top_class[:,0]] += 1 只会将raw_counts 矩阵的每一行增加一个。例如,在此行之前的调试器中:
(Pdb) top_class[:,0]
tensor([5, 9, 5, 0, 2, 3, 3, 8, 2, 9, 6, 3, 0, 3, 1, 3, 3, 4, 0, 1, 5, 2, 8, 4,
5, 3, 6, 5, 0, 3, 2, 1], device='cuda:0')
(Pdb) labels[:]
tensor([5, 9, 5, 0, 2, 3, 3, 8, 2, 9, 6, 3, 0, 3, 1, 3, 3, 4, 0, 1, 5, 2, 8, 4,
5, 3, 8, 5, 0, 3, 2, 1], device='cuda:0')
(Pdb) raw_counts
tensor([[0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.]])
一切都如预期的那样。但是在执行该行之后:
(Pdb) n
> /home/model.py(219)main()
-> for i in range(10):
(Pdb) raw_counts
tensor([[1., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
[0., 1., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
[0., 0., 1., 0., 0., 0., 0., 0., 0., 0., 0.],
[0., 0., 0., 1., 0., 0., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 1., 0., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 1., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0., 1., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0., 1., 0., 1., 0., 0.],
[0., 0., 0., 0., 0., 0., 0., 0., 0., 1., 0.],
[0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.]])
即使这批中的五个标签是 5 并且模型得到了它们,仍然是 raw_counts[4,4] == 1。有没有什么 Pythonic 方法可以计算所有五个正确答案而不会出现混乱的 for 循环等?
【问题讨论】: