def _build(self, img, sentinel=None, coords=None, logits=None): """Assume that `transform_param` has the shape of (..., n_params) where n_params = n_scales + n_shifts and: scale = transform_params[..., :n_scales] shift = transform_params[..., n_scales:n_scales+n_shifts] """ if sentinel is not None: raise ValueError( 'Either coords or logits must be given by kwargs!') if coords is not None and logits is not None: raise ValueError('Please give eithe coords or logits, not both!') if coords is None and logits is None: raise ValueError('Please give coords or logits!') if coords is None: coords = self.to_coords(logits) axis = coords.shape.ndims - 1 sx, sy, tx, ty = tf.split(coords, 4, axis=axis) sx, sy = (clip_preserve(s, 1e-4, s) for s in (sx, sy)) transform_params = tf.concat([sx, tx, sy, ty], -1) if len(img.get_shape()) == 3: img = img[..., tf.newaxis] if len(transform_params.get_shape()) == 2: return self._sample_image(img, transform_params) else: transform_params = tf.unstack(transform_params, axis=1) samples = [self._sample_image(img, tp) for tp in transform_params] return tf.stack(samples, axis=1)
def _build(self, img, sentinel=None, coords=None, logits=None): """Applies the transformation. Either coords or logits must be given, but not both. They have to be passed as kwarg. Assume that they have the shape of (..., n_params) where n_params = n_scales + n_shifts and: scale = transform_params[..., :n_scales] shift = transform_params[..., n_scales:n_scales+n_shifts] :param img: Tensor of images of shape `[B, H, W, C]`. :param sentinel: Unused; it is to guard `coords` or `logits` from being passed as positional arguments. :param coords: Tensor of coordinates in Spatial Transformer space. :param logits: Tensor of logits; they are converted to ST space. :return: Tensor of transformed images. """ if sentinel is not None: raise ValueError( 'Either coords or logits must be given by kwargs!') if coords is not None and logits is not None: raise ValueError('Please give eithe coords or logits, not both!') if coords is None and logits is None: raise ValueError('Please give coords or logits!') if coords is None: coords = self.to_coords(logits) axis = coords.shape.ndims - 1 sx, sy, tx, ty = tf.split(coords, 4, axis=axis) sx, sy = (ops.clip_preserve(s, 1e-4, s) for s in (sx, sy)) transform_params = tf.concat([sx, tx, sy, ty], -1) if len(img.get_shape()) == 3: img = img[..., tf.newaxis] if len(transform_params.get_shape()) == 2: return self._sample_image(img, transform_params) else: transform_params = tf.unstack(transform_params, axis=1) samples = [self._sample_image(img, tp) for tp in transform_params] return tf.stack(samples, axis=1)
def tabular_kl(p, q, zero_prob_value=0., logarg_clip=None): """Computes KL-divergence KL(p||q) for two probability mass functions (pmf) given in a tabular form. :param p: iterable :param q: iterable :param zero_prob_value: float; values below this threshold are treated as zero :param logarg_clip: float or None, clips the argument to the log to lie in [-logarg_clip, logarg_clip] if not None :return: iterable of brodcasted shape of (p * q), per-coordinate value of KL(p||q) """ p, q = (tf.cast(i, tf.float64) for i in (p, q)) non_zero = tf.greater(p, zero_prob_value) logarg = p / q if logarg_clip is not None: logarg = clip_preserve(logarg, 1. / logarg_clip, logarg_clip) log = masked_apply(logarg, tf.log, non_zero) kl = p * log return tf.cast(kl, tf.float32)
def log_prob(self, samples): prob = self.prob(samples) prob = clip_preserve(prob, 1e-16, 1.) return tf.log(prob)