我正在尝试使用 learn2learn 的 QuickDraw,但当我尝试对其应用转换(调整大小为 84x84,随机裁剪)时似乎出现错误。问题源于 l2l 的 quickdraw 库尝试将转换应用到 quickdraw 图像(显然是以 PIL 无法理解的 np.memmap/.npy 记录的形式),所以我收到以下错误:
Traceback (most recent call last):
File "/home/pzy2/diversity-for-predictive-success-of-meta-learning/div_src/diversity_src/dataloaders/maml_patricks_l2l.py", line 2300, in <module>
loop_through_l2l_indexable_benchmark_with_model_test()
File "/home/pzy2/diversity-for-predictive-success-of-meta-learning/div_src/diversity_src/dataloaders/maml_patricks_l2l.py", line 2259, in loop_through_l2l_indexable_benchmark_with_model_test
for benchmark in [quickdraw_l2l_tasksets()]: #hdb8_l2l_tasksets(),hdb9_l2l_tasksets(), delaunay_l2l_tasksets()]:#[dtd_l2l_tasksets(), cu_birds_l2l_tasksets(), fc100_l2l_tasksets()]:
File "/home/pzy2/diversity-for-predictive-success-of-meta-learning/div_src/diversity_src/dataloaders/maml_patricks_l2l.py", line 2216, in quickdraw_l2l_tasksets
_transforms: tuple[TaskTransform, TaskTransform, TaskTransform] = get_task_transforms_quickdraw(_datasets,
File "/home/pzy2/diversity-for-predictive-success-of-meta-learning/div_src/diversity_src/dataloaders/maml_patricks_l2l.py", line 2184, in get_task_transforms_quickdraw
train_transforms: TaskTransform = DifferentTaskTransformIndexableForEachDataset(train_dataset,
File "/home/pzy2/diversity-for-predictive-success-of-meta-learning/div_src/diversity_src/dataloaders/common.py", line 130, in __init__
self.indexable_dataset = MetaDataset(indexable_dataset)
File "learn2learn/data/meta_dataset.pyx", line 59, in learn2learn.data.meta_dataset.MetaDataset.__init__
File "learn2learn/data/meta_dataset.pyx", line 96, in learn2learn.data.meta_dataset.MetaDataset.create_bookkeeping
File "learn2learn/data/meta_dataset.pyx", line 65, in learn2learn.data.meta_dataset.MetaDataset.__getitem__
File "/home/pzy2/miniconda3/envs/metalearning3.9/lib/python3.9/site-packages/learn2learn/vision/datasets/quickdraw.py", line 511, in __getitem__
image = self.transform(image)
File "/home/pzy2/miniconda3/envs/metalearning3.9/lib/python3.9/site-packages/torchvision/transforms/transforms.py", line 60, in __call__
img = t(img)
File "/home/pzy2/miniconda3/envs/metalearning3.9/lib/python3.9/site-packages/torch/nn/modules/module.py", line 1051, in _call_impl
return forward_call(*input, **kwargs)
File "/home/pzy2/miniconda3/envs/metalearning3.9/lib/python3.9/site-packages/torchvision/transforms/transforms.py", line 900, in forward
i, j, h, w = self.get_params(img, self.scale, self.ratio)
File "/home/pzy2/miniconda3/envs/metalearning3.9/lib/python3.9/site-packages/torchvision/transforms/transforms.py", line 859, in get_params
width, height = F._get_image_size(img)
File "/home/pzy2/miniconda3/envs/metalearning3.9/lib/python3.9/site-packages/torchvision/transforms/functional.py", line 67, in _get_image_size
return F_pil._get_image_size(img)
File "/home/pzy2/miniconda3/envs/metalearning3.9/lib/python3.9/site-packages/torchvision/transforms/functional_pil.py", line 26, in _get_image_size
raise TypeError("Unexpected type {}".format(type(img)))
TypeError: Unexpected type <class 'numpy.memmap'>
原创:
尝试将 numpy.memmap 对象转换为 NumPy 数组,然后再转换为 PIL 图像。
如果您正在使用
torchvision.transforms.ToTensor
,这是不可能直接的,因为如文档中所述
在转换目标图像蒙版时不应使用此转换
查看this而不是查看调整大小的正确方法
这是引用自这个answer的例子:
>>> 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'>
试试这个代码,让我知道它是怎么回事
import torch
import torchvision.transforms as transforms
from PIL import Image
from learn2learn.data import QuickDraw
quickdraw = QuickDraw(root='path/to/quickdraw/data', train=True, transform=None)
transform = transforms.Compose([
transforms.Resize(84),
transforms.CenterCrop(84),
transforms.ToTensor(),
])
# Get an example QuickDraw image
img, _ = quickdraw[0]
# Convert to PIL image
img = Image.fromarray(img)
# Apply transform
img = transform(img)
# Add a batch dimension
img = img.unsqueeze(0)
# Display the transformed image
print(img.shape) # torch.Size([1, 1, 84, 84])
基于缺乏代码,我会从你一年前的issue #333中得到一些启发。我想它改变了很多,你不是在做同样的事情。虽然,我认为你保留了基本的数据结构。
您想基于您的 QuickDraw 数据集创建您的
MetaDataset
。我不认为QuickDraw可以通过MetaDataset
直接索引,因为MetaDataset
调用每个元素。如果您对错误的数据格式应用 data 转换 -> 就会出现不兼容性。
实际上,如果您查看 repo 上的 quickdraw,
MetaDataset
不会从它的任何地方实例化。这是因为它不起作用:这是你的错误。
问题如下:如何在quickdraw上做簿记(索引),与其他数据集相比似乎很大?
我建议你:
QuickDraw
类。 MetaDataset
你不会有(很长的)簿记。此索引可以存储在 .pkl
文件中,因此您只能执行一次。np.memmap
转换为 PIL
或 Tensor
对象。嘿伙计,你可以使用这段代码创建一个自定义转换函数,它首先使用 numpy 加载图像,然后应用必要的转换
import numpy as np
import torch
import torchvision.transforms.functional as F
class CustomTransform:
def __init__(self):
self.transform = transforms.Compose([
transforms.ToPILImage(),
transforms.Resize((84, 84)),
transforms.RandomCrop(84),
transforms.ToTensor()
])
def __call__(self, x):
x = np.load(x)
x = F.to_pil_image(x)
x = self.transform(x)
return x
我创建了一个
CustomTransform
类,它使用 QuickDraw
加载 numpy
图像,然后使用 transforms.Compose
模块中的 torchvision.transforms
函数应用必要的转换。此类的__call__
方法将QuickDraw图像的文件路径作为输入,使用numpy加载它,使用PIL应用转换,然后将其转换为PyTorch张量。
Charlie,您可以使用此自定义转换函数在 learn2learn 框架内转换您的 QuickDraw 数据集 您可以将此转换作为参数传递给
TaskDataset
构造函数,就像任何其他 PyTorch 转换一样:像这样的代码:
from learn2learn.data import TaskDataset
from learn2learn.vision.datasets import QuickDraw
custom_transform = CustomTransform()
quickdraw = QuickDraw(root='./data/quickdraw')
dataset = TaskDataset(
quickdraw,
transform=custom_transform,
target_transform=None,
task_transform=None,
num_tasks=10
)
TaskDataset
对象与 QuickDraw 数据集根据您的自定义转换函数进行转换。 num_tasks 参数指定要从数据集中生成的任务数。
希望这段代码能帮到你。祝查理好运