当前位置:   article > 正文

图像增强(albumentations)与随机种子_torchvision.transforms vs albumentations

torchvision.transforms vs albumentations

通过torchvision.transforms,可实现不同batch的训练样本根据transforms设置的各种图像处理的概率

我们知道,用torchvision.transforms、albumentations等库通过配置transforms pipline可以实现数据增强。根据定义的每种图像处理对应的概率,使得每个batch中,同个样本会做不同的图像处理,从而得到各种不同的变体图像。通过这样的方式,可以变相达到增加训练样本的目标,达到丰富我们的训练样本的目的。

但我有个疑问,如果固定随机种子,是否会使得不同batch中采取相同的图像处理(本人图像小白,所以如果觉得这是一个蠢问题,烦请略过... 谢谢)。所以简单做了一个实验。

先说结论:固定随机种子后,同个样本,在各个batch下所做的图像处理是不同的。

 

具体如下:

为了加快训练,训练样本只用了一个图像样本。如下图。

我使用的是albumentations来做数据增强,以下是我数据增强的配置文件。

{"__version__": "0.3.1", "transform": {"__class_fullname__": "albumentations.core.composition.Compose", "p": 1.0, "transforms": [{"__class_fullname__": "albumentations.augmentations.transforms.HorizontalFlip", "always_apply": false, "p": 0.5}, {"__class_fullname__": "albumentations.core.composition.OneOf", "p": 0.3, "transforms": [{"__class_fullname__": "albumentations.augmentations.transforms.RandomContrast", "always_apply": false, "p": 0.5, "limit": [-0.2, 0.2]}, {"__class_fullname__": "albumentations.augmentations.transforms.RandomGamma", "always_apply": false, "p": 0.5, "gamma_limit": [80, 120]}, {"__class_fullname__": "albumentations.augmentations.transforms.RandomBrightness", "always_apply": false, "p": 0.5, "limit": [-0.2, 0.2]}]}, {"__class_fullname__": "albumentations.core.composition.OneOf", "p": 0.3, "transforms": [{"__class_fullname__": "albumentations.augmentations.transforms.ElasticTransform", "always_apply": false, "p": 0.5, "alpha": 120, "sigma": 6.0, "alpha_affine": 3.5999999999999996, "interpolation": 1, "border_mode": 4, "value": null, "mask_value": null, "approximate": false}, {"__class_fullname__": "albumentations.augmentations.transforms.GridDistortion", "always_apply": false, "p": 0.5, "num_steps": 5, "distort_limit": [-0.3, 0.3], "interpolation": 1, "border_mode": 4, "value": null, "mask_value": null}, {"__class_fullname__": "albumentations.augmentations.transforms.OpticalDistortion", "always_apply": false, "p": 0.5, "distort_limit": [-2, 2], "shift_limit": [-0.5, 0.5], "interpolation": 1, "border_mode": 4, "value": null, "mask_value": null}]}, {"__class_fullname__": "albumentations.augmentations.transforms.ShiftScaleRotate", "always_apply": false, "p": 0.5, "shift_limit": [-0.0625, 0.0625], "scale_limit": [-0.09999999999999998, 0.10000000000000009], "rotate_limit": [-45, 45], "interpolation": 1, "border_mode": 4, "value": null, "mask_value": null}, {"__class_fullname__": "albumentations.augmentations.transforms.Resize", "always_apply": true, "p": 1, "height": 1024, "width": 1024, "interpolation": 1}], "bbox_params": {}, "keypoint_params": {}, "additional_targets": {}}}

以下是GetDataset的类定义。训练时,每个训练迭代,都会调用一次这个类的__getitem__。这里图像变换的结果会直接送入模型,所以这里面把变换后的图像保存下来以便观察。

  1. from PIL import Image
  2. class GetDataset(Dataset):
  3. def __init__(self, data_folder,sub_dir,mode, transform,
  4. image_names=None):
  5. self.transform = transform
  6. self.mode = mode
  7. self.data_folder = data_folder
  8. self.mask_path = os.path.join(data_folder,sub_dir +'_mask')
  9. self.filename_list = image_names
  10. self.set_mode(mode)
  11. self.to_tensor = ToTensor()
  12. self.img_list = []
  13. self.sub_dir = sub_dir
  14. def set_mode(self, mode):
  15. self.mode = mode
  16. if self.mode == 'train':
  17. self.num_data = len(self.filename_list)
  18. elif self.mode == 'val':
  19. self.num_data = len(self.filename_list)
  20. elif self.mode == 'predict':
  21. self.filename_list = sorted(self.filename_list)
  22. self.num_data = len(self.filename_list)
  23. def __getitem__(self,index):
  24. image_path = os.path.join(self.data_folder, os.path.join(self.sub_dir,self.filename_list[index]))
  25. label_path = os.path.join(self.data_folder, os.path.join(self.sub_dir+'_mask',self.filename_list[index].split('.png')[0] + '_mask.png'))
  26. if self.mode == 'predict':
  27. image = cv2.imread(image_path)
  28. image = Image.fromarray(image)
  29. if self.transform:
  30. sample = {"img": image}
  31. sample = self.transform(**sample)
  32. image_id = self.filename_list[index].replace('.png', '')
  33. if image==None:
  34. print("image为None:{}".format(image))
  35. return image_id, sample
  36. elif self.mode == 'train' or self.mode == 'val':
  37. image = cv2.imread(image_path)
  38. label = cv2.imread(label_path,0)
  39. if label is None:
  40. print("image_path:",image_path)
  41. print("label_path:",label_path)
  42. print("index:{} label is None".format(index))
  43. label = np.zeros(shape = (image.shape[0],image.shape[1]))
  44. if self.transform:
  45. sample = {"image": image, "mask": label}
  46. sample = self.transform(**sample)
  47. # 测试变换 -start
  48. def save_img(data,name):
  49. import time
  50. if name=='data':
  51. test_img = cv2.cvtColor(data,cv2.COLOR_BGR2RGB)
  52. elif name=='label':
  53. test_img = data
  54. print("test_img:{},{}".format(test_img.shape,test_img))
  55. tmp_path = '/home/cbl/project/MyExperiment/segmentation/output/predict/2917282960_06beee649a_b_{}_trans_test000_{}.png'.format(name,str(time.time()))
  56. cv2.imwrite(tmp_path,test_img)
  57. print('已存储:{}'.format(tmp_path))
  58. save_img(sample["image"],name='data')
  59. save_img(sample["mask"],name='label')
  60. # 测试变换 -end
  61. sample = self.to_tensor(**sample)
  62. image, label = sample['image'], sample['mask']
  63. sample = {'img': image, 'label': label, 'img_path': image_path}
  64. return sample
  65. def __len__(self):
  66. return self.num_data
  67. def make_loader(dataset_folder,sub_dir,images_filename_list, mode,shuffle=False, transform=None, problem_type='binary', batch_size=1):
  68. return DataLoader(
  69. dataset=GetDataset(mode=mode,data_folder = dataset_folder,sub_dir = sub_dir,image_names = images_filename_list,transform=transform),
  70. shuffle=shuffle,
  71. num_workers=0,
  72. batch_size=batch_size
  73. )

以下是每个epoch输出的图片,我们发现每次调用都会产生不同的图像变换:

epoch1

epoch2

epoch3

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小惠珠哦/article/detail/832879
推荐阅读
相关标签
  

闽ICP备14008679号