关于PyTorch,未使用DataLoader进行预测与使用DataLoader预测结果差异

-1 投票
1 回答
44 浏览
提问于 2025-04-14 17:55

我尝试在不使用 Dataloader 的情况下预测一张单独的图片,但结果有点奇怪。

Terminal Result

这张图片是我预测的结果。使用 Dataloader 时,预测的结果和标签是一致的。但是,当我读取一张单独的图片进行预测时,得到的标签可能和预期的不一样,尽管预测本身是准确的。举个例子,模型可能把所有标签都预测成14,而标签3可能是25。

我刚接触 Pytorch,对这个问题感到困惑。预测时一定要使用 Dataloader 吗?

以下是我的主要代码:

data_transforms = {
    'train':
    transforms.Compose([
    transforms.Resize(256),
    transforms.RandomRotation(45),
    transforms.CenterCrop(224),
    transforms.RandomHorizontalFlip(p=0.5),
    transforms.RandomVerticalFlip(p=0.5),
    transforms.ColorJitter(brightness=0.2, contrast=0.1, saturation=0.1, hue=0.1),
    transforms.RandomGrayscale(p=0.025),
    transforms.ToTensor(),
    transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])
    ]),
    'valid': transforms.Compose([transforms.Resize(256),
    transforms.CenterCrop(224),
    transforms.ToTensor(),
    transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])
    ]),
}
   
def loop_prediction(): # wrong label
    correct_count = 0
    size = 10
    for i in range(size):
        # random get a name from './flower_data/valid/{random_number}/*.jpg'
        rand_int = random.randint(2, 3)
        img_file_name = random.choice(os.listdir(f'./flower_data/valid/{rand_int}'))
        img_file = f'./flower_data/valid/{rand_int}/{img_file_name}'
        img = Image.open(img_file)
        # read a image and change to tensor
        transform = transforms.Compose([
            transforms.Resize(256),
            transforms.CenterCrop(224),
            transforms.ToTensor(),
            transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]),
        ])

        img = transform(img)
        img = img.unsqueeze(0)
        # print(img.shape)
        model_ft.eval()
        with torch.no_grad():
            output = model_ft(img.cuda())

            _, preds_tensor = torch.max(output, 1)
            preds = np.squeeze(preds_tensor.numpy()) if not train_on_gpu else np.squeeze(
                preds_tensor.cpu().numpy())  #

        print('Label', rand_int, ' ', 'Predict:', preds)
        if preds + 1 == rand_int:
            correct_count += 1
   
def batch_prediction(): # correct label
    image_datasets = {x: datasets.ImageFolder(os.path.join(data_dir, x), data_transforms[x]) for x in
                      ['train', 'valid']}
    dataloaders = {x: torch.utils.data.DataLoader(image_datasets[x], batch_size=batch_size, shuffle=True) for x in
                   ['train', 'valid']}
    dataiter = iter(dataloaders['valid'])
    images, labels = next(dataiter)
    model_ft.eval()
    print(images.shape, labels.shape)
    if train_on_gpu:
        output = model_ft(images.cuda())
    else:
        output = model_ft(images)
    _, preds_tensor = torch.max(output, 1)
    preds = np.squeeze(preds_tensor.numpy()) if not train_on_gpu else np.squeeze(preds_tensor.cpu().numpy())
    print('Label:', labels, 'Predict:', preds)

我想找到一种方法,在 Pytorch 中不使用 Dataloader 预测一张单独的图片,并获得正确的预测标签。

终端结果

1 个回答

0

我解决了这个问题。

点击这里查看图片描述

出现标签错误的原因是,读取图片的目录顺序是按照1,10,100...这样的顺序,而不是1,2,3...的顺序。所以当我没有使用数据加载器(Dataloader)时,系统会把标签为2的图片预测成14。我使用了一个函数,它可以交换字典中的键和值,然后通过预测的值反向查找键,这样我就得到了正确的结果。这种方法可能不是最好的,也不是官方推荐的解决方案。

点击这里查看图片描述

撰写回答