2

对于涉及回归的任务,我需要训练我的模型从 RGB 图像生成密度图。为了增加我的数据集,我决定水平翻转所有图像。就此而言,我还必须翻转我的真实图像,我也这样做了。

dataset_for_augmentation.listDataset(train_list,
                        shuffle=True,
                        transform=transforms.Compose([
                            transforms.RandomHorizontalFlip(p=1),
                            transforms.ToTensor(),
                            transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]),
                        ]),
                        target_transform=transforms.Compose([
                            transforms.RandomHorizontalFlip(p=1),
                            transforms.ToTensor()
                        ]),
                        train=True,
                        resize=4,
                        batch_size=args.batch_size,
                        num_workers=args.workers),

但问题是:出于某种原因,PyTorch transforms.RandomHorizo​​ntalFlip 函数仅将 PIL 图像(不允许使用 numpy)作为输入。所以我决定将类型转换为 PIL Image。

img_path = self.lines[index]

img, target = load_data(img_path, self.train, resize=self.resize)

if type(target[0][0]) is np.float64:
    target = np.float32(target)

img = Image.fromarray(img)
target = Image.fromarray(target)

if self.transform is not None:
    img = self.transform(img)
    target = self.target_transform(target)

return img, target

是的,这个操作需要大量的时间。考虑到我需要对数千张图像执行此操作,每批 23 秒(最多应该不到半秒)是不能容忍的。

2019-11-01 16:29:02,497 - INFO - Epoch: [0][0/152]  Time 27.095 (27.095)    Data 23.150 (23.150)    Loss 93.7401 (93.7401)

如果有任何建议可以加快我的增强过程,我将不胜感激

4

2 回答 2

3

您无需更改DataLoader即可。您可以使用ToPILImage()

transform=transforms.Compose([
    transforms.ToPILImage(),  # check mode assumption in the documentation
    transforms.RandomHorizontalFlip(p=1),
    transforms.ToTensor(),
    transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]),
])

无论如何,我会避免转换为 PIL。这似乎完全没有必要。如果你想翻转所有图像,那么为什么不只使用 NumPy 来做呢?

img_path = self.lines[index]

img, target = load_data(img_path, self.train, resize=self.resize)

if type(target[0][0]) is np.float64:
    target = np.float32(target)

# assuming width axis=1 -- see my comment below
img = np.flip(img, axis=1)
target = np.flip(target, axis=1)

if self.transform is not None:
    img = self.transform(img)
    target = self.target_transform(target)

return img, target

transforms.RandomHorizontalFlip(p=1)Compose. 和ToTensor(...)手柄一样ndarray,你很高兴。

注意:我假设宽度轴等于 1,因为ToTensor期望它在那里。

文档

转换 PIL 图像或numpy.ndarray (H x W x C) ...

于 2019-11-01T11:54:03.190 回答
1

@Berriel答案的更多补充。

水平翻转

您同时使用transforms.RandomHorizontalFlip(p=1)X图像y。在您的情况下,使用p=1,这些将被完全转换,但您错过了数据增强的点,因为网络只会看到翻转的图像(而不仅仅是原始图像)。您应该选择低于 1 且高于 0 的概率(通常0.5)以获得图像版本的高可变性。

如果是这种情况(p=0.5),您可以确定会发生一种情况,即被X翻转而y不会。

我建议使用albumentations库,它albumentations.augmentations.transforms.HorizontalFlip以相同的方式对两个图像进行翻转。

正常化

您也可以找到已经在那里设置normalizationImageNet手段和标准。

缓存

此外,为了加快速度,您可以使用torchdata第三方库(免责声明我是作者)。在您的情况下,您可以在使用这些转换之后将图像从磁盘转换PILTensorNormalize使用albumentationscache在磁盘上,甚至更好地转换为 RAM 图像,torchdata并最终应用您的转换。这种方式将允许您仅HorizontalFlip在初始时期后将 s 应用于您的图像和目标,之前的步骤将被预先计算。

于 2019-11-01T14:18:44.803 回答