问题描述
我对Pytorch执行的数据增强有些困惑.现在,据我所知,当我们执行数据增强时,我们将保留原始数据集,然后添加其他版本(翻转,裁剪等).但这似乎并没有发生在Pytorch中.据我从参考文献中理解的,当我们在Pytorch中使用data.transforms时,它将它们一个一个应用.因此:
data_transforms = { 'train': transforms.Compose([ transforms.RandomResizedCrop(224), transforms.RandomHorizontalFlip(), transforms.ToTensor(), transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225]) ]), 'val': transforms.Compose([ transforms.Resize(256), transforms.CenterCrop(224), transforms.ToTensor(), transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225]) ]), }
在这里,对于培训,我们首先是随机裁剪图像并将其调整为Shape (224,224).然后,我们正在拍摄这些(224,224)图像,然后水平翻转它们.因此,我们的数据集现在仅包含水平翻转的图像,因此在这种情况下,我们的原始图像丢失了.
我对吗?这种理解正确吗?如果没有,那么我们在上面的该代码中(取自官方文档)将Pytorch告诉原始图像并将其调整到预期的形状(224,224)?
中,我们要在哪里告诉Pytorch谢谢
推荐答案
transforms操作在每个批处理生成时都应用于您的原始图像.因此,您的数据集保持不变,仅复制批处理图像并转换了所有迭代.
混乱可能来自以下事实:在您的示例中,transforms通常都用于数据准备(调整/裁剪到预期的尺寸,正常值等)和数据扩展(随机调整/调整大小裁剪,随机翻转图像等).
您的data_transforms['train']做什么是:
- 随机调整提供的图像并随机裁剪以获取(224, 224) patch
- 使用50/50 Chance 申请或不随机水平翻转
- 将其转换为Tensor
- 给定提供的平均值和偏差值 ,将结果标准化
您的data_transforms['val']是:
- 将图像大小调整到(256, 256)
- 中心裁剪大小的图像以获得(224, 224)补丁
- 将其转换为Tensor
- 给定提供的平均值和偏差值 ,将结果标准化
(即.
如果您不希望训练图像以50/50的机会水平翻转,请删除transforms.RandomHorizontalFlip()线.
类似地,如果您希望图像始终为中心编写,请替换transforms.RandomResizedCrop transforms.Resize和transforms.CenterCrop,如data_transforms['val'].
其他推荐答案
我假设您在问您是否正在问这些数据扩展变换(例如Randomhorizontalflip)实际上也会增加数据集的大小,还是将它们应用于数据集中的每个项目上一一且不添加数据集的大小.
运行以下简单代码段,我们可以观察到后者是true ,即,如果您的数据集的8张图像,并在通过数据集进行迭代时为该数据集创建一个pytorch数据集对象,每个数据点都调用转换,然后返回转换的数据点.因此,例如,如果您有随机翻转,则某些数据点作为原始返回,有些数据被返回为翻转(例如4个翻转和4个原始). 换句话说,通过通过数据集项目进行一次迭代,您将获得8个数据点(有些翻转,有些则没有). [这与扩展数据集的常规理解不符(例如,在这种情况下,增强数据集中有16个数据点)]
class experimental_dataset(Dataset): def __init__(self, data, transform): self.data = data self.transform = transform def __len__(self): return len(self.data.shape[0]) def __getitem__(self, idx): item = self.data[idx] item = self.transform(item) return item transform = transforms.Compose([ transforms.ToPILImage(), transforms.RandomHorizontalFlip(), transforms.ToTensor() ]) x = torch.rand(8, 1, 2, 2) print(x) dataset = experimental_dataset(x,transform) for item in dataset: print(item)
结果:(浮点的差异很小是由转换为pil图像和背部引起的)
)原始虚拟数据集:
tensor([[[[0.1872, 0.5518], [0.5733, 0.6593]]], [[[0.6570, 0.6487], [0.4415, 0.5883]]], [[[0.5682, 0.3294], [0.9346, 0.1243]]], [[[0.1829, 0.5607], [0.3661, 0.6277]]], [[[0.1201, 0.1574], [0.4224, 0.6146]]], [[[0.9301, 0.3369], [0.9210, 0.9616]]], [[[0.8567, 0.2297], [0.1789, 0.8954]]], [[[0.0068, 0.8932], [0.9971, 0.3548]]]])
转换的数据集:
tensor([[[0.1843, 0.5490], [0.5725, 0.6588]]]) tensor([[[0.6549, 0.6471], [0.4392, 0.5882]]]) tensor([[[0.5647, 0.3255], [0.9333, 0.1216]]]) tensor([[[0.5569, 0.1804], [0.6275, 0.3647]]]) tensor([[[0.1569, 0.1176], [0.6118, 0.4196]]]) tensor([[[0.9294, 0.3333], [0.9176, 0.9608]]]) tensor([[[0.8549, 0.2275], [0.1765, 0.8941]]]) tensor([[[0.8902, 0.0039], [0.3529, 0.9961]]])
其他推荐答案
是的,转换后,数据集大小不会更改.每个图像都传递给转换并返回,因此大小保持不变.
如果您想将原始数据集与转换的一个concat一起使用.
例如increased_dataset = torch.utils.data.ConcatDataset([transformed_dataset,original])