def _get_dynamic_augmentations(self, leave):
        augmentations = []
        downscale = random.choice([True, False])
        if self._scale:
            h, w, c = leave.shape
            scale_max = self._max_width/w - 1
            scale_min = -(1 - self._min_width/w)
            if downscale:
                augmentations.append(albu.RandomScale(scale_limit=[scale_min, 0.0], p=1))
            else:
                augmentations.append(albu.RandomScale(scale_limit=[0.0, scale_max], p=1))
        else:
            augmentations.append(None)

        rand_color = randomcolor.RandomColor()
        color = rand_color.generate(hue="green", count=1)
        if self._dropout_aug:
            augmentations.append(self._get_dropout_aug(leave, color))
        else:
            augmentations.append(None)

        blur_aug = self._blur_aug()
        if blur_aug:
            augmentations.append(blur_aug)
        else:
            if self._sharpen:
                augmentations.append(albu.IAASharpen(p=0.5))
            else:
                augmentations.append(None)
        return augmentations
Exemple #2
0
 def __init__(self, prob):
     self.transform = A.Compose(
         [A.RandomScale(p=prob)],
         bbox_params=A.BboxParams(format='pascal_voc',
                                  label_fields=['category_ids'],
                                  min_visibility=0.3),
     )
Exemple #3
0
def common_aug(mode, params, mean, p=1.):
    '''
    :param mode: 'more', 'inference', 'inference+flip', 'basic' ,
    '''
    augs_list = []
    assert mode in {
        'more',
        'inference',
        'inference+flip',
        'basic',
    }
    assert max(params.augmented_image_size,
               params.padded_image_size) >= params.nn_image_size
    augs_list += [
        albumentations.Resize(params.augmented_image_size,
                              params.augmented_image_size),
    ]
    if params.padded_image_size:
        augs_list += [
            albumentations.PadIfNeeded(min_height=params.padded_image_size,
                                       min_width=params.padded_image_size,
                                       border_mode=cv2.BORDER_REFLECT_101),
        ]
    if mode != 'inference':
        if mode == 'inference+flip':
            augs_list += [
                albumentations.HorizontalFlip(p=1.),
            ]
        else:
            augs_list += [
                albumentations.HorizontalFlip(),
            ]
    if mode == 'more':
        augs_list += [
            albumentations.RandomScale(0.1),
        ]
    if mode in ['inference', 'inference+flip']:
        augs_list += [
            albumentations.CenterCrop(params.nn_image_size,
                                      params.nn_image_size),
        ]
    else:
        augs_list += [
            albumentations.RandomCrop(params.nn_image_size,
                                      params.nn_image_size),
        ]
    augs_list += [
        albumentations.ToFloat(),
        albumentations.Normalize(mean=mean[0],
                                 std=mean[1] * params.norm_sigma_k,
                                 max_pixel_value=1.0),
    ]
    if mode == 'more':
        augs_list += [
            albumentations.Blur(),
            # albumentations.Rotate(limit=5),
            albumentations.RandomBrightness(),
            albumentations.RandomContrast(),
        ]
    return albumentations.Compose(augs_list, p=p)
Exemple #4
0
    def __init__(self, path, _, autoaugment):
        self.imgs_pre, self.lbls_pre = load_data(path, "pre")
        self.imgs_post, self.lbls_post = load_data(path, "post")
        assert len(self.imgs_pre) == len(self.imgs_post)
        assert len(self.imgs_post) == len(self.lbls_post)
        data_frame = pd.read_csv("/workspace/xview2/utils/index.csv")
        self.idx = []
        self.idx.extend(
            data_frame[data_frame["1"] == 1]["idx"].values.tolist())
        self.idx.extend(
            data_frame[data_frame["2"] == 1]["idx"].values.tolist())
        self.idx.extend(
            data_frame[data_frame["3"] == 1]["idx"].values.tolist())
        self.idx.extend(
            data_frame[data_frame["4"] == 1]["idx"].values.tolist())
        self.idx = sorted(list(set(self.idx)))

        self.crop = A.CropNonEmptyMaskIfExists(p=1, width=512, height=512)
        self.zoom = A.RandomScale(p=0.2,
                                  scale_limit=(0, 0.3),
                                  interpolation=cv2.INTER_CUBIC)
        self.hflip = A.HorizontalFlip(p=0.33)
        self.vflip = A.VerticalFlip(p=0.33)
        self.noise = A.GaussNoise(p=0.1)
        self.brctr = A.RandomBrightnessContrast(p=0.2)
        self.normalize = A.Normalize()

        self.use_autoaugment = autoaugment
        if self.use_autoaugment:
            self.autoaugment = ImageNetPolicy()
    def __init__(self, data_dir, train=True, **kwargs):

        if train:
            transform_shape = A.Compose([
                A.ElasticTransform(alpha=2, sigma=5, alpha_affine=5),
                A.RandomScale((-.15, .1)),
                A.PadIfNeeded(160, 160, value=0, border_mode=1),
                A.CenterCrop(160, 160),
                A.HorizontalFlip(),
                A.Rotate(limit=5),
            ])

            transform_color = A.Compose([
                A.RandomBrightnessContrast(brightness_limit=.15,
                                           contrast_limit=.15),
                A.GaussianBlur(blur_limit=7),
                A.GaussNoise(var_limit=.001, )
            ])
        else:
            transform_shape = transform_color = None

        super(brain_dataset, self).__init__(data_dir,
                                            sample=True,
                                            transform_shape=transform_shape,
                                            transform_color=transform_color,
                                            **kwargs)
def get_training_augmentation(augmentation_key="aug1"):
    transform_dict = {
        "resunet1": [
            albu.HorizontalFlip(p=0.5),
        ],
        "resunet2": [
            albu.HorizontalFlip(p=0.5),
            albu.Rotate(limit=30,
                        interpolation=1,
                        border_mode=4,
                        value=None,
                        mask_value=None,
                        always_apply=False,
                        p=1),
        ],
        "resnet": [
            albu.HorizontalFlip(p=0.5),
            albu.Rotate(limit=30,
                        interpolation=1,
                        border_mode=4,
                        value=None,
                        mask_value=None,
                        always_apply=False,
                        p=1),
            albu.Compose([
                albu.RandomScale(scale_limit=0.1, p=1),
                CenterCrop(height=256, width=256, p=1),
            ],
                         p=0.66)
        ]
    }
    train_transform = transform_dict[augmentation_key]
    print(f"Train Transforms: {train_transform}")
    return albu.Compose(train_transform)
