使用learn2learn在PyTorch中转换QuickDraw图像至84×84时遇类型错误
解决learn2learn QuickDraw数据集变换时的np.memmap格式错误
问题说明
使用learn2learn加载QuickDraw数据集时,应用调整尺寸(84×84)、随机裁剪等torchvision变换会触发TypeError: Unexpected type <class 'numpy.memmap'>错误。核心原因是QuickDraw数据集以np.memmap/.npy格式存储图像,而torchvision基于PIL实现的变换无法直接处理该类型数据。
报错堆栈
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'>
解决方案
自定义一个前置变换,先将np.memmap/numpy数组转换为PIL图像,再串联后续的尺寸调整、随机裁剪等操作。示例代码如下:
from PIL import Image import numpy as np from torchvision import transforms class ToPILImageFromNumpy: def __call__(self, img): # 先将memmap转为普通numpy数组,再转成PIL灰度图(QuickDraw为单通道) if isinstance(img, np.memmap): img = np.array(img) return Image.fromarray(img.astype(np.uint8), mode='L') # 构建完整的变换流水线 train_transform = transforms.Compose([ ToPILImageFromNumpy(), transforms.Resize(96), # 先放大到96,为随机裁剪留有余量 transforms.RandomCrop(84), transforms.ToTensor(), # 可按需添加归一化等其他变换 ]) # 加载QuickDraw时传入自定义变换 from learn2learn.vision.datasets import QuickDraw train_dataset = QuickDraw(root='./data', train=True, transform=train_transform, download=True)
关键细节
- QuickDraw图像为单通道灰度数据,转换PIL图像时需指定
mode='L' - 先Resize到比目标尺寸大的尺寸再裁剪,避免直接缩放导致的图像拉伸变形
- 转换时先将np.memmap转为普通numpy数组,确保PIL能正确识别数据格式
内容的提问来源于stack exchange,提问作者Charlie Parker
相关产品推荐
相关产品推荐

