Ejemplo n.º 1
0
    def __init__(self, data={}, n_gpus=1, data_shape=None, **config):
        self.datasets = data
        self.data_shape = data_shape
        self.n_gpus = n_gpus
        self.graph = tf.get_default_graph()
        self.name = self.__class__.__name__.lower()  # get child name

        # Update config
        self.config = dict_update(self.default_config,
                                  getattr(self, 'default_config', {}))
        self.config = dict_update(self.config, config)

        required = getattr(self, 'required_config_keys', [])
        if self.datasets:
            required += self.required_baseconfig
        for r in required:
            assert r in self.config, 'Required configuration entry: \'{}\''.format(
                r)
        assert set(self.datasets) <= self.dataset_names, \
            'Unknown dataset name: {}'.format(set(self.datasets)-self.dataset_names)
        assert n_gpus > 0, 'TODO: CPU-only training is currently not supported.'

        if data_shape is None:
            self.data_shape = {
                i: s['shape']
                for i, s in self.input_spec.items()
            }

        with tf.variable_scope('', reuse=tf.AUTO_REUSE):
            self._build_graph()
    def _model(self, inputs, mode, **config):
        assert mode != Mode.TRAIN

        config_path = Path(DATA_PATH, 'weights', config['config']).as_posix()
        with open(config_path, 'rb') as f:
            original_config = pickle.load(f).__dict__
        config = tools.dict_update(original_config, config)
        namespace = Namespace(**config)

        image = inputs['image'] / 255.0
        ops = build_networks(namespace, image, False)
        ops = {k: tf.expand_dims(v, axis=0) for k, v in ops.items()}
        ret = {
            'keypoints': ops['kpts'],
            'scores': ops['scores'],
            'descriptors': ops['feats']
        }
        return ret
    def __init__(self, **config):
        # Update config
        self.config = dict_update(getattr(self, 'default_config', {}), config)

        self.dataset = self._init_dataset(**self.config)
        self.split_names = getattr(self, 'split_names',
                                   self.default_split_names)

        self.tf_splits = {}
        self.tf_it = {}
        self.tf_next = {}
        with tf.device('/cpu:0'):
            for n in self.split_names:
                self.tf_splits[n] = self._get_data(self.dataset, n,
                                                   **self.config)
                prefetched = self.tf_splits[n].prefetch(
                    self.config.get('prefetch', 1))
                self.tf_it[n] = prefetched.make_initializable_iterator()
                self.tf_next[n] = self.tf_it[n].get_next()
        self.end_set = tf.errors.OutOfRangeError

        sess_config = tf.ConfigProto()
        sess_config.gpu_options.allow_growth = True
        self.sess = tf.Session(config=sess_config)
def homography_adaptation(image, net, config):
    """Perfoms homography adaptation.
    Inference using multiple random warped patches of the same input image for robust
    predictions.
    Arguments:
        image: A `Tensor` with shape `[N, H, W, 1]`.
        net: A function that takes an image as input, performs inference, and outputs the
            prediction dictionary.
        config: A configuration dictionary containing optional entries such as the number
            of sampled homographies `'num'`, the aggregation method `'aggregation'`.
    Returns:
        A dictionary which contains the aggregated detection probabilities.
    """

    probs = net(image)['prob']
    counts = tf.ones_like(probs)
    images = image

    probs = tf.expand_dims(probs, axis=-1)
    counts = tf.expand_dims(counts, axis=-1)
    images = tf.expand_dims(images, axis=-1)

    shape = tf.shape(image)[1:3]
    config = dict_update(homography_adaptation_default_config, config)

    def step(i, probs, counts, images):
        # Sample image patch
        H = sample_homography(shape, **config['homographies'])
        H_inv = invert_homography(H)
        warped = H_transform(image, H, interpolation='BILINEAR')
        count = H_transform(tf.expand_dims(tf.ones(tf.shape(image)[:3]), -1),
                            H_inv,
                            interpolation='NEAREST')[..., 0]

        # Predict detection probabilities
        warped_shape = tf.to_int32(
            tf.to_float(shape) * config['homographies']['patch_ratio'])
        input_warped = tf.image.resize_images(warped, warped_shape)
        prob = net(input_warped)['prob']
        prob = tf.image.resize_images(tf.expand_dims(prob, axis=-1),
                                      shape)[..., 0]
        prob_proj = H_transform(tf.expand_dims(prob, -1),
                                H_inv,
                                interpolation='BILINEAR')[..., 0]

        probs = tf.concat([probs, tf.expand_dims(prob_proj, -1)], axis=-1)
        counts = tf.concat([counts, tf.expand_dims(count, -1)], axis=-1)
        images = tf.concat([images, tf.expand_dims(warped, -1)], axis=-1)
        return i + 1, probs, counts, images

    _, probs, counts, images = tf.while_loop(
        lambda i, p, c, im: tf.less(i, config['num'] - 1),
        step, [0, probs, counts, images],
        parallel_iterations=1,
        back_prop=False,
        shape_invariants=[
            tf.TensorShape([]),
            tf.TensorShape([None, None, None, None]),
            tf.TensorShape([None, None, None, None]),
            tf.TensorShape([None, None, None, 1, None])
        ])

    counts = tf.reduce_sum(counts, axis=-1)
    max_prob = tf.reduce_max(probs, axis=-1)
    mean_prob = tf.reduce_sum(probs, axis=-1) / counts

    if config['aggregation'] == 'max':
        prob = max_prob
    elif config['aggregation'] == 'sum':
        prob = mean_prob
    else:
        raise ValueError('Unkown aggregation method: {}'.format(
            config['aggregation']))

    if config['filter_counts']:
        prob = tf.where(tf.greater_equal(counts, config['filter_counts']),
                        prob, tf.zeros_like(prob))

    return {
        'prob': prob,
        'counts': counts,
        'mean_prob': mean_prob,
        'input_images': images,
        'H_probs': probs
    }  # debug
    with open(args.config, 'r') as f:
        config = yaml.load(f)
    keys = '*' if args.keys == '*' else args.keys.split(',')

    if args.as_dataset:
        base_dir = Path(DATA_PATH, export_name)
    else:
        base_dir = Path(EXPER_PATH, 'exports')
        base_dir = Path(base_dir, ((exper_name + '/') if exper_name else '') +
                        export_name)
    base_dir.mkdir(parents=True, exist_ok=True)

    if exper_name:
        # Update only the model config (not the dataset)
        with open(Path(EXPER_PATH, exper_name, 'config.yaml'), 'r') as f:
            config['model'] = tools.dict_update(
                yaml.load(f)['model'], config.get('model', {}))
        checkpoint_path = Path(EXPER_PATH, exper_name)
        if config.get('weights', None):
            checkpoint_path = Path(checkpoint_path, config['weights'])
    else:
        if config.get('weights', None):
            checkpoint_path = Path(DATA_PATH, 'weights', config['weights'])
        else:
            checkpoint_path = None
            logging.info('No weights provided.')
    logging.info(f'Starting export with configuration:\n{pformat(config)}')

    with get_model(config['model']['name'])(data_shape={
            'image': [None, None, None, config['model']['image_channels']]
    },
                                            **config['model']) as net: