对于涉及回归的任务,我需要训练模型以从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转换.RandomHorizontalFlip函数仅接受PIL图像(不允许numpy)作为输入。所以我决定将类型转换为PIL图像。
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)
我希望您能提出一些加快我的增强过程的建议
答案 0 :(得分: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
希望宽度轴在那里。
来自docs:
转换PIL图像或 numpy.ndarray (H xW x C)...
答案 1 :(得分:1)
对@Berriel答案的更多补充。
您同时为transforms.RandomHorizontalFlip(p=1)
和X
图像使用y
。在您的情况下,使用p=1
时,这些转换将完全相同,但由于网络只能看到翻转的图像(而不是原始图像),因此您缺少数据扩充的要点。您应该选择小于1且大于0(通常为0.5
)的概率,以使图像的版本具有较高的可变性。
如果是这种情况(p=0.5
,您可以肯定会发生X
被翻转而y
未被翻转的情况。
我建议使用albumentations
库,并且albumentations.augmentations.transforms.HorizontalFlip
可以以相同的方式对两个图像进行翻转。
您可以在normalization
中找到ImageNet
的均值和标准差。
此外,为加快速度,您可以使用torchdata
第三方库(免责声明,我是作者)。在您的情况下,您可以将PIL
的图像从Tensor
转换为Normalize
,将albumentations
转换为cache
在磁盘上,甚至可以将RAM图像转换为{ {1}},最后应用您的转换。这样一来,您仅可以在初始时期之后将torchdata
应用于图像和目标,而之前的步骤将被预先计算。