Issue about PyTorch, predicting without utilizing a DataLoader return distinct predictions compared to employing a DataLoader

48 views Asked by At

I try to predict a single image without using Dataloader, but I get a weird result.

Terminal Result

This image is the result of my prediction. With Dataloader, predicted results are consistent with labels. However, when reading a single image and making a prediction, the resulting label might differ from the expected one, yet the prediction itself remains accurate. For instance, the model predicts all labels as 14, and label 3 may be 25.

I'm new to Pytorch, and confused about this issue. Is this mandatory to apply Dataloader to predict?

The following is my main code:

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)

I want to find a way to predict a single image without Dataloader in Pytorch, and get the correct prediction label

Terminal Result

1

There are 1 answers

0
Dan On

I fixed this problem.

enter image description here

The reason for the labeling error is that the directory order of the images read is sorted by 1,10,100... instead of 1,2,3... instead of 1,2,3... So when I didn't use Dataloader, it would predict the image for label 2 to be 14. I used a function that exchanges the Key and values in the dictionary and then backtracks through the predicted values to find the Key, and I get the correct result. This way may not be the best or the official solution.

enter image description here