Exemple #7
0
    def __init__(self, outputs=6):
        super().__init__()
        self.net = models.resnet34(True)
        self.linear = Sequential(ReLU(), Dropout(), Linear(1000, outputs))

        df = pd.read_csv(
            "/home/dipet/kaggle/prostate/input/prostate-cancer-grade-assessment/train.csv"
        )
        self.train_df, self.valid_df = train_test_split(df, test_size=0.2)
        self.data_dir = "/datasets/panda/train_128_100"

        self.train_transforms = A.Compose([
            A.InvertImg(p=1),
            A.RandomGridShuffle(grid=(10, 10)),
            A.RandomScale(0.1),
            A.PadIfNeeded(1280, 1280),
            A.RandomSizedCrop([1000, 1280], 1280, 1280),
            A.Flip(),
            A.Rotate(90),
            A.RandomBrightnessContrast(0.02, 0.02),
            A.HueSaturationValue(0, 10, 10),
            A.Normalize(mean, std, 1),
        ])
        self.valid_transforms = A.Compose([
            A.InvertImg(p=1),
            A.Normalize(mean, std, 1),
        ])
    def __init__(self, base_dir='/newDisk/users/duanshiyu/cityscapes/', split='train',
                 affine_augmenter=None, image_augmenter=None, target_size=(1024, 2048),
                 net_type='unet', ignore_index=255, debug=False):
        self.debug = debug
        self.base_dir = Path(base_dir)
        assert net_type in ['unet', 'deeplab']
        self.net_type = net_type
        self.ignore_index = ignore_index
        self.split = 'val' if split == 'valid' else split

        self.img_paths = sorted(self.base_dir.glob(f'leftImg8bit_sequence/{self.split}/*/*leftImg8bit.png'))
        # self.lbl_paths = sorted(self.base_dir.glob(f'gtFine/{self.split}/*/*gtFine_labelIds.png'))
        # assert len(self.img_paths) == len(self.lbl_paths)

        # Resize
        if isinstance(target_size, str):
            target_size = eval(target_size)
        if self.split == 'train':
            if self.net_type == 'deeplab':
                target_size = (target_size[0] + 1, target_size[1] + 1)
            self.resizer = albu.Compose([albu.RandomScale(scale_limit=(-0.5, 0.5), p=1.0),
                                         PadIfNeededRightBottom(min_height=target_size[0], min_width=target_size[1],
                                                                value=0, ignore_index=self.ignore_index, p=1.0),
                                         albu.RandomCrop(height=target_size[0], width=target_size[1], p=1.0)])
        else:
            self.resizer = None

        # Augment
        if self.split == 'train':
            self.affine_augmenter = affine_augmenter
            self.image_augmenter = image_augmenter
        else:
            self.affine_augmenter = None
            self.image_augmenter = None
Exemple #9
0
def transformation(image):
    transform = A.Compose([
        A.HorizontalFlip(p=0.5),
        A.RandomScale(p=0.5, interpolation=1, scale_limit=(-0.1, 0.1)),
        A.ShiftScaleRotate(p=0.5, rotate_limit=(-2, 2)),
        A.Resize(always_apply=False, height=128, width=64)
    ])
    augmented_img = transform(image=image)["image"]
    return augmented_img
Exemple #10
0
def albument():
    bbox_params = A.BboxParams(format='coco',
                               min_area=600,
                               min_visibility=0.4,
                               label_fields=['class_categories'])

    # describe the transformations
    transform_lst = [
        # resize 10% smaller
        A.Compose([A.RandomScale(scale_limit=[-0.10, -0.10], p=1)],
                  bbox_params=bbox_params),
        # resize 15% smaller
        A.Compose([A.RandomScale(scale_limit=[-0.15, -0.15], p=1)],
                  bbox_params=bbox_params),
        # resize 20% smaller
        A.Compose([A.RandomScale(scale_limit=[-0.20, -0.20], p=1)],
                  bbox_params=bbox_params)
    ]

    return transform_lst
Exemple #11
0
def base_line_transform():
    result = [
        albu.HorizontalFlip(),
        albu.RandomGamma(),
        albu.RandomBrightnessContrast(),
        albu.OneOf([
            albu.ToGray(),
            albu.CLAHE()]),
        albu.RandomScale(),
    ]
    return result
Exemple #12
0
    def ensure_min_size(self, image):
        ''' Ensures each dimension of the image is >= self.min_img_size '''
        dims = image.shape[0:2]

        if dims[0] < self.min_img_size or dims[1] < self.min_img_size:
            # image is too small
            ratio = self.min_img_size / min(dims)
            resizer = A.RandomScale([ratio, ratio], always_apply=True, p=1.0)
            image = resizer(image=image)['image']

        return image
