【发布时间】:2021-04-07 04:46:23
【问题描述】:
希望能解决一个奇怪的 CNN 训练问题。
我正在训练一个 Resnet 分类器,以从大约 10k 图像数据集中预测 4 类图像。代码非常简单。这是 Resnet/CNN 设置部分:
####################################
########### LOAD RESNET ############
####################################
device = torch.device("cuda" if torch.cuda.is_available()
else "cpu")
model = models.resnet50(pretrained=True)
#
for param in model.parameters():
param.requires_grad = False
#
model.fc = nn.Sequential(nn.Linear(2048, 512),
nn.ReLU(),
#nn.Dropout(0.2),
nn.Linear(512, 10),
nn.LogSoftmax(dim=1))
#
criterion = nn.NLLLoss()
#
optimizer = optim.Adam(model.fc.parameters(), lr=0.003)
# move model to gpu
model.to(device)
这是训练阶段(它对 500 张图像中的数据进行批处理,并对测试数据集进行混洗)和一些 epoch 后的一些准确度结果:
trainloader, testloader, n_batches = make_trainloader(all_data,
vals,
batch_size=500,
randomize=True)
...
for inputs, labels in trainloader:
...
inputs, labels = inputs.to(device), labels.to(device)
...
# PREDICT;
outputs = model(inputs)
...
epoch #: 12
Loss: 0.1689 Acc: 0.9400
labels: tensor([0, 0, 1, 0, 3, 0, 0, 2, 1, 2], device='cuda:0')
predictions: tensor([0, 0, 1, 0, 3, 0, 0, 2, 1, 2], device='cuda:0')
所以奇怪的是,我似乎无法很好地预测单个图像,而只能预测具有混合类的大批量数据。例如,如果我提供来自第 1 类的 500 张图像,则预测是随机的,但如果我提供来自 4 类的 500 张混合图像(很像在训练期间),则预测很好(就像在训练期间一样)。
我似乎对如何在单个图像上使用 ResNet 分类器感到困惑,尽管它似乎确实学会了预测输入数据的各个标签(请参阅上面的标签和预测输出)。或者我的分类器不是在学习单个图像,而是图像组,不确定。
感谢任何帮助或指导(我可以提供更多代码,但不想让消息太长)。这是预测代码:
# Predict
randomize = False
# load data from above
inputs = test_data[:2000]
vals_inputs = test_vals[:2000]
print ("test data size: ", vals_inputs.shape)
trainloader, testloader, n_batches = make_trainloader(inputs,
vals_inputs,
batch_size=500,
randomize=randomize)
for inputs, labels in trainloader:
# load to device
inputs, labels = inputs.to(device), labels.to(device)
# PREDICT;
outputs = model(inputs)
_, preds = torch.max(outputs, 1)
print ("prediction: ", preds[:10])
print ("labels: ", labels[:10])
...
test data size: torch.Size([2000])
prediction: tensor([1, 1, 2, 1, 2, 3, 2, 3, 2, 3], device='cuda:0')
labels: tensor([0, 0, 0, 0, 0, 0, 0, 0, 0, 0], device='cuda:0')
0 Loss: 3.2936 Acc: 0.1420
prediction: tensor([1, 3, 3, 3, 3, 1, 2, 1, 1, 2], device='cuda:0')
labels: tensor([1, 1, 1, 1, 1, 1, 1, 1, 1, 1], device='cuda:0')
0 Loss: 2.1462 Acc: 0.2780
prediction: tensor([3, 3, 1, 2, 0, 1, 2, 1, 3, 2], device='cuda:0')
labels: tensor([2, 2, 2, 2, 2, 2, 2, 2, 2, 2], device='cuda:0')
0 Loss: 2.1975 Acc: 0.2560
与我简单地打乱数据相比,准确性非常高:
# Predict
randomize = True
...
test data size: torch.Size([2000])
prediction: tensor([0, 0, 3, 2, 0, 2, 0, 3, 0, 2], device='cuda:0')
labels: tensor([0, 0, 3, 2, 0, 2, 0, 3, 0, 2], device='cuda:0')
0 Loss: 0.1500 Acc: 0.9580
prediction: tensor([0, 3, 3, 3, 0, 0, 3, 2, 3, 3], device='cuda:0')
labels: tensor([0, 2, 3, 0, 0, 0, 3, 2, 0, 3], device='cuda:0')
0 Loss: 0.1714 Acc: 0.9340
prediction: tensor([3, 3, 2, 2, 3, 1, 3, 0, 2, 2], device='cuda:0')
labels: tensor([3, 3, 2, 2, 3, 1, 3, 0, 2, 2], device='cuda:0')
0 Loss: 0.1655 Acc: 0.9400
【问题讨论】:
-
能否提供
make_trainloader的代码?
标签: machine-learning pytorch conv-neural-network prediction resnet