Exemple #1
0
class EvaluationSettings(Configurable):
    data_loaders = State()
    visualize = State(default=True)
    resume = State()

    def __init__(self, **kwargs):
        self.load_all(**kwargs)
Exemple #2
0
class RandomSampleDataLoader(Configurable, torch.utils.data.DataLoader):
    datasets = State()
    weights = State()
    batch_size = State(default=256)
    num_workers = State(default=10)
    size = State(default=2**31)

    def __init__(self, **kwargs):
        self.load_all(**kwargs)

        cmd = kwargs['cmd']
        if 'batch_size' in cmd:
            self.batch_size = cmd['batch_size']

        probs = []
        for dataset, weight in zip(self.datasets, self.weights):
            probs.append(np.full(len(dataset), weight / len(dataset)))

        dataset = ConcatDataset(self.datasets)
        probs = np.concatenate(probs)
        assert (len(dataset) == len(probs))

        sampler = RandomSampleSampler(dataset, probs, self.size)

        torch.utils.data.DataLoader.__init__(
            self,
            dataset,
            batch_size=self.batch_size,
            num_workers=self.num_workers,
            sampler=sampler,
            worker_init_fn=default_worker_init_fn,
        )
Exemple #3
0
class ResizeData(_ResizeImage, DataProcess):
    key = State(default='image')
    box_key = State(default='polygons')
    image_size = State(default=[64, 256])  # height, width

    def __init__(self, cmd={}, mode=None, key=None, box_key=None, **kwargs):
        self.load_all(**kwargs)
        if mode is not None:
            self.mode = mode
        if key is not None:
            self.key = key
        if box_key is not None:
            self.box_key = box_key
        if 'resize_mode' in cmd:
            self.mode = cmd['resize_mode']
        assert self.mode in self.MODES

    def process(self, data):
        height, width = data['image'].shape[:2]
        new_height, new_width = self.get_image_size(data['image'])
        data[self.key] = self.resize_or_pad(data[self.key])

        charboxes = data[self.box_key]
        data[self.box_key] = charboxes.copy()
        data[self.box_key][:, :, 0] = data[self.box_key][:, :, 0] * \
            new_width / width
        data[self.box_key][:, :, 1] = data[self.box_key][:, :, 1] * \
            new_height / height
        return data
Exemple #4
0
class ShowSettings(Configurable):
    data_loader = State()
    representer = State()
    visualizer = State()

    def __init__(self, **kwargs):
        self.load_all(**kwargs)
Exemple #5
0
class Checkpoint(Configurable):
    start_epoch = State(default=0)
    start_iter = State(default=0)
    resume = State()

    def __init__(self, **kwargs):
        self.load_all(**kwargs)

        cmd = kwargs['cmd']
        if 'start_epoch' in cmd:
            self.start_epoch = cmd['start_epoch']
        if 'start_iter' in cmd:
            self.start_iter = cmd['start_iter']
        if 'resume' in cmd:
            self.resume = cmd['resume']

    def restore_model(self, model, device, logger):
        if self.resume is None:
            return

        if not os.path.exists(self.resume):
            self.logger.warning("Checkpoint not found: " + self.resume)
            return

        logger.info("Resuming from " + self.resume)
        state_dict = torch.load(self.resume, map_location=device)
        model.load_state_dict(state_dict, strict=False)
        logger.info("Resumed from " + self.resume)

    def restore_counter(self):
        return self.start_epoch, self.start_iter
Exemple #6
0
class FilterKeys(DataProcess):
    required = State(default=[])
    superfluous = State(default=[])

    def __init__(self, **kwargs):
        super().__init__(self, **kwargs)

        self.required_keys = set(self.required)
        self.superfluous_keys = set(self.superfluous)
        if len(self.required_keys) > 0 and len(self.superfluous_keys) > 0:
            raise ValueError(
                'required_keys and superfluous_keys can not be specified at the same time.')

    def process(self, data):
        for key in self.required:
            assert key in data, '%s is required in data' % key

        superfluous = self.superfluous_keys
        if len(superfluous) == 0:
            for key in data.keys():
                if key not in self.required_keys:
                    superfluous.add(key)

        for key in superfluous:
            del data[key]
        return data
Exemple #7
0
class SerializeBox(DataProcess):
    box_key = State(default='charboxes')
    format = State(default='NP2')

    def process(self, data):
        data[self.box_key] = data['lines'].quads
        return data
Exemple #8
0
class MultiStepLR(Configurable):
    lr = State()
    milestones = State(default=[])  # milestones must be sorted
    gamma = State(default=0.1)

    def __init__(self, cmd={}, **kwargs):
        self.load_all(**kwargs)
        self.lr = cmd.get('lr', self.lr)

    def get_learning_rate(self, epoch, step):
        return self.lr * self.gamma**bisect_right(self.milestones, epoch)