Exemple #13
0
    def _build_augmentation_ops(self):
        r"""Builds sequence of augmentation ops.

        Returns:
            (list of alb.ops): List of augmentation ops.
        """
        augs = []
        for key, value in self.aug_list.items():
            if key == 'resize_smallest_side':
                self.resize_smallest_side = value
            elif key == 'resize_h_w':
                h, w = value.split(',')
                h, w = int(h), int(w)
                self.resize_h, self.resize_w = h, w
            elif key == 'random_resize_h_w_aspect':
                aspect_start, aspect_end = value.find('('), value.find(')')
                aspect = value[aspect_start+1:aspect_end]
                aspect_min, aspect_max = aspect.split(',')
                h, w = value[:aspect_start].split(',')[:2]
                h, w = int(h), int(w)
                aspect_min, aspect_max = float(aspect_min), float(aspect_max)
                augs.append(alb.RandomResizedCrop(
                    h, w, scale=(1, 1),
                    ratio=(aspect_min, aspect_max), always_apply=True, p=1))
                self.resize_h, self.resize_w = h, w
            elif key == 'rotate':
                augs.append(alb.Rotate(
                    limit=value, always_apply=True, p=1))
            elif key == 'random_rotate_90':
                augs.append(alb.RandomRotate90(always_apply=False, p=0.5))
            elif key == 'random_scale_limit':
                augs.append(alb.RandomScale(scale_limit=(0, value), p=1))
            elif key == 'random_crop_h_w':
                h, w = value.split(',')
                h, w = int(h), int(w)
                self.crop_h, self.crop_w = h, w
                augs.append(alb.RandomCrop(h, w, always_apply=True, p=1))
            elif key == 'center_crop_h_w':
                h, w = value.split(',')
                h, w = int(h), int(w)
                self.crop_h, self.crop_w = h, w
                augs.append(alb.CenterCrop(h, w, always_apply=True, p=1))
            elif key == 'horizontal_flip':
                # This is handled separately as we need to keep track if this
                # was applied in order to correctly modify keypoint data.
                if value:
                    augs.append(alb.HorizontalFlip(always_apply=False, p=0.5))
            elif key == 'max_time_step':
                self.max_time_step = value
                assert self.max_time_step >= 1, \
                    'max_time_step has to be at least 1'
            else:
                raise ValueError('Unknown augmentation %s' % (key))
        return augs
    def __init__(
            self,
            base_dir='../data/sherbrooke',
            split='train',
            affine_augmenter=None,
            image_augmenter=None,
            target_size=(1024, 2048),  #original resolution
            #affine_augmenter=None, image_augmenter=None, target_size=(921, 1843), #if downscaled to 90%
            #affine_augmenter=None, image_augmenter=None, target_size=(384, 768), #if downscaled to 37,5%
            #affine_augmenter=None, image_augmenter=None, target_size=(128, 256), #if downscaled to 12,5%
        net_type='unet',
            ignore_index=255,
            debug=False):
        self.debug = debug
        self.base_dir = Path(base_dir)
        assert net_type in ['unet', 'deeplab']
        self.net_type = net_type
        self.ignore_index = ignore_index
        self.split = 'val' if split == 'valid' else split

        self.img_paths = sorted(
            self.base_dir.glob(f'leftImg8bit/{self.split}/*/*leftImg8bit.png'))
        self.lbl_paths = sorted(
            self.base_dir.glob(f'gtFine/{self.split}/*/*gtFine_labelIds.png'))
        assert len(self.img_paths) == len(self.lbl_paths)

        # Resize
        if isinstance(target_size, str):
            target_size = eval(target_size)
        if self.split == 'train':
            if self.net_type == 'deeplab':
                target_size = (target_size[0] + 1, target_size[1] + 1)
            self.resizer = albu.Compose([
                albu.RandomScale(scale_limit=(-0.7, 1), p=1.0),
                PadIfNeededRightBottom(min_height=target_size[0],
                                       min_width=target_size[1],
                                       value=0,
                                       ignore_index=self.ignore_index,
                                       p=1.0),
                albu.RandomCrop(height=target_size[0],
                                width=target_size[1],
                                p=1.0)
            ])
        else:
            self.resizer = None

        # Augment
        if self.split == 'train':
            self.affine_augmenter = affine_augmenter
            self.image_augmenter = image_augmenter
        else:
            self.affine_augmenter = None
            self.image_augmenter = None
Exemple #15
0
 def __init__(self, base_size, crop_size, fill=0):
     self.base_size = base_size
     self.crop_size = crop_size
     self.base_height = base_size[0]
     self.fill = fill
     self.aug = alb.Compose([
         alb.RandomScale(),
         alb.PadIfNeeded(min_height=base_size[0],
                         min_width=base_size[1],
                         border_mode=cv2.BORDER_REFLECT101),
         alb.RandomCrop(height=base_size[0], width=base_size[1])
     ])
    def setup_pipeline(self, dict_transform):

        tranform_list = []
        if 'shadow' in dict_transform:
            tranform_list.append(
                A.RandomShadow(shadow_roi=(0, 0.5, 1, 1),
                               num_shadows_upper=1,
                               p=0.2))
        if 'scale' in dict_transform:
            tranform_list.append(
                A.RandomScale(scale_limit=float(dict_transform['scale'])))
        if 'rotate' in dict_transform:
            tranform_list.append(
                A.Rotate(limit=float(dict_transform['rotate']), p=0.8))
        if 'shift' in dict_transform:
            tranform_list.append(
                A.ShiftScaleRotate(shift_limit=float(dict_transform['shift']),
                                   scale_limit=0.0,
                                   rotate_limit=0,
                                   interpolation=1,
                                   border_mode=4,
                                   p=0.8))
        if 'brightness' in dict_transform:
            tranform_list.append(
                A.RandomBrightness(limit=float(dict_transform['brightness']),
                                   p=0.8))
        if 'contrast' in dict_transform:
            tranform_list.append(
                A.RandomContrast(limit=float(dict_transform['contrast']),
                                 p=0.8))
        if 'motion_blur' in dict_transform:
            tranform_list.append(A.MotionBlur(p=0.5, blur_limit=7))
        if 'fog' in dict_transform:
            tranform_list.append(
                A.RandomFog(fog_coef_lower=0.0,
                            fog_coef_upper=float(dict_transform['fog']),
                            alpha_coef=0.05,
                            p=0.7))
        if 'rain' in dict_transform:
            tranform_list.append(
                A.RandomRain(brightness_coefficient=0.95,
                             drop_width=1,
                             blur_value=1,
                             p=0.7))
        if 'occlusion' in dict_transform:
            tranform_list.append(
                A.CoarseDropout(max_holes=5, max_height=8, max_width=8, p=0.5))
        self.transform = A.Compose(tranform_list)
Exemple #17
0
    def __init__(self, base_dir=None, split='train', affine_augmenter=None, image_augmenter=None, 
            target_size=224, filename=None, use_bined=False, n_class=4, debug=False):
        self.base_dir = base_dir
        self.base_dir = Path(base_dir)
        self.split = split
        self.use_bined = use_bined
        self.n_class = n_class
        self.debug = debug

        self.img_paths = []
        self.bbox = []
        self.labels = []
        self.euler_binned = []

        with open(self.base_dir / filename) as f:
            for i, line in enumerate(f.readlines()):
                ls = line.strip()

                mat_path = self.base_dir / ls.replace('.jpg', '.mat')
                bbox, pose = get_pt_ypr_from_mat(mat_path, pt3d=True)

                if True and (abs(pose[0])>99 or abs(pose[1])>99 or abs(pose[2])>99):
                    continue

                if use_bined:
                    yaw_pitch_bins = np.array([-60, -40, -20, 20, 40, 60])
                    roll_bins = np.array(range(-81, 82, 9))
                    self.euler_binned.append([np.digitize(pose[0], yaw_pitch_bins),np.digitize(pose[1], yaw_pitch_bins),np.digitize(pose[2], roll_bins)])

                self.labels.append(np.array(pose))
                self.bbox.append(bbox)
                self.img_paths.append(ls)

        self.labels_sort_idx = np.argsort(-np.mean(np.abs(self.labels), axis=1))
        

        if 'train' in self.split:
            self.resizer = albu.Compose([albu.SmallestMaxSize(target_size, p=1.),
                                        albu.RandomScale(scale_limit=(-0.2, 0.2), p=0.1),
                                        albu.PadIfNeeded(min_height=target_size, min_width=target_size, value=0, p=1),
                                        albu.RandomCrop(target_size, target_size, p=1.)])
        else:
            # self.resizer = albu.Compose([albu.Resize(target_size[0], target_size[1], p=1.)])
            self.resizer = albu.Compose([albu.SmallestMaxSize(target_size, p=1.),
                                        albu.CenterCrop(target_size, target_size, p=1.)])

        self.affine_augmenter = affine_augmenter
        self.image_augmenter = image_augmenter
    def __init__(self, data_path: str, phase: str, augment: bool,
                 img_size: Tuple[int, int], dataset_folder: str,
                 weights_rgb_path: str) -> None:

        self.data_path = data_path
        self.dataset_folder = dataset_folder
        self.phase = phase
        self.augment = augment
        self.img_size = img_size
        self.weights_rgb_path = weights_rgb_path

        if self.dataset_folder == 'V2':
            self.items = [
                filename.split('.')[0] for filename in os.listdir(
                    f'{self.data_path}/{self.dataset_folder}/{self.phase}_RGB')
            ]

        elif self.dataset_folder == 'V3':
            self.items, self.labels = self._get_files()

        self.kmeans = self._define_kmeans_mask()

        if self.augment:
            self.Resize = A.RandomScale()
            self.Crop = A.RandomCrop(width=self.img_size, height=self.img_size)
            # self.Rotate = A.Rotate(limit=3, p=0.5)
            self.HorizontalFlip = A.HorizontalFlip(p=1)
            self.RGBShift = A.RGBShift(r_shift_limit=15,
                                       g_shift_limit=15,
                                       b_shift_limit=15,
                                       p=0.5)

            self.RandomBrightness = A.RandomBrightness(limit=0.2)

            self.transform = A.Compose([
                self.Resize,
                self.Crop,
                #  self.Rotate,
                self.HorizontalFlip,
                self.RGBShift,
                #  self.RandomBrightness
            ])

        else:
            self.Crop = A.RandomCrop(width=self.img_size, height=self.img_size)
            self.transform = A.Compose([self.Crop])

        self.to_tensor = ToTensor()
