如何将Torchvision Transforms应用于Numpy数组?训练时机该如何选择?
问题解决方案
一、如何将Transform应用到数据集
你当前使用的TensorDataset不支持直接传入transform处理数据,需要自定义Dataset类来实现变换的应用,同时要注意训练集和验证集的transform必须区分开:验证集不能使用随机增强操作(比如随机裁剪、随机翻转),否则会干扰模型的评估结果。
1. 自定义Dataset类
这个类会在每次获取样本时自动应用指定的transform:
from torch.utils.data import Dataset class CustomImageDataset(Dataset): def __init__(self, data, labels, transform=None): self.data = data self.labels = labels self.transform = transform def __len__(self): return len(self.data) def __getitem__(self, idx): # 获取单张图片和标签 img = self.data[idx] label = self.labels[idx] # 应用变换(如果有) if self.transform: # 注意:如果你的X_train是0-1范围的float数组,需要先转成0-255的uint8,否则ToPILImage会显示异常 # 可添加这行代码:img = (img * 255).astype('uint8') img = self.transform(img) return img, label
2. 分别定义训练/验证集的Transform
- 训练集:保留随机增强操作,提升模型泛化能力
- 验证集:仅做固定尺寸调整、转Tensor和归一化,避免随机操作影响评估
from torchvision import transforms # 训练集变换(带随机增强) train_transform = transforms.Compose([ transforms.ToPILImage(), transforms.RandomResizedCrop(224), transforms.RandomHorizontalFlip(), transforms.ToTensor(), transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]), ]) # 验证集变换(无随机操作) val_transform = transforms.Compose([ transforms.ToPILImage(), transforms.Resize((224, 224)), # 固定resize到指定尺寸 transforms.ToTensor(), transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]), ])
3. 创建数据集与DataLoader
替换原来的TensorDataset为自定义的Dataset类:
train_dataset = CustomImageDataset(X_train, y_train, transform=train_transform) val_dataset = CustomImageDataset(X_val, y_val, transform=val_transform) # 定义DataLoader(和你原来的代码一致) train_loader = torch.utils.data.DataLoader(train_dataset, batch_size=32, shuffle=True, num_workers=4) val_loader = torch.utils.data.DataLoader(val_dataset, batch_size=32, shuffle=False, num_workers=4)
二、变换的执行时机
必须在**训练过程中(即DataLoader加载每个样本/批次时)**执行这些变换,原因如下:
- 对于
RandomResizedCrop、RandomHorizontalFlip这类随机增强操作,需要每个epoch甚至每个样本加载时生成不同的变换结果,这样才能让模型接触到更多样的样本变体,真正起到数据增强、提升泛化能力的作用。如果提前对整个数据集做一次增强再保存,所有样本的增强结果固定,就失去了随机增强的意义。 - 归一化操作虽然可以提前预处理,但和随机增强一起在加载时处理更便捷,也避免重复计算。
内容的提问来源于stack exchange,提问作者Marco
相关产品推荐
相关产品推荐