Exemple #9
0
class DecayLearningRate(Configurable):
    lr = State(default=0.007)
    epochs = State(default=1200)
    factor = State(default=0.9)

    def __init__(self, **kwargs):
        self.load_all(**kwargs)

    def get_learning_rate(self, epoch, step=None):
        rate = np.power(1.0 - epoch / float(self.epochs + 1), self.factor)
        return rate * self.lr
Exemple #10
0
class WarmupLR(Configurable):
    steps = State(default=4000)
    warmup_lr = State(default=1e-5)
    origin_lr = State()

    def __init__(self, cmd={}, **kwargs):
        self.load_all(**kwargs)

    def get_learning_rate(self, epoch, step):
        if epoch == 0 and step < self.steps:
            return self.warmup_lr
        return self.origin_lr.get_learning_rate(epoch, step)
Exemple #11
0
class TrainSettings(Configurable):
    data_loader = State()
    model_saver = State()
    checkpoint = State()
    scheduler = State()
    epochs = State(default=10)

    def __init__(self, **kwargs):
        kwargs['cmd'].update(is_train=True)
        self.load_all(**kwargs)
        if 'epochs' in kwargs['cmd']:
            self.epochs = kwargs['cmd']['epochs']
Exemple #12
0
class ValidationSettings(Configurable):
    data_loaders = State()
    visualize = State()
    interval = State(default=100)
    exempt = State(default=-1)

    def __init__(self, **kwargs):
        kwargs['cmd'].update(is_train=False)
        self.load_all(**kwargs)

        cmd = kwargs['cmd']
        self.visualize = cmd['visualize']
Exemple #13
0
class PiecewiseConstantLearningRate(Configurable):
    boundaries = State(default=[10000, 20000])
    values = State(default=[0.001, 0.0001, 0.00001])

    def __init__(self, **kwargs):
        self.load_all(**kwargs)

    def get_learning_rate(self, epoch, step):
        for boundary, value in zip(self.boundaries, self.values[:-1]):
            if step < boundary:
                return value
        return self.values[-1]
Exemple #14
0
class Structure(Configurable):
    builder = State()
    representer = State()
    measurer = State()
    visualizer = State()

    def __init__(self, **kwargs):
        self.load_all(**kwargs)

    @property
    def model_name(self):
        return self.builder.model_name