Exemple #19
0
    def __call__(self, sample):

        # img, mask = sample.image, sample.annotation
        # w, h = img.size
        # scale = random.choice(self.scales)
        # w, h = int(w * scale), int(h * scale)

        # sample.image = img
        # sample.annotation = mask

        img, annot = sample.image, sample.annotation

        aug = A.RandomScale(scale_limit=self.scales)

        bbox_aug = []
        if annot is not None:
            augmented = aug(image=img, bboxes=annot)
            bbox_aug = augmented['bboxes']
        else:
            augmented = aug(image=img)
        image_aug = augmented['image']

        # the shape has to be at least (0,5)
        if len(bbox_aug) == 0:
            bbox_aug = np.zeros((0, 5))

        masks = []
        if sample.masks_and_category is not None:
            for index in sample.masks_and_category:
                masks.append(index[0])

        if masks != []:
            w, h, _ = image_aug.shape

            mask_aug = []
            if masks is not None:
                for mask in masks:
                    mask = cv2.resize(mask, (h, w))
                    mask_aug.append(mask)

                for i, index in enumerate(sample.masks_and_category):
                    index[0] = mask_aug[i]

        sample.image = image_aug
        sample.annotation = bbox_aug
Exemple #20
0
import random
from os import path
import albumentations as alb
from albumentations.pytorch import ToTensorV2
from skimage.color import gray2rgb
import cv2

import numpy as np
from torch.utils.data import Dataset
import pickle

from conet.config import get_cfg

train_aug = alb.Compose([
    # alb.RandomSizedCrop(min_max_height=(300, 500)),
    alb.RandomScale(),
    alb.HorizontalFlip(),
    alb.VerticalFlip(),
    alb.RandomBrightness(limit=0.01),
    alb.Rotate(limit=30),
    alb.PadIfNeeded(520, border_mode=cv2.BORDER_REFLECT101),
    alb.RandomCrop(512, 512),
    alb.Normalize(),
    # alb.pytorch.ToTensor(),
    ToTensorV2()
])

