PyTorch - 获取 'TypeError: pic 应该是 PIL Image 或 ndarray。得到 <class 'numpy.ndarray'>' 错误
Posted
技术标签:
【中文标题】PyTorch - 获取 \'TypeError: pic 应该是 PIL Image 或 ndarray。得到 <class \'numpy.ndarray\'>\' 错误【英文标题】:PyTorch - Getting the 'TypeError: pic should be PIL Image or ndarray. Got <class 'numpy.ndarray'>' errorPyTorch - 获取 'TypeError: pic 应该是 PIL Image 或 ndarray。得到 <class 'numpy.ndarray'>' 错误 【发布时间】:2019-11-06 12:40:59 【问题描述】:当我尝试通过DataLoader
加载非图像数据集时,我收到错误TypeError: pic should be PIL Image or ndarray. Got <class 'numpy.ndarray'>
。 torch
和torchvision
的版本分别是1.0.1
和0.2.2.post3
。 Python 的版本是3.7.1
在Windows 10
机器上。
代码如下:
class AndroDataset(Dataset):
def __init__(self, csv_path):
self.transform = transforms.Compose([transforms.ToTensor()])
csv_data = pd.read_csv(csv_path)
self.csv_path = csv_path
self.features = []
self.classes = []
self.features.append(csv_data.iloc[:, :-1].values)
self.classes.append(csv_data.iloc[:, -1].values)
def __getitem__(self, index):
# the error occurs here
return self.transform(self.features[index]), self.transform(self.classes[index])
def __len__(self):
return len(self.features)
我设置了加载器:
training_data = AndroDataset('android.csv')
train_loader = DataLoader(dataset=training_data, batch_size=batch_size, shuffle=True)
这是完整的错误堆栈跟踪:
Traceback (most recent call last):
File "C:\Program Files\JetBrains\PyCharm 2018.1.2\helpers\pydev\pydevd.py", line 1758, in <module>
main()
File "C:\Program Files\JetBrains\PyCharm 2018.1.2\helpers\pydev\pydevd.py", line 1752, in main
globals = debugger.run(setup['file'], None, None, is_module)
File "C:\Program Files\JetBrains\PyCharm 2018.1.2\helpers\pydev\pydevd.py", line 1147, in run
pydev_imports.execfile(file, globals, locals) # execute the script
File "C:\Program Files\JetBrains\PyCharm 2018.1.2\helpers\pydev\_pydev_imps\_pydev_execfile.py", line 18, in execfile
exec(compile(contents+"\n", file, 'exec'), glob, loc)
File "C:/Users/talha/Documents/PyCharmProjects/DeepAndroid/deep_test_conv1d.py", line 231, in <module>
main()
File "C:/Users/talha/Documents/PyCharmProjects/DeepAndroid/deep_test_conv1d.py", line 149, in main
for i, (images, labels) in enumerate(train_loader):
File "C:\Users\talha\Documents\PyCharmProjects\DeepAndroid\venv\lib\site-packages\torch\utils\data\dataloader.py", line 615, in __next__
batch = self.collate_fn([self.dataset[i] for i in indices])
File "C:\Users\talha\Documents\PyCharmProjects\DeepAndroid\venv\lib\site-packages\torch\utils\data\dataloader.py", line 615, in <listcomp>
batch = self.collate_fn([self.dataset[i] for i in indices])
File "C:/Users/talha/Documents/PyCharmProjects/DeepAndroid/deep_test_conv1d.py", line 102, in __getitem__
return self.transform(self.features[index]), self.transform(self.classes[index])
File "C:\Users\talha\Documents\PyCharmProjects\DeepAndroid\venv\lib\site-packages\torchvision\transforms\transforms.py", line 60, in __call__
img = t(img)
File "C:\Users\talha\Documents\PyCharmProjects\DeepAndroid\venv\lib\site-packages\torchvision\transforms\transforms.py", line 91, in __call__
return F.to_tensor(pic)
File "C:\Users\talha\Documents\PyCharmProjects\DeepAndroid\venv\lib\site-packages\torchvision\transforms\functional.py", line 50, in to_tensor
raise TypeError('pic should be PIL Image or ndarray. Got '.format(type(pic)))
TypeError: pic should be PIL Image or ndarray. Got <class 'numpy.ndarray'>
【问题讨论】:
【参考方案1】:这是因为您使用了转换:
self.transform = transforms.Compose([transforms.ToTensor()])
正如您在documentation 中看到的,torchvision.transforms.ToTensor
将 PIL 图像或 numpy.ndarray
转换为张量。因此,如果您想使用这种转换,您的数据必须是上述类型之一。
【讨论】:
我认为错误描述证实了您所说的。但是我的数据已经是ndarray
的一个实例,正如错误描述中所说的那样。
@talha06 您的数据的形状和类型是什么?它应该是三个维度,根据文档,numpy.ndarray 应该有 dtype = np.uint8
它是二维的,它的形状是(5289, 38)
。 dtype
是 int64
,因为我没有明确地将其转换为。只需将csv
数据读入dataframe
,然后取其值为ndarray
。
好的,看来您需要更改类型和形状以满足文档中的要求(因此添加通道尺寸,根据您的形状可以只是一个通道)【参考方案2】:
扩展@MiriamFarber 的答案,您不能在numpy.ndarray
对象上使用transforms.ToTensor()
。您可以使用 torch.from_numpy()
将 numpy
数组转换为 torch
张量,然后将您的张量转换为所需的数据类型。
例如:
>>> import numpy as np
>>> import torch
>>> np_arr = np.ones((5289, 38))
>>> torch_tensor = torch.from_numpy(np_arr).long()
>>> type(np_arr)
<class 'numpy.ndarray'>
>>> type(torch_tensor)
<class 'torch.Tensor'>
【讨论】:
【参考方案3】:如果要在numpy
数组上使用torchvision.transforms,首先使用transforms.ToPILImage()
将numpy 数组转换为PIL Image 对象
【讨论】:
为什么说你可以使用ndarray
呢?不是和np.ndarray
一样吗?【参考方案4】:
tf=transforms.Compose([
transforms.ToPILImage(),
transforms.Resize((512,640)),
transforms.ToTensor()
])
它对我有用。
【讨论】:
以上是关于PyTorch - 获取 'TypeError: pic 应该是 PIL Image 或 ndarray。得到 <class 'numpy.ndarray'>' 错误的主要内容,如果未能解决你的问题,请参考以下文章
Pytorch 1.7.0 | DataLoader 错误 - TypeError:“模块”对象不可调用
PyTorch - TypeError: forward() 接受 1 个位置参数,但给出了 2 个
Ray[tune] for pytorch TypeError: ray.cloudpickle.dumps
PyTorch BERT TypeError: forward() got an unexpected keyword argument 'labels'
亲测已解决TypeError: __init__() takes 1 positional argument but 2 were given
python pip install 报错TypeError: unsupported operand type(s) for -=: 'Retry' and 'int'