Exemple #15
0
class MakeCenterMap(DataProcess):
    max_size = State(default=32)
    shape = State(default=(64, 256))
    sigma_ratio = State(default=16)
    function_name = State(default='sample_gaussian')
    points_key = 'points'
    correlation = 0  # The formulation of guassian is simplified when correlation is 0

    def process(self, data):
        assert self.points_key in data, '%s in data is required' % self.points_key
        points = data['points'] * self.shape[::-1]  # N, 2
        assert points.shape[0] >= self.max_size
        func = getattr(self, self.function_name)
        data['charmaps'] = func(points, *self.shape)
        return data

    def gaussian(self, points, height, width):
        index_x, index_y = np.meshgrid(np.linspace(0, width, width),
                                       np.linspace(0, height, height))
        index_x = np.repeat(index_x[np.newaxis], points.shape[0], axis=0)
        index_y = np.repeat(index_y[np.newaxis], points.shape[0], axis=0)
        mu_x = points[:, 0][:, np.newaxis, np.newaxis]
        mu_y = points[:, 1][:, np.newaxis, np.newaxis]
        mask_is_zero = ((mu_x == 0) + (mu_y == 0)) == 0
        result = np.reciprocal(2 * np.pi * width / self.sigma_ratio * height / self.sigma_ratio)\
            * np.exp(- 0.5 * (np.square((index_x - mu_x) / width * self.sigma_ratio) +
                              np.square((index_y - mu_y) / height * self.sigma_ratio)))

        result = result / \
            np.maximum(result.max(axis=1, keepdims=True).max(
                axis=2, keepdims=True), np.finfo(np.float32).eps)
        result = result * mask_is_zero
        return result.astype(np.float32)

    def sample_gaussian(self, points, height, width):
        points = (points + 0.5).astype(np.int32)
        canvas = np.zeros((self.max_size, height, width), dtype=np.float32)
        for index in range(canvas.shape[0]):
            point = points[index]
            canvas[index, point[1], point[0]] = 1.
            if point.sum() > 0:
                fi.gaussian_filter(canvas[index], (height // self.sigma_ratio,
                                                   width // self.sigma_ratio),
                                   output=canvas[index], mode='mirror')
                canvas[index] = canvas[index] / canvas[index].max()
                x_range = min(point[0], width - point[0])
                canvas[index, :, :point[0] - x_range] = 0
                canvas[index, :, point[0] + x_range:] = 0
                y_range = min(point[1], width - point[1])
                canvas[index, :point[1] - y_range, :] = 0
                canvas[index, point[1] + y_range:, :] = 0
        return canvas
Exemple #16
0
class MakeCenterPoints(DataProcess):
    box_key = State(default='charboxes')
    size = State(default=32)

    def process(self, data):
        shape = data['image'].shape[:2]
        points = np.zeros((self.size, 2), dtype=np.float32)
        boxes = np.array(data[self.box_key])[:self.size]

        size = boxes.shape[0]
        points[:size] = boxes.mean(axis=1)
        data['points'] = (points / shape[::-1]).astype(np.float32)
        return data
Exemple #17
0
class ResizeImage(_ResizeImage, DataProcess):
    mode = State(default='keep_ratio')
    image_size = State(default=[1152, 2048])  # height, width
    key = State(default='image')

    def __init__(self, cmd={}, mode=None, **kwargs):
        self.load_all(**kwargs)
        if mode is not None:
            self.mode = mode
        if 'resize_mode' in cmd:
            self.mode = cmd['resize_mode']
        assert self.mode in self.MODES

    def process(self, data):
        data[self.key] = self.resize_or_pad(data[self.key])
        return data
Exemple #18
0
class ConstantLearningRate(Configurable):
    lr = State(default=0.0001)

    def __init__(self, **kwargs):
        self.load_all(**kwargs)

    def get_learning_rate(self, epoch, step):
        return self.lr
Exemple #19
0
class OptimizerScheduler(Configurable):
    optimizer = State()
    optimizer_args = State(default={})
    learning_rate = State(autoload=False)

    def __init__(self, cmd={}, **kwargs):
        self.load_all(**kwargs)
        self.load('learning_rate', cmd=cmd, **kwargs)
        if 'lr' in cmd:
            self.optimizer_args['lr'] = cmd['lr']

    def create_optimizer(self, parameters):
        optimizer = getattr(torch.optim, self.optimizer)(parameters,
                                                         **self.optimizer_args)
        if hasattr(self.learning_rate, 'prepare'):
            self.learning_rate.prepare(optimizer)
        return optimizer
Exemple #20
0
class Builder(Configurable):
    model = State()
    model_args = State()

    def __init__(self, cmd={}, **kwargs):
        self.load_all(**kwargs)
        if 'backbone' in cmd:
            self.model_args['backbone'] = cmd['backbone']

    @property
    def model_name(self):
        return self.model + '-' + getattr(structure_model, self.model).model_name(self.model_args)

    def build(self, device, distributed=False, local_rank: int = 0):
        Model = getattr(structure_model,self.model)
        model = Model(self.model_args, device,
                      distributed=distributed, local_rank=local_rank)
        return model
Exemple #21
0
class SliceDataset(TorchDataset, Configurable):
    dataset = State()
    start = State()
    end = State()

    def __init__(self, **kwargs):
        self.load_all(**kwargs)

        if self.start is None:
            self.start = 0
        if self.end is None:
            self.end = len(self.dataset)

    def __getitem__(self, idx):
        return self.dataset[self.start + idx]

    def __len__(self):
        return self.end - self.start
Exemple #22
0
class PriorityLearningRate(Configurable):
    learning_rates = State()

    def __init__(self, **kwargs):
        self.load_all(**kwargs)

    def get_learning_rate(self, epoch, step):
        for learning_rate in self.learning_rates:
            lr = learning_rate.get_learning_rate(epoch, step)
            if lr is not None:
                return lr
        return None
Exemple #23
0
class Experiment(Configurable):
    structure = State(autoload=False)
    train = State()
    validation = State(autoload=False)
    evaluation = State(autoload=False)
    logger = State(autoload=True)

    def __init__(self, **kwargs):
        self.load('structure', **kwargs)

        cmd = kwargs.get('cmd', {})
        if 'name' not in cmd:
            cmd['name'] = self.structure.model_name

        self.load_all(**kwargs)
        self.distributed = cmd.get('distributed', False)
        self.local_rank = cmd.get('local_rank', 0)

        if cmd.get('validate', False):
            self.load('validation', **kwargs)
        else:
            self.validation = None
Exemple #24
0
class FileMonitorLearningRate(Configurable):
    file_path = State()

    def __init__(self, **kwargs):
        self.load_all(**kwargs)

        self.monitor = SignalMonitor(self.file_path)

    def get_learning_rate(self, epoch, step):
        signal = self.monitor.get_signal()
        if signal is not None:
            return float(signal)
        return None
Exemple #25
0
class InfiniteDataLoader(Configurable, torch.utils.data.DataLoader):
    dataset = State()
    batch_size = State(default=256)
    num_workers = State(default=10)
    limit_size = State(default=2**31)

    def __init__(self, **kwargs):
        self.load_all(**kwargs)

        cmd = kwargs['cmd']
        if 'batch_size' in cmd:
            self.batch_size = cmd['batch_size']

        sampler = InfiniteOrderedSampler(self.dataset, self.limit_size)

        torch.utils.data.DataLoader.__init__(
            self,
            self.dataset,
            batch_size=self.batch_size,
            num_workers=self.num_workers,
            sampler=sampler,
            worker_init_fn=default_worker_init_fn,
        )
Exemple #26
0
class ModelSaver(Configurable):
    dir_path = State()
    save_interval = State(default=1000)
    signal_path = State()

    def __init__(self, **kwargs):
        self.load_all(**kwargs)

        # BUG: signal path should not be global
        self.monitor = SignalMonitor(self.signal_path)

    def maybe_save_model(self, model, epoch, step, logger):
        if step % self.save_interval == 0 or self.monitor.get_signal(
        ) is not None:
            self.save_model(model, epoch, step)
            logger.report_time('Saving ')
            logger.iter(step)

    def save_model(self, model, epoch=None, step=None):
        if isinstance(model, dict):
            for name, net in model.items():
                checkpoint_name = self.make_checkpoint_name(name, epoch, step)
                self.save_checkpoint(net, checkpoint_name)
        else:
            checkpoint_name = self.make_checkpoint_name('model', epoch, step)
            self.save_checkpoint(model, checkpoint_name)

    def save_checkpoint(self, net, name):
        os.makedirs(self.dir_path, exist_ok=True)
        torch.save(net.state_dict(), os.path.join(self.dir_path, name))

    def make_checkpoint_name(self, name, epoch=None, step=None):
        if epoch is None or step is None:
            c_name = name + '_latest'
        else:
            c_name = '{}_epoch_{}_minibatch_{}'.format(name, epoch, step)
        return c_name
Exemple #27
0
class BuitlinLearningRate(Configurable):
    lr = State(default=0.001)
    klass = State(default='StepLR')
    args = State(default=[])
    kwargs = State(default={})

    def __init__(self, cmd={}, **kwargs):
        self.load_all(**kwargs)
        self.lr = cmd.get('lr', None) or self.lr
        self.scheduler = None

    def prepare(self, optimizer):
        self.scheduler = getattr(lr_scheduler,
                                 self.klass)(optimizer, *self.args,
                                             **self.kwargs)

    def get_learning_rate(self, epoch, step=None):
        if self.scheduler is None:
            raise 'learning rate not ready(prepared with optimizer) '
        self.scheduler.last_epoch = epoch
        # return value of gt_lr is a list,
        # where each element is the corresponding learning rate for a
        # paramater group.
        return self.scheduler.get_lr()[0]
Exemple #28
0
class DataIdMetaLoader(MetaLoader):
    return_dict = State(default=False)
    scan_meta = False

    def __init__(self, return_dict=None, cmd={}, **kwargs):
        super().__init__(cmd=cmd, **kwargs)
        if return_dict is not None:
            self.return_dict = return_dict

    def parse_meta(self, data_id):
        return dict(data_id=data_id)

    def post_prosess(self, meta):
        if self.return_dict:
            return meta
        return meta['data_id']
Exemple #29
0
class UnifyRect(SerializeBox):
    max_size = State(default=64)

    def process(self, data):
        h, w = data['image'].shape[:2]
        boxes = np.zeros((self.max_size, 4), dtype=np.float32)
        mask_has_box = np.zeros(self.max_size, dtype=np.float32)
        data = super().process(data)
        quad = data[self.box_key]
        assert quad.shape[0] <= self.max_size
        boxes[:quad.shape[0]] = quad.rectify() / np.array([w, h, w, h
                                                           ]).reshape(1, 4)
        mask_has_box[:quad.shape[0]] = 1.
        data['boxes'] = boxes
        data['mask_has_box'] = mask_has_box
        return data
Exemple #30
0
class RandomCropAug(Configurable):
    size = State(default=640)

    def __init__(self, size=640, *args, **kwargs):
        self.size = size or self.size
        self.augment = RandomCrop(size)

    def __call__(self, data):
        '''
        This augmenter is supposed to following the process of `MakeICDARData`,
        in which labels are mapped to this specific format:
            (image, polygons: (n, 4, 2), tags: [Boolean], ...)
        '''
        image, boxes, ignore_tags = data[:3]
        image, boxes, ignore_tags = self.augment(image, boxes, ignore_tags)
        return (image, boxes, ignore_tags, *data[3:])