val_aug = alb.Compose([
    # alb.PadIfNeeded(512, border_mode=cv2.BORDER_REFLECT101),
    alb.Normalize(),
    alb.Resize(512, 512),
val_interval = 1
accumulation_steps = 4

val_img_size = 513
train_img_size = 480

# ##############################
# Setup Dataflow
# ##############################

mean = (0.485, 0.456, 0.406)
std = (0.229, 0.224, 0.225)

train_transforms = A.Compose([
    A.RandomScale(scale_limit=(0.0, 1.5),
                  interpolation=cv2.INTER_LINEAR,
                  p=1.0),
    A.PadIfNeeded(val_img_size, val_img_size, border_mode=cv2.BORDER_CONSTANT),
    A.RandomCrop(train_img_size, train_img_size),
    A.HorizontalFlip(),
    A.Blur(blur_limit=3),
    A.Normalize(mean=mean, std=std),
    ignore_mask_boundaries,
    ToTensor(),
])

val_transforms = A.Compose([
    A.PadIfNeeded(val_img_size, val_img_size, border_mode=cv2.BORDER_CONSTANT),
    A.Normalize(mean=mean, std=std),
    ignore_mask_boundaries,
    ToTensor(),
Exemple #22
0
    'verbose': 1
}
"""
Augmentation Parameters
"""

# These are the augmentations from the GoogLeNet paper, which come from: https://arxiv.org/pdf/1312.5402.pdf
# We do not know how the perturbation magnitude in paper maps to albumentations so just used library defaults

# Furthermore, the GoogLeNet paper recommends "sampling of various sized patches of the image whose size is distributed
# evenly between 8% and 100% of the image area with aspect ratio constrained to the interval [3/4, 4/3]."
# We upscale the image by 3.5 so that the 224x224 sampled patch has 8% area of original image. We scale
# uniformly though.
aug_list = AugmentationList(albumentations.RandomBrightnessContrast(p=1),
                            albumentations.RGBShift(p=1),
                            albumentations.RandomScale(scale_limit=(1, 3.5),
                                                       p=1),
                            albumentations.HorizontalFlip(),
                            shuffle=True)

shift_scale = 0.1
"""
Loading Params
"""

# If model_file is not None and checkpoint_dir is not None then loading happens, else not
loading_params = {
    'checkpoint_dir': None,
    'model_file': None,
    'epoch_start': None
}
Exemple #23
0
    def __init__(self,
                 base_dir='../data/sherbrooke',
                 split='train',
                 affine_augmenter=None,
                 image_augmenter=None,
                 target_size=(544, 544),
                 net_type='deeplab',
                 ignore_index=255,
                 defects=False,
                 debug=False):
        if defects is False:
            self.n_classes = 2
            self.void_classes = [
                1, 2, 3, 4, 5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
                20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, -1
            ]
            self.valid_classes = [
                0, 8
            ]  # background and sidewalks only. 0 will become background...
        else:
            base_dir = '../data/bbox_mask'
            self.n_classes = 2
            self.void_classes = [0, 4]  #why 4?
            self.valid_classes = [8, 35]  # background and sidewalks only.
        self.class_map = dict(zip(self.valid_classes, range(self.n_classes)))
        self.debug = debug
        self.defects = defects
        self.base_dir = Path(base_dir)
        assert net_type in ['unet', 'deeplab']
        self.net_type = net_type
        self.ignore_index = ignore_index
        self.split = 'val' if split == 'valid' else split

        self.img_paths = sorted(
            self.base_dir.glob(f'leftImg8bit/{self.split}/*/*leftImg8bit.*'))
        self.lbl_paths = sorted(
            self.base_dir.glob(f'gtFine/{self.split}/*/*gtFine*.png'))

        #Quality control
        if len(self.img_paths) != len(self.lbl_paths):
            raise AssertionError(
                f'Length of images (count: {len(self.img_paths)}) '
                f'and labels (count: {len(self.lbl_paths)}) don\'t match')
        if len(self.img_paths) == 0:
            raise AssertionError(
                f'No images found. Check current working directory.')
        count = 0

        for img_path, lbl_path in zip(self.img_paths, self.lbl_paths):
            count += 1
            _, img_path = os.path.split(img_path)
            img_name, img_ext = os.path.splitext(
                img_path)  # separate name and extension
            _, lbl_path = os.path.split(lbl_path)
            lbl_name, lbl_ext = os.path.splitext(
                lbl_path)  # separate name and extension
            if img_name.split('_')[0] != lbl_name.split('_')[0]:
                raise AssertionError(
                    f'Image {img_name} and label {lbl_name} don\'t match')
        print(
            f'Assertion success: image and label filenames in {self.split} split of dataset match.'
        )

        # Resize
        if isinstance(target_size, str):
            target_size = eval(target_size)
        if self.split == 'train':
            if self.net_type == 'deeplab':
                target_size = (target_size[0] + 1, target_size[1] + 1)
            # Resize (Scale & Pad & Crop)
            #self.resizer = None
            self.resizer = albu.Compose([
                albu.RandomScale(scale_limit=(-0.5, 0.5), p=0.5),
                #next transform is custom. see src.utils.custom_aug
                PadIfNeededRightBottom(min_height=target_size[0],
                                       min_width=target_size[1],
                                       value=0,
                                       ignore_index=self.ignore_index,
                                       p=1.0),
                albu.RandomCrop(height=target_size[0],
                                width=target_size[1],
                                p=1.0)
            ])
            #self.resizer_info = (f'albu.RandomScale(scale_limit={self.resizer.transforms[0].scale_limit}, p=0.5),'
            #                     f'albu.RandomCrop(height={target_size[0]}, width={target_size[1]}, p=1.0)')
        else:
            self.resizer = None

        # Augment
        if self.split == 'train':
            self.affine_augmenter = affine_augmenter
            self.image_augmenter = image_augmenter
        else:
            self.affine_augmenter = None
            self.image_augmenter = None
Exemple #24
0
def run(fold, args):
    if args.sz:
        print(f"Images will be resized to {args.sz}")
        args.sz = int(args.sz)

    # get training and valid data
    df = pd.read_csv(args.training_folds_csv)
    if args.loss == 'crossentropy' and not args.isic2019:
        diag_to_ix = {
            v: i
            for i, v in enumerate(sorted(list(set(df.diagnosis))))
        }
        ix_to_diag = {v: i for i, v in diag_to_ix.items()}

    if args.external_csv_path:
        df_external = pd.read_csv(args.external_csv_path)
    df_train = df.query(f"kfold != {fold}").reset_index(drop=True)
    df_valid = df.query(f"kfold == {fold}").reset_index(drop=True)
    print(
        f"Running for K-Fold {fold}; train_df: {df_train.shape}, valid_df: {df_valid.shape}"
    )

    # calculate weights for NN loss
    weights = len(df) / df.target.value_counts().values
    class_weights = torch.FloatTensor(weights)
    if args.loss == 'weighted_bce':
        print(f"assigning weights {weights} to loss fn.")
    if args.loss == 'focal_loss':
        print("Focal loss will be used for training.")
    if args.loss == 'weighted_cross_entropy':
        print(f"assigning weights {weights} to loss fn.")

    # create model
    if 'efficient_net' in args.model_name:
        model = MODEL_DISPATCHER[args.model_name](
            pretrained=args.pretrained,
            arch_name=args.arch_name,
            ce=(args.loss == 'crossentropy'
                or args.loss == 'weighted_cross_entropy'
                or args.load_pretrained_2019))
    else:
        model = MODEL_DISPATCHER[args.model_name](pretrained=args.pretrained)

    if args.model_path is not None:
        print(
            f"Loading pretrained model and updating final layer from {args.model_path}"
        )
        model.load_state_dict(torch.load(args.model_path))
        nftrs = model.base_model._fc.in_features
        model.base_model._fc = nn.Linear(nftrs, 1)

    meta_array = None
    if args.use_metadata:
        # create meta array
        sex_dummy_train = pd.get_dummies(df_train['sex'])[['male', 'female']]
        site_dummy_train = pd.get_dummies(
            df_train['anatom_site_general_challenge'])[[
                'head/neck', 'lower extremity', 'oral/genital', 'palms/soles',
                'torso', 'upper extremity'
            ]]
        assert max(df_train.age_approx) < 100
        age_train = df_train.age_approx.fillna(-5) / 100
        meta_array = pd.concat([sex_dummy_train, site_dummy_train, age_train],
                               axis=1).values
        # modify model forward
        if args.freeze_cnn:
            model.load_state_dict(torch.load(args.model_path))

        # update the forward pass
        model = modify_model(model, args)

        # freeze cnn
        if args.freeze_cnn:
            print("\nFreezing CNN layers!\n")
            for param in model.base_model.parameters():
                param.requires_grad = False

        # add external meta to meta array
        if args.external_csv_path:
            sex_dummy_ext = pd.get_dummies(
                df_external['sex'])[['male', 'female']]
            df_external[
                'anatom_site_general'] = df_external.anatom_site_general.replace(
                    {
                        'anterior torso': 'torso',
                        'lateral torso': 'torso',
                        'posterior torso': 'torso'
                    })
            site_dummy_ext = pd.get_dummies(
                df_external['anatom_site_general'])[[
                    'head/neck', 'lower extremity', 'oral/genital',
                    'palms/soles', 'torso', 'upper extremity'
                ]]
            assert max(df_external.age_approx) < 100
            age_ext = df_external.age_approx.fillna(-5) / 100
            meta_array = np.concatenate([
                meta_array,
                pd.concat([sex_dummy_ext, site_dummy_ext, age_ext],
                          axis=1).values
            ])

        assert meta_array.shape[1] == 9

    model = model.to(args.device)

    train_aug = albumentations.Compose([
        albumentations.RandomScale(0.07),
        albumentations.Rotate(50),
        albumentations.RandomBrightnessContrast(0.15, 0.1),
        albumentations.Flip(p=0.5),
        albumentations.IAAAffine(shear=0.1),
        albumentations.RandomCrop(args.sz, args.sz)
        if args.sz else albumentations.NoOp(),
        albumentations.OneOf([
            albumentations.Cutout(random.randint(1, 8), 16, 16),
            albumentations.CoarseDropout(random.randint(1, 8), 16, 16)
        ]),
        albumentations.Normalize(always_apply=True)
    ])

    valid_aug = albumentations.Compose([
        albumentations.CenterCrop(args.sz, args.sz)
        if args.sz else albumentations.NoOp(),
        albumentations.Normalize(always_apply=True),
    ])

    print(f"\nUsing train augmentations: {train_aug}\n")

    # get train and valid images & targets and add external data if required (external data only contains melonama data)
    train_images = df_train.image_name.tolist()
    if args.external_csv_path:
        external_images = df_external.image.tolist()
        if args.exclude_outliers_2019:
            # from EDA notebook
            external_images = np.load(
                f'/home/ubuntu/repos/kaggle/melonama/data/external/clean_external_2019_{args.sz}.npy'
            ).tolist()
        print(
            f"\n\n{len(external_images)} external images will be added to each training fold."
        )
        train_images = train_images + external_images
    if args.use_pseudo_labels:
        test_df = pd.read_csv(
            '/home/ubuntu/repos/kaggle/melonama/data/test.csv')
        test_images = test_df.image_name.tolist()

        if args.pseudo_images_path:
            test_images = list(
                np.load(args.pseudo_images_path, allow_pickle=True))

        print(
            f"\n\n{len(test_images)} test images will be added to each training fold."
        )
        train_images = train_images + test_images

    train_image_paths = [
        os.path.join(args.train_data_dir, image_name + '.jpg')
        for image_name in train_images
    ]
    train_targets = df_train.target if not args.external_csv_path else np.concatenate(
        [df_train.target.values,
         np.ones(len(external_images))])

    if args.use_pseudo_labels:
        train_targets = np.concatenate([
            train_targets,
            np.load(args.pseudo_labels_path, allow_pickle=True)
        ])

    if args.loss == 'crossentropy':
        df_train['diagnosis'] = df_train.diagnosis.map(diag_to_ix)
        train_targets = df_train.diagnosis.values

    assert len(train_image_paths) == len(
        train_targets
    ), "Length of train images {} doesnt match length of targets {}".format(
        len(train_images), len(train_targets))

    # same for valid dataframe
    valid_images = df_valid.image_name.tolist()
    valid_image_paths = [
        os.path.join(args.train_data_dir, image_name + '.jpg')
        for image_name in valid_images
    ]
    valid_targets = df_valid.target
    if args.loss == 'crossentropy':
        df_valid['diagnosis'] = df_valid.diagnosis.map(diag_to_ix)
        valid_targets = df_valid.diagnosis.values

    print(
        f"\n\n Total Train images: {len(train_image_paths)}, Total val: {len(valid_image_paths)}\n\n"
    )
    # create train and valid dataset, dont use color constancy as already preprocessed in directory
    train_dataset = MelonamaDataset(train_image_paths,
                                    train_targets,
                                    train_aug,
                                    cc=args.cc,
                                    meta_array=meta_array)
    valid_dataset = MelonamaDataset(valid_image_paths,
                                    valid_targets,
                                    valid_aug,
                                    cc=args.cc,
                                    meta_array=meta_array)

    # create dataloaders
    train_loader = torch.utils.data.DataLoader(
        train_dataset,
        batch_size=args.train_batch_size,
        shuffle=True,
        num_workers=4)
    valid_loader = torch.utils.data.DataLoader(
        valid_dataset,
        batch_size=args.valid_batch_size,
        shuffle=False,
        num_workers=4)

    # create optimizer and scheduler for training
    optimizer = torch.optim.Adam(model.parameters(), lr=args.learning_rate)
    scheduler = torch.optim.lr_scheduler.MultiStepLR(
        optimizer, milestones=[3, 5, 6, 7, 8, 9, 10, 11, 13, 15], gamma=0.5)

    es = EarlyStopping(patience=3,
                       mode='min' if args.metric == 'valid_loss' else 'max')

    for epoch in range(args.epochs):
        train_loss = train_one_epoch(
            args,
            train_loader,
            model,
            optimizer,
            weights=None
            if not args.loss.startswith('weighted') else class_weights)
        preds, valid_loss = evaluate(args, valid_loader, model)
        predictions = np.vstack(preds).ravel()

        if args.loss == 'crossentropy' or args.loss == 'weighted_cross_entropy':
            accuracy = metrics.accuracy_score(valid_targets, predictions)
        else:
            auc = metrics.roc_auc_score(valid_targets, predictions)

        preds_df = pd.DataFrame({
            'predictions': predictions,
            'targets': valid_targets,
            'valid_image_paths': valid_image_paths
        })
        print(
            f"Epoch: {epoch}, Train loss: {train_loss}, Valid loss: {valid_loss}, Valid Score: {locals()[f'{args.metric}']}"
        )

        scheduler.step()
        for param_group in optimizer.param_groups:
            print(f"Current Learning Rate: {param_group['lr']}")
        es(locals()[f"{args.metric}"],
           model,
           model_path=
           f"/home/ubuntu/repos/kaggle/melonama/models/{syd_now.strftime(r'%d%m%y')}/{args.arch_name}_fold_{fold}_{args.sz}_{locals()[f'{args.metric}']}.bin",
           preds_df=preds_df,
           df_path=
           f"/home/ubuntu/repos/kaggle/melonama/valid_preds/{syd_now.strftime(r'%d%m%y')}/{args.arch_name}_fold_{fold}_{args.sz}_{locals()[f'{args.metric}']}.bin",
           args=args)
        if es.early_stop:
            return preds_df
Exemple #25
0
    def aug_data(self, origin_image, save_path, annotations_bbox,
                 annotations_img):
        '''
        对缺陷做增广,并且更新标注文件
        {
       "0": "背景",
       "1": "边异常",
       "2": "角异常",
       "3": "白色点瑕疵",
       "4": "浅色块瑕疵",
       "5": "深色点块瑕疵",
       "6": "光圈瑕疵"
      }
        origin_image:原始图片的位置
        flaw_image:提取出来的缺陷的位置
        annotations:原图的数据标注
        :return:
        '''
        import copy
        annotations = {
            im_name: [annotations_bbox[im_name], annotations_img[im_name]]
            for im_name in annotations_bbox.keys()
        }
        transform_3456 = A.Compose([  #对第3,4,5,6类缺陷做增广
            A.RandomScale((1.0, 1.2)),
            A.Flip(),
            # A.GridDistortion(distort_limit=0.3,num_steps = 5),
            A.RandomRotate90()
        ])
        transform_angle = A.Compose([  #对第1,2类缺陷做增广
            A.RandomScale(),
            # A.elastic_transform(),
        ])

        image_list = os.listdir(origin_image)
        # flaw_1 = osp.join(flaw_image,'1')
        # flaw_2 = osp.join(flaw_image,'2')
        # flaw_3 = osp.join(flaw_image,'3')
        # flaw_4 = osp.join(flaw_image,'4')
        # flaw_5 = osp.join(flaw_image,'5')
        # flaw_6 = osp.join(flaw_image,'6')
        json_save_path = osp.join(osp.dirname(origin_image),
                                  'auged_normal.json')
        # import pdb
        # pdb.set_trace()
        annotations_new = copy.deepcopy(annotations)
        for img in tqdm(image_list):
            img_path = osp.join(origin_image, img)
            # ann_bbox = annotations_bbox[img]
            anno = annotations[img]
            ann_bbox = anno[0]
            # ann_img = annotations_img[img]
            image = cv2.imread(img_path)
            new_path = osp.join(save_path, img)
            for box in ann_bbox:
                # import pdb
                # pdb.set_trace()
                bbox = box[1]
                bbox = [int(bbox[0]), int(bbox[1]), int(bbox[2]), int(bbox[3])]
                width = int(bbox[2])
                height = int(bbox[3])
                area = width * height
                category = box[0]
                if 0 < area < 1024:
                    for i in range(10):
                        # import pdb
                        # pdb.set_trace()
                        flaw = image[bbox[1]:bbox[1] + height,
                                     bbox[0]:bbox[0] + width]
                        if height <= 0 or width <= 0:
                            import pdb
                            pdb.set_trace()
                        flaw = transform_3456(image=flaw)['image']
                        f_h, f_w, _ = flaw.shape
                        # mask = 255 * np.ones((f_h, f_w, 3), dtype=np.uint8)
                        w, h = self.random_coor(0, 500 - f_w - 1, 0,
                                                500 - f_h - 1, image)
                        # image = cv2.seamlessClone(flaw, image, mask, (w + f_w // 2,h + f_h // 2, ),
                        #                               cv2.MIXED_CLONE)  # 泊松融合

                        image[h:h + f_h, w:w + f_w] = flaw
                        new_bbox = [w, h, f_w, f_h]
                        annotations_new[img][0].append([category, new_bbox])
            cv2.imwrite(new_path, image)

            # new_image = self.aug_3456(img_path,flaw_3,flaw_4,flaw_5,flaw_6,annotations,transform_3456)
            # new_path = osp.join(save_path,img)
            # cv2.imshow('src',new_image)
            # cv2.waitKey()
            # cv2.imwrite(new_path,new_image)
            # self.aug_angle(img_path,flaw_2,annotations,transform_angle)
            # self.aug_edge(img_path,flaw_1,annotations,transform_angle)
        self.convert2coco(annotations_new, json_save_path)
Exemple #26
0
def train(fold):
    training_data_path = "/home/dragoshh1984/repos/kaggle/datasets/melanomia_classification/512x512-dataset-melanoma/512x512-dataset-melanoma"
    model_path = "/home/dragoshh1984/repos/kaggle/melanomia-classification"
    df = pd.read_csv(
        "/home/dragoshh1984/repos/kaggle/datasets/melanomia_classification/new_train.csv"
    )

    # defines
    device = "cuda"
    epochs = 20
    train_bs = 16
    valid_bs = 16

    # for this model
    mean = (0.485, 0.456, 0.406)
    std = (0.229, 0.224, 0.225)

    # data for training
    df_train = df[df.fold != fold].reset_index(drop=True)
    df_valid = df[df.fold == fold].reset_index(drop=True)

    # augmentations
    train_aug = albumentations.Compose([
        albumentations.RandomResizedCrop(224, 224, (0.7, 1.0)),
        albumentations.HorizontalFlip(),
        albumentations.VerticalFlip(),
        albumentations.Cutout(),
        albumentations.RandomBrightness(),
        albumentations.RandomContrast(),
        albumentations.Rotate(),
        albumentations.RandomScale(),
        albumentations.PadIfNeeded(300, 300),
        albumentations.Normalize(mean,
                                 std,
                                 max_pixel_value=255.0,
                                 always_apply=True),
    ])

    valid_aug = albumentations.Compose([
        albumentations.RandomResizedCrop(224, 224, (0.7, 1.0)),
        albumentations.HorizontalFlip(),
        albumentations.VerticalFlip(),
        albumentations.Cutout(),
        albumentations.RandomBrightness(),
        albumentations.RandomContrast(),
        albumentations.Rotate(),
        albumentations.RandomScale(),
        albumentations.PadIfNeeded(300, 300),
        albumentations.Normalize(mean,
                                 std,
                                 max_pixel_value=255.0,
                                 always_apply=True),
    ])

    train_images = df_train.image_id.values.tolist()
    train_images = [
        os.path.join(training_data_path, i + ".jpg") for i in train_images
    ]
    train_metada = df_train.drop([
        "fold", "target", "image_id", "patient_id", "source", "stratify_group"
    ],
                                 axis=1).values.tolist()
    train_targets = df_train.target.values

    valid_images = df_valid.image_id.values.tolist()
    valid_images = [
        os.path.join(training_data_path, i + ".jpg") for i in valid_images
    ]
    valid_metadata = df_valid.drop([
        "fold", "target", "image_id", "patient_id", "source", "stratify_group"
    ],
                                   axis=1).values.tolist()
    valid_targets = df_valid.target.values

    # datasets
    training_dataset = ClassificationLoader(image_paths=train_images,
                                            metadata=train_metada,
                                            targets=train_targets,
                                            resize=None,
                                            augmentations=train_aug)

    # loaders
    train_loader = torch.utils.data.DataLoader(training_dataset,
                                               batch_size=train_bs,
                                               shuffle=True,
                                               num_workers=4)

    valid_dataset = ClassificationLoader(image_paths=valid_images,
                                         metadata=valid_metadata,
                                         targets=valid_targets,
                                         resize=None,
                                         augmentations=valid_aug)

    valid_loader = torch.utils.data.DataLoader(valid_dataset,
                                               batch_size=valid_bs,
                                               shuffle=False,
                                               num_workers=4)

    model = EfficientNet_tabular(pretrained="imagenet")
    model.to(device)

    optimizer = torch.optim.Adam(model.parameters(), lr=1e-4)

    # max for auc metric
    scheduler = torch.optim.lr_scheduler.ReduceLROnPlateau(optimizer,
                                                           patience=3,
                                                           mode="max")

    # early stopping
    es = EarlyStopping(patience=3, mode="max")
    # import pdb; pdb.set_trace()
    for epoch in range(epochs):
        training_loss = Engine.train(train_loader, model, optimizer, device)
        predictions, valid_loss = Engine.evaluate(valid_loader, model, device)
        # import pdb; pdb.set_trace()
        predictions = np.vstack((predictions)).ravel()
        auc = metrics.roc_auc_score(valid_targets, predictions)
        scheduler.step(auc)

        print(f"epoch={epoch}, auc={auc}")
        es(auc, model, os.path.join(model_path, f"model{fold}.bin"))

        if es.early_stop:
            print("early stopping")
            break
args = parser.parse_args()

if args.distributed:
    dist.init_process_group('nccl', init_method='env://')
    world_size = dist.get_world_size()
    world_rank = dist.get_rank()
    local_rank = args.local_rank
else:
    local_rank = 0

torch.cuda.set_device(local_rank)
device = torch.device('cuda')

train_tfms = albu.Compose([
    albu.RandomScale([0.5, 2.0]),
    albu.RandomCrop(512, 768),
    albu.HorizontalFlip(),
    albu.Normalize(),
    ToTensor(),
])
val_tfms = albu.Compose([
    albu.Normalize(),
    ToTensor(),
])

cityscapes_dir = os.path.join(DATASET_DIR, 'cityscapes')
train_dataset = CityScapesDataset(
    cityscapes_dir, split='train', transforms=train_tfms)
val_dataset = CityScapesDataset(
    cityscapes_dir, split='val', transforms=val_tfms)
Exemple #28
0
parser.add_argument('--distributed', action='store_true')
parser.add_argument('--local_rank', type=int, default=0)
args = parser.parse_args()

distributed = args.distributed
world_size, world_rank, local_rank = setup_distributed(distributed,
                                                       args.local_rank)

device = torch.device('cuda')

crop_size = args.crop_size

train_tfms = albu.Compose([
    albu.RandomScale([0.75, 2],
                     interpolation=cv2.INTER_CUBIC,
                     always_apply=True),
    albu.RandomCrop(1024, 512),
    albu.HorizontalFlip(),
    # albu.HueSaturationValue(),
    albu.Normalize(),
    ToTensor(),
])
val_tfms = albu.Compose([
    albu.Normalize(),
    ToTensor(),
])

dataset_dir = get_datasets_root('cityscapes')
train_dataset = Cityscapes(dataset_dir, split='train', transforms=train_tfms)
val_dataset = Cityscapes(dataset_dir, split='val', transforms=val_tfms)
Exemple #29
0
parser.add_argument('--distributed', action='store_true')
parser.add_argument('--local_rank', type=int, default=0)
args = parser.parse_args()

distributed = args.distributed
world_size, world_rank, local_rank = setup_distributed(distributed,
                                                       args.local_rank)

device = torch.device('cuda')

crop_size = args.crop_size

train_tfms = albu.Compose([
    albu.RandomScale([-0.5, 1.0],
                     interpolation=cv2.INTER_CUBIC,
                     always_apply=True),
    albu.RandomCrop(512, 1024),
    albu.HorizontalFlip(),
    albu.HueSaturationValue(),
    albu.Normalize(),
    ToTensor(),
])
val_tfms = albu.Compose([
    albu.Normalize(),
    ToTensor(),
])

dataset_dir = get_datasets_root('cityscapes')
train_dataset = Cityscapes(dataset_dir, split='train', transforms=train_tfms)
val_dataset = Cityscapes(dataset_dir, split='val', transforms=val_tfms)
    def __init__(self,
                 base_dir='../data/pascal_voc_2012/VOCdevkit/VOC2012',
                 split='train_aug',
                 affine_augmenter=None,
                 image_augmenter=None,
                 target_size=(512, 512),
                 net_type='unet',
                 ignore_index=255,
                 debug=False):
        self.debug = debug
        self.base_dir = Path(base_dir)
        assert net_type in ['unet', 'deeplab']
        self.net_type = net_type
        self.ignore_index = ignore_index
        self.split = split

        valid_ids = self.base_dir / 'ImageSets' / 'Segmentation' / 'val.txt'
        with open(valid_ids, 'r') as f:
            valid_ids = f.readlines()
        if self.split == 'valid':
            lbl_dir = 'SegmentationClass'
            img_ids = valid_ids
        else:
            valid_set = set([valid_id.strip() for valid_id in valid_ids])
            lbl_dir = 'SegmentationClassAug' if 'aug' in split else 'SegmentationClass'
            all_set = set([
                p.name[:-4] for p in self.base_dir.joinpath(lbl_dir).iterdir()
            ])
            img_ids = list(all_set - valid_set)
        self.img_paths = [
            (self.base_dir / 'JPEGImages' / f'{img_id.strip()}.jpg')
            for img_id in img_ids
        ]
        self.lbl_paths = [(self.base_dir / lbl_dir / f'{img_id.strip()}.png')
                          for img_id in img_ids]

        # Resize
        if isinstance(target_size, str):
            target_size = eval(target_size)
        if 'train' in self.split:
            if self.net_type == 'deeplab':
                target_size = (target_size[0] + 1, target_size[1] + 1)
            self.resizer = albu.Compose([
                albu.RandomScale(scale_limit=(-0.5, 0.5), p=1.0),
                PadIfNeededRightBottom(min_height=target_size[0],
                                       min_width=target_size[1],
                                       value=0,
                                       ignore_index=self.ignore_index,
                                       p=1.0),
                albu.RandomCrop(height=target_size[0],
                                width=target_size[1],
                                p=1.0)
            ])
        else:
            # self.resizer = None
            self.resizer = albu.Compose([
                PadIfNeededRightBottom(min_height=target_size[0],
                                       min_width=target_size[1],
                                       value=0,
                                       ignore_index=self.ignore_index,
                                       p=1.0),
                albu.Crop(x_min=0,
                          x_max=target_size[1],
                          y_min=0,
                          y_max=target_size[0])
            ])

        # Augment
        if 'train' in self.split:
            self.affine_augmenter = affine_augmenter
            self.image_augmenter = image_augmenter
        else:
            self.affine_augmenter = None
            self.image_augmenter = None