如何在数据集上使用map()?解决ViT训练中DataLoader无map属性报错
问题解决:AttributeError: 'DataLoader' object has no attribute 'map'
错误原因很明确:你调用的map()是Hugging Face Dataset类的专属方法,但当前调用对象是PyTorch的DataLoader,它并不具备这个方法。下面提供两种可行的解决思路:
方案一:改用Hugging Face Dataset加载数据(推荐,适配你的预处理逻辑)
既然你用到了Hugging Face的ViTFeatureExtractor和批量预处理需求,直接用Hugging Face的Dataset加载数据更顺畅:
from datasets import load_dataset from transformers import ViTFeatureExtractor, default_data_collator from torch.utils.data import DataLoader # 1. 自动识别文件夹结构加载数据集 # 替换为你的数据集根目录,需保证根目录下有train/val/test子文件夹 dataset = load_dataset("imagefolder", data_dir="./your_dataset_root") # 2. 初始化特征提取器和预处理函数 feature_extractor = ViTFeatureExtractor.from_pretrained('google/vit-base-patch16-224-in21k') def preprocess_images(examples): # 直接用特征提取器处理图片,无需手动转数组 inputs = feature_extractor(examples['image'], return_tensors="pt") examples['pixel_values'] = inputs['pixel_values'] # 将字符串标签转为数字索引 examples['label'] = [dataset['train'].features['label'].str2int(lbl) for lbl in examples['label']] return examples # 3. 批量预处理数据集 processed_dataset = dataset.map(preprocess_images, batched=True) # 4. 转为PyTorch格式并生成DataLoader processed_dataset.set_format("torch", columns=["pixel_values", "label"]) train_loader = DataLoader(processed_dataset['train'], batch_size=1, shuffle=True, num_workers=3) val_loader = DataLoader(processed_dataset['validation'], batch_size=1, shuffle=True) test_loader = DataLoader(processed_dataset['test'], batch_size=1, shuffle=True)
说明:load_dataset("imagefolder")会自动识别train/val/test分文件夹、子文件夹对应类别的结构,无需手动编写Dataset类。
方案二:在自定义PyTorch Dataset中集成预处理
如果坚持使用自己编写的PyTorch Dataset,直接把预处理逻辑嵌入__getitem__方法即可,无需调用map:
from torch.utils.data import Dataset, DataLoader from PIL import Image import glob from transformers import ViTFeatureExtractor class MyDataset(Dataset): def __init__(self, path, feature_extractor): self.files = glob.glob(path) self.feature_extractor = feature_extractor # 定义标签到数字的映射 self.label_map = {'class1':0, 'class2':1, 'class3':2, 'class4':3} self.labels = [self.label_map[filepath.split('/')[-2]] for filepath in self.files] def __getitem__(self, item): file_path = self.files[item] label = self.labels[item] # 加载图片并完成预处理 image = Image.open(file_path).convert("RGB") inputs = self.feature_extractor(images=image, return_tensors="pt") # 移除单个样本的batch维度(DataLoader会自动添加批量维度) pixel_values = inputs['pixel_values'].squeeze(0) return pixel_values, label def __len__(self): return len(self.files) # 初始化特征提取器 feature_extractor = ViTFeatureExtractor.from_pretrained('google/vit-base-patch16-224-in21k') # 加载数据集 train_data = MyDataset(train_path, feature_extractor) val_data = MyDataset(val_path, feature_extractor) test_data = MyDataset(test_path, feature_extractor) # 生成DataLoader train_loader = DataLoader(train_data, batch_size=1, shuffle=True, num_workers=3) val_loader = DataLoader(val_data, batch_size=1, shuffle=True) test_loader = DataLoader(test_data, batch_size=1, shuffle=True)
说明:这种方式将预处理逻辑直接嵌入Dataset的样本获取流程,每次取数据时自动完成预处理,无需额外调用map方法。
内容的提问来源于stack exchange,提问作者Ltl
相关产品推荐
相关产品推荐

