赞
踩
通过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__。这里图像变换的结果会直接送入模型,所以这里面把变换后的图像保存下来以便观察。
- from PIL import Image
- class GetDataset(Dataset):
- def __init__(self, data_folder,sub_dir,mode, transform,
- image_names=None):
-
- self.transform = transform
- self.mode = mode
- self.data_folder = data_folder
- self.mask_path = os.path.join(data_folder,sub_dir +'_mask')
- self.filename_list = image_names
- self.set_mode(mode)
- self.to_tensor = ToTensor()
- self.img_list = []
- self.sub_dir = sub_dir
- def set_mode(self, mode):
- self.mode = mode
-
- if self.mode == 'train':
- self.num_data = len(self.filename_list)
-
- elif self.mode == 'val':
- self.num_data = len(self.filename_list)
-
- elif self.mode == 'predict':
- self.filename_list = sorted(self.filename_list)
- self.num_data = len(self.filename_list)
-
-
- def __getitem__(self,index):
- image_path = os.path.join(self.data_folder, os.path.join(self.sub_dir,self.filename_list[index]))
- label_path = os.path.join(self.data_folder, os.path.join(self.sub_dir+'_mask',self.filename_list[index].split('.png')[0] + '_mask.png'))
- if self.mode == 'predict':
- image = cv2.imread(image_path)
- image = Image.fromarray(image)
-
- if self.transform:
- sample = {"img": image}
- sample = self.transform(**sample)
- image_id = self.filename_list[index].replace('.png', '')
-
- if image==None:
- print("image为None:{}".format(image))
-
- return image_id, sample
-
- elif self.mode == 'train' or self.mode == 'val':
- image = cv2.imread(image_path)
- label = cv2.imread(label_path,0)
-
- if label is None:
- print("image_path:",image_path)
- print("label_path:",label_path)
- print("index:{} label is None".format(index))
-
- label = np.zeros(shape = (image.shape[0],image.shape[1]))
-
- if self.transform:
- sample = {"image": image, "mask": label}
- sample = self.transform(**sample)
-
- # 测试变换 -start
- def save_img(data,name):
- import time
- if name=='data':
- test_img = cv2.cvtColor(data,cv2.COLOR_BGR2RGB)
-
- elif name=='label':
- test_img = data
- print("test_img:{},{}".format(test_img.shape,test_img))
- tmp_path = '/home/cbl/project/MyExperiment/segmentation/output/predict/2917282960_06beee649a_b_{}_trans_test000_{}.png'.format(name,str(time.time()))
- cv2.imwrite(tmp_path,test_img)
-
- print('已存储:{}'.format(tmp_path))
- save_img(sample["image"],name='data')
- save_img(sample["mask"],name='label')
- # 测试变换 -end
-
-
- sample = self.to_tensor(**sample)
- image, label = sample['image'], sample['mask']
-
- sample = {'img': image, 'label': label, 'img_path': image_path}
- return sample
-
-
-
- def __len__(self):
- return self.num_data
-
-
-
- def make_loader(dataset_folder,sub_dir,images_filename_list, mode,shuffle=False, transform=None, problem_type='binary', batch_size=1):
- return DataLoader(
- dataset=GetDataset(mode=mode,data_folder = dataset_folder,sub_dir = sub_dir,image_names = images_filename_list,transform=transform),
- shuffle=shuffle,
- num_workers=0,
- batch_size=batch_size
- )
![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)
以下是每个epoch输出的图片,我们发现每次调用都会产生不同的图像变换:
epoch1
epoch2
epoch3
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。