如何使用 learn2learn 库在 pytorch 中将 quickdraw 图像转换为 84 x 84?

问题描述 投票:0回答:5

我正在尝试使用 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'>

原创:

python machine-learning deep-learning pytorch learn2learn
5个回答
0
投票

尝试将 numpy.memmap 对象转换为 NumPy 数组,然后再转换为 PIL 图像。


0
投票

如果您正在使用

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'>

0
投票

试试这个代码,让我知道它是怎么回事

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])

0
投票

基于缺乏代码,我会从你一年前的issue #333中得到一些启发。我想它改变了很多,你不是在做同样的事情。虽然,我认为你保留了基本的数据结构。

您想基于您的 QuickDraw 数据集创建您的

MetaDataset
。我不认为QuickDraw可以通过
MetaDataset
直接索引,因为
MetaDataset
调用每个元素。如果您对错误的数据格式应用 data 转换 -> 就会出现不兼容性。

实际上,如果您查看 repo 上的 quickdraw,

MetaDataset
不会从它的任何地方实例化。这是因为它不起作用:这是你的错误。

问题如下:如何在quickdraw上做簿记(索引),与其他数据集相比似乎很大?

我建议你:

  1. 根据 quickdraw repo 中的注释文件执行自己的书。然后你可以把它有一个属性给你的新
    QuickDraw
    类。
    MetaDataset
    你不会有(很长的)簿记。此索引可以存储在
    .pkl
    文件中,因此您只能执行一次。
  2. 然后只为 QuickDraw 添加预转换。实际上,如果你真的不想在你的课堂上触及你的变换,比方说,我不知道你的约束,你可以猴子修补对象,在最坏的情况下。但是更合理的解决方法是在您的 data 转换中插入一个函数,以将
    np.memmap
    转换为
    PIL
    Tensor
    对象。

0
投票

嘿伙计,你可以使用这段代码创建一个自定义转换函数,它首先使用 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 参数指定要从数据集中生成的任务数。

希望这段代码能帮到你。祝查理好运

© www.soinside.com 2019 - 2024. All rights reserved.