PyTorch中的数据增强
image-processing
python
pytorch
11
0

我对PyTorch中执行的数据扩充感到有些困惑。现在,据我所知,当我们执行数据扩充时,我们将保留原始数据集,然后添加它的其他版本(Flipping,Cropping等)。但这似乎并没有在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])
    ]),
}

在这里,为了进行训练,我们首先是随机裁剪图像并将其大小调整为形状(224,224) 。然后,我们将拍摄这些(224,224)张图像并水平翻转它们。因此,我们的数据集现在仅包含水平翻转的图像,因此在这种情况下我们的原始图像会丢失。

我对吗?这种理解正确吗?如果不是,那么我们在上面的这段代码中(从官方文档中获取)告诉PyTorch保留原始图像并将其大小调整为期望的形状(224,224)

谢谢

参考资料:
Stack Overflow
收藏
评论
共 2 个回答
高赞 时间 活跃

transforms操作将在每个批次生成时应用于原始图像。因此,您的数据集保持不变,只有批处理图像在每次迭代时都被复制和转换。

造成混淆的原因可能是,经常像您的示例中那样, transforms既用于数据准备(将大小调整/裁剪为预期的尺寸,对值进行归一化等)又用于数据增强(将大小调整/裁剪随机化,随机翻转图片等)。


您的data_transforms['train']所做的是:

  • 随机调整提供的图像大小并随机裁剪以获取(224, 224)补丁
  • 是否对该补丁应用随机水平翻转,机会为50/50
  • 将其转换为Tensor
  • 给定您提供的平均值和偏差值,对结果Tensor归一化

您的data_transforms['val']所做的是:

  • 将图像调整为(256, 256)
  • 中心裁剪调整大小的图像以获得(224, 224)色块
  • 将其转换为Tensor
  • 给定您提供的平均值和偏差值,对结果Tensor归一化

(即,将训练数据的随机调整大小/裁剪替换为用于验证的固定操作,以得到可靠的验证结果)


如果您不希望训练图像以50/50的机会水平翻转,只需删除transforms.RandomHorizontalFlip()行即可。

同样,如果你希望你的图片永远是中心,裁剪,替换transforms.RandomResizedCrop通过transforms.Resizetransforms.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]]])
收藏
评论
新手导航
  • 社区规范
  • 提出问题
  • 进行投票
  • 个人资料
  • 优化问题
  • 回答问题

关于我们

常见问题

内容许可

联系我们

@2020 AskGo
京ICP备20001863号