【发布时间】:2019-05-16 06:17:11
【问题描述】:
我目前正在做我的迷你项目,根据海报预测电影类型。所以在我拥有的数据集中,每部电影可以有 1 到 3 种类型,因此每个实例可以属于多个类。我总共有 15 个课程(15 个流派)。所以现在我面临的问题是如何使用 pytorch 对这个特定问题进行预测。
在 pytorch CIFAR-tutorial 中,每个实例只能有一个类(例如,如果图像是汽车,它应该属于汽车类),总共有 10 个类。所以在这种情况下,模型预测的定义方式如下(从pytorch网站复制代码sn-p):
import torch.optim as optim
criterion = nn.CrossEntropyLoss()
optimizer = optim.SGD(net.parameters(), lr=0.001, momentum=0.9)
for epoch in range(2): # loop over the dataset multiple times
running_loss = 0.0
for i, data in enumerate(trainloader, 0):
# get the inputs
inputs, labels = data
# zero the parameter gradients
optimizer.zero_grad()
# forward + backward + optimize
outputs = net(inputs)
loss = criterion(outputs, labels)
loss.backward()
optimizer.step()
# print statistics
running_loss += loss.item()
if i % 2000 == 1999: # print every 2000 mini-batches
print('[%d, %5d] loss: %.3f' %
(epoch + 1, i + 1, running_loss / 2000))
running_loss = 0.0
print('完成训练')
问题1(训练部分)。您可以建议将什么用作激活函数。我在考虑 BCEWithLogitsLoss() 但我不确定它会有多好。
然后测试集的预测精度定义如下: 整个网络:
correct = 0
total = 0
with torch.no_grad():
for data in testloader:
images, labels = data
outputs = net(images)
_, predicted = torch.max(outputs.data, 1)
total += labels.size(0)
correct += (predicted == labels).sum().item()
print('Accuracy of the network on the 10000 test images: %d %%' % (
100 * correct / total))
对于每个班级:
class_correct = list(0. for i in range(10))
class_total = list(0. for i in range(10))
with torch.no_grad():
for data in testloader:
images, labels = data
outputs = net(images)
_, predicted = torch.max(outputs, 1)
c = (predicted == labels).squeeze()
for i in range(4):
label = labels[i]
class_correct[label] += c[i].item()
class_total[label] += 1
for i in range(10):
print('Accuracy of %5s : %2d %%' % (
classes[i], 100 * class_correct[i] / class_total[i]))
其中输出如下:
Accuracy of plane : 36 %
Accuracy of car : 40 %
Accuracy of bird : 30 %
Accuracy of cat : 19 %
Accuracy of deer : 28 %
Accuracy of dog : 17 %
Accuracy of frog : 34 %
Accuracy of horse : 43 %
Accuracy of ship : 57 %
Accuracy of truck : 35 %
现在是问题 2: 如何确定准确性,使其看起来如下:
例如:
The Matrix (1999) ['Action: 91%', 'Drama: 25%', 'Adventure: 13%']
The Others (2001) ['Drama: 76%', 'Horror: 65%', 'Action: 41%']
Alien: Resurrection (1997) ['Horror: 67%', 'Action: 64%', 'Drama: 43%']
The Martian (2015) ['Drama: 95%', 'Adventure: 81%']
考虑到每部电影并不总是有 3 种类型,有时是 2,有时是 1。所以在我看来,我应该在输出列表中找到 3 个最大值、2 个最大值或 1 个最大值,即 list 15 种类型,例如,如果
我预测的类型是[电影,冒险]然后
some_kind_of_function(outputs) 应该给我输出
[1 0 0 0 0 0 0 0 0 0 0 1 0 0 0],
之后我可以将其与 ground_truth 进行比较。 我不认为 torchmax 在这种情况下会起作用,因为它只给出 [weigts array] 中的一个最大值,所以
实现它的最佳方式是什么?
提前谢谢你,感谢任何帮助或建议:)
【问题讨论】:
-
我不确定你的迷你项目的损失函数,但我建议你多了解一下 CIFAR-10。这样想,CIFAR-10 CNN 正在计算输入图像成为 10 个类别之一的概率。最后,您只需打印 10 中的最大数字,并希望这是真的。因此,在您的情况下,您将有 15 个类(对应于 15 个流派)。成功训练后,您的模型将为每个输入海报生成一个包含 15 个概率的数组。您可以选择前 3 个以显示最佳 3 类型或 5 个用于前 5。其他方法是设置截止概率,例如 0.6 并显示所有类别 > 0.6。
-
嗨@MohanaRao,谢谢你的解释,我知道概率是如何计算的,但是由于我的标签并不总是有一个值,它是一个最多可以有3个元素的张量,我无法正确训练我的数据,因为我的损失没有正确计算,并且我收到类似 ValueError: Target size (torch.Size([4, 3])) must be the same as input size (torch.Size([4 , 15]))
标签: conv-neural-network pytorch multilabel-classification multiclass-classification