【问题标题】:TypeError: tensor is not a torch imageTypeError:张量不是火炬图像
【发布时间】:2019-01-19 06:45:12
【问题描述】:

在学习 Udacity 的 AI 课程时,我在迁移学习部分遇到了这个错误。这是似乎导致问题的代码:

import torch
from torch import nn
from torch import optim
import torch.nn.functional as F
from torchvision import datasets, transforms, models

data_dir = 'filename'

# TODO: Define transforms for the training data and testing data
train_transforms= transforms.Compose([transforms.Resize((224,224)), transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]), transforms.ToTensor()])
test_transforms= transforms.Compose([transforms.Resize((224,224)), transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]), transforms.ToTensor()])

# Pass transforms in here, then run the next cell to see how the transforms look
train_data = datasets.ImageFolder(data_dir + '/train', transform=train_transforms)
test_data = datasets.ImageFolder(data_dir + '/test', transform=test_transforms)

trainloader = torch.utils.data.DataLoader(train_data, batch_size=64, shuffle=True)
testloader = torch.utils.data.DataLoader(test_data, batch_size=32)

【问题讨论】:

    标签: python pytorch


    【解决方案1】:

    问题在于转换的顺序。 ToTensor 变换应该在 Normalize 变换之前,因为后者需要一个张量,但 Resize 变换返回一个图像。更改了错误行的正确代码:

    train_transforms = transforms.Compose([
        transforms.Resize((224,224)), 
        transforms.ToTensor(), 
        transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])])
    test_transforms = transforms.Compose([
        transforms.Resize((224,224)), 
        transforms.ToTensor(), 
        transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])])
    

    【讨论】:

    • 我确实遵循了同样的顺序,现在我得到了:TypeError: batch must contain tensors, numbers, dicts or lists; found <class 'PIL.PngImagePlugin.PngImageFile'>
    • @Kasparov92 你使用的是哪个版本的 Pytorch?
    【解决方案2】:

    另一个不太优雅的解决方案(假设图像是用 opencv 加载的,因此是 BGR):

    t_ = transforms.Compose([transforms.ToPILImage(),
                             transforms.Resize((224,224)),
                             transforms.ToTensor()])
    
    norm_ = transforms.Normalize([103.939, 116.779, 123.68],[1,1,1])
    img = 255*t_(img)
    img = norm_(img)
    

    【讨论】:

      【解决方案3】:

      这个错误的一个原因是transforms.Normalize 只接受 3d 数据(3、224、224)。这是一个示例代码:

      # imagenet normalize
      
      from torchvision.transforms import Normalize
      
      mean = [0.485, 0.456, 0.406]
      std = [0.229, 0.224, 0.225]
      normalize = Normalize(mean, std)
      
      
      img = np.random.choice(255, (10, 224, 224, 3))
      img = img/255 # [0, 1]
      img = torch.tensor(img, device=device).float().permute(0, 3, 1, 2)
      img = normalize(img)
      

      这将引发错误,因为输入数据具有 4d 形状。如果你把代码改成这个,那么错误就会消失。

      img = np.random.choice(255, (224, 224, 3))
      

      【讨论】:

      • 那么,我该如何标准化一个批次?
      【解决方案4】:

      就我而言,我遇到了the comment of shark deng 中描述的问题:规范化不适用于批处理。

      我的一个解决方案是改用 torchvision.transforms.functional.normalize,它适用于批处理。

      【讨论】:

        猜你喜欢
        • 2017-04-04
        • 2017-02-23
        • 2022-07-20
        • 2020-06-22
        • 1970-01-01
        • 1970-01-01
        • 2021-12-12
        • 2022-01-20
        • 2015-09-16
        相关资源
        最近更新 更多