Esempio n. 1
0
def _wasserstein_distance(a, b):
    """
    Wasserstein distance function

    :param a: data points from distribution A
    :param b: data points from distribution B
    :return:
    """
    # Compute the cdf distance
    a_sorter = tf.argsort(a)
    b_sorter = tf.argsort(b)

    # Pooled value from both a and b
    all_values = K.concatenate([a, b])
    all_values = tf.sort(all_values)

    # Compute the difference between the sorted pooled values
    deltas = _diff(all_values)

    # Get the positions of the values of a and b between the 2 distributions
    a_cdf_indices = tf.searchsorted(tf.gather(a, a_sorter),
                                    all_values[:-1],
                                    side='right')
    b_cdf_indices = tf.searchsorted(tf.gather(b, b_sorter),
                                    all_values[:-1],
                                    side='right')

    # Calculate CDF
    a_cdf = tf.cast(a_cdf_indices / tf.size(a), 'float')
    b_cdf = tf.cast(b_cdf_indices / tf.size(b), 'float')

    # Wasserstein distance
    return K.sum(tf.multiply(K.abs(a_cdf - b_cdf), deltas))
Esempio n. 2
0
    def emd(self, x, y, nbins=255):

        x = tf.reshape(x, [-1])
        y = tf.reshape(y, [-1])

        range_h = [tf.reduce_min(tf.concat([x, y], axis=-1)), tf.reduce_max(tf.concat([x, y], axis=-1))]

        histo_x = tf.cast(tf.histogram_fixed_width(x, range_h, nbins=nbins, dtype=tf.int32), dtype=tf.float32)
        histo_y = tf.cast(tf.histogram_fixed_width(y, range_h, nbins=nbins, dtype=tf.int32), dtype=tf.float32)

        all_sorted_xy = tf.sort(tf.concat([histo_x, histo_y], axis=-1))
        
        all_sorted_xy_delta = tf.cast(all_sorted_xy[1:] - all_sorted_xy[:-1], dtype=tf.float32)

        histo_x_sorted = tf.sort(histo_x)
        histo_y_sorted = tf.sort(histo_y)

        histo_x_indices = tf.searchsorted(histo_x_sorted, all_sorted_xy[:-1], side='right')
        histo_y_indices = tf.searchsorted(histo_y_sorted, all_sorted_xy[:-1], side='right')

        cmdf_x = tf.cast(tf.math.divide(histo_x_indices, nbins), dtype=tf.float32)
        cmdf_y = tf.cast(tf.math.divide(histo_y_indices, nbins), dtype=tf.float32)
        
        return tf.math.sqrt(tf.reduce_sum(tf.math.multiply(tf.math.squared_difference(cmdf_x, cmdf_y), all_sorted_xy_delta)))
        
Esempio n. 3
0
def tf_wasserstein_dist(label, predicted):
    u_values = K.flatten(predicted)
    v_values = K.flatten(label)
    u_weights = weightsMatrix[0]
    v_weights = weightsMatrix[0]

    u_sorter = tf.argsort(u_values)
    v_sorter = tf.argsort(v_values)

    all_values = tf.concat((u_values, v_values), axis=0)
    all_values = tf.sort(all_values)

    def tf_diff_axis_0(a):
        return a[1:] - a[:-1]

    deltas = tf_diff_axis_0(all_values)

    u_cdf_indices = tf.gather(u_values, u_sorter)
    u_cdf_indices = tf.searchsorted(u_cdf_indices, all_values[:-1], 'right')
    v_cdf_indices = tf.gather(v_values, v_sorter)
    v_cdf_indices = tf.searchsorted(v_cdf_indices, all_values[:-1], 'right')

    u_sorted_weights = K.cumsum(tf.gather(u_weights, u_sorter))
    u_sorted_weights = tf.concat(([0], u_sorted_weights), axis=0)
    u_cdf = tf.gather(u_sorted_weights, u_cdf_indices) / u_sorted_weights[-1]

    v_sorted_weights = K.cumsum(tf.gather(v_weights, v_sorter))
    v_sorted_weights = tf.concat(([0], v_sorted_weights), axis=0)
    v_cdf = tf.gather(v_sorted_weights, v_cdf_indices) / v_sorted_weights[-1]

    result = tf.cast(K.abs(u_cdf - v_cdf), tf.float32)
    return K.sum(tf.math.multiply(result, deltas))
Esempio n. 4
0
    def update_state(self, y_true, y_pred, sample_weight=None):
        """Accumulates ranks.

        Args:
          y_true: actual rank values.
          y_pred: predicted rank values.
          sample_weight (optional): Ignored.

        Returns:
          Update op.
        """
        if y_true.shape and y_true.shape[0]:
            i = tf.searchsorted(
                self.actual_cuts,
                tf.cast(tf.reshape(y_true, -1), self.actual_cuts.dtype),
            )
            j = tf.searchsorted(
                self.preds_cuts, tf.cast(tf.reshape(y_pred, -1), self.preds_cuts.dtype)
            )

            def body(k, n, m, nrow, ncol):
                return (
                    k + 1,
                    n + 1,
                    tf.sparse.add(
                        m,
                        tf.SparseTensor(
                            [[i[k], j[k]]],
                            tf.cast([1], dtype=self.m.dtype),
                            self.m.shape,
                        ),
                    ),
                    tf.sparse.add(
                        nrow,
                        tf.SparseTensor(
                            [[i[k]]],
                            tf.cast([1], dtype=self.nrow.dtype),
                            self.nrow.shape,
                        ),
                    ),
                    tf.sparse.add(
                        ncol,
                        tf.SparseTensor(
                            [[j[k]]],
                            tf.cast([1], dtype=self.ncol.dtype),
                            self.ncol.shape,
                        ),
                    ),
                )

            _, self.n, self.m, self.nrow, self.ncol = tf.while_loop(
                lambda k, n, m, nrow, ncol: k < i.shape[0],
                body=body,
                loop_vars=(0, self.n, self.m, self.nrow, self.ncol),
            )
Esempio n. 5
0
def replace(x, mapping, zero=True):
    """Replace values in tensor `x` using dictionary `mapping`.

    Parameters
    ----------
    x: tensor, values to replace.
    mapping: dict, dictionary mapping original values to new values. Values in
        x equal to a key in the mapping are replaced with the corresponding
        value. Keys and values may overlap.
    zero: boolean, zero values in `x` not in `mapping.keys()`.

    Returns
    -------
    Modified tensor.
    """
    x = tf.cast(x, dtype=tf.int32)
    keys = tf.convert_to_tensor(list(mapping.keys()))
    vals = tf.convert_to_tensor(list(mapping.values()))

    sidx = tf.argsort(keys)
    ks = tf.gather(keys, sidx)
    vs = tf.gather(vals, sidx)

    idx = tf.searchsorted(ks, tf.reshape(x, (-1, )))
    idx = tf.reshape(idx, x.shape)

    # Zero values that are equal to len(vs).
    idx = tf.multiply(idx, tf.cast(tf.not_equal(idx, vs.shape[0]), tf.int32))
    mask = tf.equal(tf.gather(ks, idx), x)
    if zero:
        out = tf.where(mask, tf.gather(vs, idx), 0)
    else:
        out = tf.where(mask, tf.gather(vs, idx), x)

    return out
Esempio n. 6
0
def map_cat_sparse(fn, Nr, batchsize, index_dtype=tf.int64):
    CURROW = 0
    WIDTH = None

    def go(st, en):
        nonlocal CURROW, WIDTH
        g = fn(st, en)

        # check for consistant widths
        if WIDTH is None:
            WIDTH = g.shape[1]
        else:
            assert WIDTH == g.shape[1]

        rows_n_cols = tf.cast(tf.where(g), dtype=index_dtype)
        data = tf.gather_nd(g, rows_n_cols)
        rows = rows_n_cols[:, 0] + st
        cols = rows_n_cols[:, 1]

        return rows, cols, data

    rows, cols, data = map_accum(go, Nr, batchsize, 'ccc')
    row_indptr = tf.searchsorted(rows, tf.range(0, Nr + 1, dtype=rows.dtype))
    return sparsematrix.CSRMatrix(row_indptr, rows, cols, data, (Nr, WIDTH),
                                  rows.shape[0])
Esempio n. 7
0
def rle2mask(rle, mask_shape):
    '''
    Converts a run lenght encoding (RLE) into a mask of shape mask_shape
    Args:
        rle: (str or bytestring) run lenght encoding. A series of space
            separated start-pixel run pairs.
        mask_shape: (tuple of 2 ints) the 2D expected shape of the mask
    Returns: mask of shape mask_shape
    '''
    size = tf.math.reduce_prod(mask_shape)

    s = tf.strings.split(rle)
    s = tf.strings.to_number(s, tf.int32)

    starts = s[0::2] - 1
    lens = s[1::2]

    total_ones = tf.reduce_sum(lens)
    ones = tf.ones([total_ones], tf.int32)

    r = tf.range(total_ones)
    lens_cum = tf.math.cumsum(lens)
    s = tf.searchsorted(lens_cum, r, 'right')
    idx = r + tf.gather(starts - tf.pad(lens_cum[:-1], [(1, 0)]), s)

    mask_flat = tf.scatter_nd(tf.expand_dims(idx, 1), ones, [size])
    mask = tf.reshape(mask_flat, (mask_shape[1], mask_shape[0]))
    return tf.transpose(mask)
Esempio n. 8
0
    def get_all_N_bit_intervals(self, Z):
        """

        :param Z: batch of latent representations of shape B x C
        :return: two tensors of shape C x (N+1) x B
        """
        N = self.max_bits_per_coord
        # backend has to be tensorflow >= 1.15 for searchsorted to work below (numpy's version doesn't support matrices)
        Z_repeated = tf.repeat(tf.transpose(Z)[:, None, :], N + 1,
                               axis=1)  # C x (N+1) x B
        right_endpoint_idx = tf.searchsorted(
            self._search_grids, Z_repeated,
            side='left')  # search inner-most dim
        right_endpoint_idx = tf.clip_by_value(right_endpoint_idx, 0,
                                              2**N - 1)  # C x (N+1) x B
        left_endpoint_idx = tf.clip_by_value(right_endpoint_idx - 1, 0,
                                             2**N - 1)
        right_endpoints = tf.gather(self._search_grids,
                                    right_endpoint_idx,
                                    batch_dims=2)
        left_endpoints = tf.gather(self._search_grids,
                                   left_endpoint_idx,
                                   batch_dims=2)

        return left_endpoints, right_endpoints
Esempio n. 9
0
 def from_dense_tensor(cls,t,index_dtype=tf.int64):
     rows_n_cols = tf.cast(tf.where(t),dtype=index_dtype)
     data=tf.gather_nd(t,rows_n_cols)
     rows=rows_n_cols[:,0]
     cols=rows_n_cols[:,1]
     row_indptr = tf.searchsorted(rows,tf.range(0,t.shape[0]+1,dtype=rows.dtype))
     return CSRMatrix(row_indptr,cols,data,t.shape,rows.shape[0])
Esempio n. 10
0
    def sample_pdf(self, u, bins, weights):
        """ Creates samples along ray.
        Args:
            u: Distribution of sample probabilities along rays
            bins: Number of samples to compute
            weights: Unnormalized pdf"""
        weights += 1e-5  # prevent nans
        pdf = weights / tf.reduce_sum(weights, -1, keepdims=True)
        print(f"pdf {pdf}")
        cdf = tf.cumsum(pdf, -1)
        cdf = tf.concat([tf.zeros_like(cdf[..., :1]), cdf], -1)
        inds = tf.searchsorted(cdf, u, side='right')
        print(f"inds {inds}")
        below = tf.maximum(0, inds - 1)
        above = tf.minimum(tf.shape(cdf)[-1] - 1, inds)
        inds_g = tf.stack([below, above], -1)
        cdf_g = tf.gather(cdf,
                          inds_g,
                          axis=-1,
                          batch_dims=len(tf.shape(inds_g)) - 2)
        bins_g = tf.gather(bins,
                           inds_g,
                           axis=-1,
                           batch_dims=len(tf.shape(inds_g)) - 2)

        denom = (cdf_g[..., 1] - cdf_g[..., 0])
        denom = tf.where(denom < 1e-5, tf.ones_like(denom), denom)
        t = (u - cdf_g[..., 0]) / denom
        samples = bins_g[..., 0] + t * (bins_g[..., 1] - bins_g[..., 0])

        return samples
 def _inverse(self, y):
   flat_y = tf.reshape(y, shape=[-1])
   # Search for the indices of self.map_values that are closest to flat_y.
   # Since self.map_values is strictly increasing, the closest is either the
   # first one that is strictly greater than flat_y, or the one before it.
   upper_candidates = tf.minimum(
       tf.size(input=self.map_values) - 1,
       tf.searchsorted(self.map_values, values=flat_y, side='right'))
   lower_candidates = tf.maximum(0, upper_candidates - 1)
   candidates = tf.stack([lower_candidates, upper_candidates], axis=-1)
   lower_cand_diff = tf.abs(flat_y - self._forward(lower_candidates))
   upper_cand_diff = tf.abs(flat_y - self._forward(upper_candidates))
   if self.validate_args:
     with tf.control_dependencies([
         tf.compat.v1.assert_near(
             tf.minimum(lower_cand_diff, upper_cand_diff),
             0,
             message='inverse value not found')
     ]):
       candidates = tf.identity(candidates)
   candidate_selector = tf.stack([
       tf.range(tf.size(input=flat_y), dtype=tf.int32),
       tf.argmin(
           input=[lower_cand_diff, upper_cand_diff], output_type=tf.int32)
   ],
                                 axis=-1)
   return tf.reshape(
       tf.gather_nd(candidates, candidate_selector), shape=y.shape)
Esempio n. 12
0
def sample_pdf(bins, weights, n_samples, det=False):
  """Function for sampling a probability distribution."""
  # Get pdf
  weights += 1e-5  # prevent nans
  pdf = weights / tf.reduce_sum(weights, -1, keepdims=True)
  cdf = tf.cumsum(pdf, -1)
  cdf = tf.concat([tf.zeros_like(cdf[Ellipsis, :1]), cdf], -1)

  # Take uniform samples
  u_shape = tf.concat([tf.shape(cdf)[:-1], tf.constant([n_samples])], axis=0)
  if det:
    u = tf.linspace(0., 1., n_samples)
    u = tf.broadcast_to(u, u_shape)
  else:
    u = tf.random.uniform(u_shape)

  # Invert CDF
  inds = tf.searchsorted(cdf, u, side='right')
  below = tf.maximum(0, inds - 1)
  above = tf.minimum(tf.shape(cdf)[-1] - 1, inds)
  inds_g = tf.stack([below, above], -1)
  cdf_g = tf.gather(cdf, inds_g, axis=-1, batch_dims=len(tf.shape(inds_g)) - 2)
  bins_g = tf.gather(
      bins, inds_g, axis=-1, batch_dims=len(tf.shape(inds_g)) - 2)

  denom = (cdf_g[Ellipsis, 1] - cdf_g[Ellipsis, 0])
  denom = tf.where(denom < 1e-5, tf.ones_like(denom), denom)
  t = (u - cdf_g[Ellipsis, 0]) / denom
  samples = bins_g[Ellipsis, 0] + t * (bins_g[Ellipsis, 1] - bins_g[Ellipsis, 0])

  return samples
Esempio n. 13
0
def sample_pdf(bins, weights, N_samples, det=False):
    # Get pdf
    weights += 1e-5  # prevent nans
    pdf = weights / tf.reduce_sum(input_tensor=weights, axis=-1, keepdims=True)
    cdf = tf.cumsum(pdf, -1)
    cdf = tf.concat([tf.zeros_like(cdf[..., :1]), cdf], -1)

    # Take uniform samples
    if det:
        u = tf.linspace(0., 1., N_samples)
        u = tf.broadcast_to(u, list(cdf.shape[:-1]) + [N_samples])
    else:
        u = tf.random.uniform(list(cdf.shape[:-1]) + [N_samples])

    # Invert CDF
    inds = tf.searchsorted(cdf, u, side='right')
    below = tf.maximum(0, inds - 1)
    above = tf.minimum(cdf.shape[-1] - 1, inds)
    inds_g = tf.stack([below, above], -1)
    cdf_g = tf.gather(cdf, inds_g, axis=-1, batch_dims=len(inds_g.shape) - 2)
    bins_g = tf.gather(bins, inds_g, axis=-1, batch_dims=len(inds_g.shape) - 2)

    denom = (cdf_g[..., 1] - cdf_g[..., 0])
    denom = tf.compat.v1.where(denom < 1e-5, tf.ones_like(denom), denom)
    t = (u - cdf_g[..., 0]) / denom
    samples = bins_g[..., 0] + t * (bins_g[..., 1] - bins_g[..., 0])

    return samples
Esempio n. 14
0
def alphas_neighbour_knots(a_q2, padded_q2, actual_values):
    """
    Parameters
    ----------
        a_q2: tf.tensor
            tensor of values of q2
        padded_q2: tf.tensor
            values of log(q2) of the grid
        actual_values: tf.tensor
            values of the grid
    Returns
    ----------
        q2_id: tf.tensor of shape [None]
            q2 bin for each query point
        corn_q2: tf.tensor of shape [4,None]
            q2 values of the 4 knots around the query point
        A: tf.tensor of shape [4,None]
            alphas values of the 4 grid knots around the query point
    """
    # print('nk')
    q2_id = tf.searchsorted(padded_q2[1:-1], a_q2, out_type=DTYPEINT)
    s = tf.size(padded_q2, out_type=DTYPEINT)
    q2_id = tf.clip_by_value(q2_id, tf.constant([0], dtype=DTYPEINT), s - 3)

    piu = tf.reshape(tf.range(-1, 3, dtype=DTYPEINT), (4, 1))
    corn_q2_id = tf.repeat(tf.reshape(q2_id, (1, -1)), 4, axis=0) + piu

    corn_q2 = tf.gather(padded_q2, corn_q2_id, name="fnk_2")

    A = tf.gather(actual_values, corn_q2_id, name="fnk_3")

    return q2_id, corn_q2, A
Esempio n. 15
0
def offsets_to_segment_ids(offsets):
    '''Transforms offsets to segment_ids,
  the segment_ids will be used in tf.segment_sum/segment_mean
  [3, 0, 1, 2] -> [0, 0, 0, 1, 3, 3].
  '''
    c = tf.cumsum(offsets)
    return tf.searchsorted(c, tf.range(c[-1]), side='right')
Esempio n. 16
0
def _piecewise_constant_function(x, jump_locations, values,
                                 batch_rank, side='left'):
  """Computes value of the piecewise constant function."""
  # Initializer already verified that `jump_locations` and `values` have the
  # same shape
  batch_shape = jump_locations.shape.as_list()[:-1]
  # Check that the batch shape of `x` is the same as of `jump_locations` and
  # `values`
  batch_shape_x = x.shape.as_list()[:batch_rank]
  if batch_shape_x != batch_shape:
    raise ValueError('Batch shape of `x` is {1} but should be {0}'.format(
        batch_shape, batch_shape_x))
  if x.shape.as_list()[:batch_rank]:
    no_batch_shape = False
  else:
    no_batch_shape = True
    x = tf.expand_dims(x, 0)
  # Expand batch size to one if there is no batch shape
  if not batch_shape:
    jump_locations = tf.expand_dims(jump_locations, 0)
    values = tf.expand_dims(values, 0)
  indices = tf.searchsorted(jump_locations, x, side=side)
  index_matrix = _prepare_index_matrix(
      indices.shape.as_list()[:-1], indices.shape.as_list()[-1], indices.dtype)
  indices_nd = tf.concat(
      [index_matrix, tf.expand_dims(indices, -1)], -1)
  res = tf.gather_nd(values, indices_nd)
  if no_batch_shape:
    return tf.squeeze(res, 0)
  else:
    return res
Esempio n. 17
0
    def quantize(self, lab_images):
        l = lab_images[:, :, :, :1] * 50.0
        ab = (lab_images[:, :, :, 1:] * 255.0) - 128.0
        e = np.linspace(1, 50, 50, dtype=np.float32)
        linspace = np.tile(e, [ab.shape[0], ab.shape[1], ab.shape[2], 1])
        l_inds = tf.searchsorted(linspace, l)
        l_inds = tf.squeeze(l_inds)
        bs, h, w, c = ab.shape
        ab = tf.reshape(ab, [bs * h * w, c])
        (dists, inds) = self.nbrs.kneighbors(ab)

        # Sigma = 5
        sigma = 5
        wts = tf.exp(dists**2 / (2 * sigma**2))
        #wts = tf.reduce_mean(wts, axis=1)
        wts = tf.nn.softmax(wts)
        inds = tf.expand_dims(inds, -1)
        batch_ind = tf.expand_dims(tf.range(0, bs * h * w, 1, dtype=tf.int64),
                                   -1)
        batch_ind = tf.tile(batch_ind, tf.constant([1, 5], tf.int32))
        batch_ind = tf.expand_dims(batch_ind, -1)
        inds = tf.concat([batch_ind, inds], axis=-1)

        #wts = tf.expand_dims(wts, -2)

        #hot_mixed_l = tf.scatter_nd(indices=l_inds, updates=1, shape=[128, 32, 32, 50])
        hot_mixed_l = tf.one_hot(l_inds, 50)
        hot_mixed_ab = tf.scatter_nd(indices=inds,
                                     updates=wts,
                                     shape=[bs * h * w, 313])
        hot_mixed_ab = tf.reshape(hot_mixed_ab, [bs, h, w, 313])

        return hot_mixed_l, hot_mixed_ab
def rle_decode_tf(
        mask_rle  # the run-length encoded mask, as a string
    ,
        shape  # the image dimension e.g. (640,480)
):
    """
    function for converting masks in Run-Length Encoding into a tensor 
    source: https://stackoverflow.com/questions/58693261/decoding-rle-run-length-encoding-mask-with-tensorflow-datasets
    """
    shape = tf.convert_to_tensor(shape, tf.int64)
    size = tf.math.reduce_prod(shape)
    # Split string
    s = tf.strings.split(mask_rle)
    s = tf.strings.to_number(s, tf.int64)
    # Get starts and lengths
    starts = s[::2] - 1
    lens = s[1::2]
    # Make ones to be scattered
    total_ones = tf.reduce_sum(lens)
    ones = tf.ones([total_ones], tf.uint8)
    # Make scattering indices
    r = tf.range(total_ones)
    lens_cum = tf.math.cumsum(lens)
    s = tf.searchsorted(lens_cum, r, 'right')
    idx = r + tf.gather(starts - tf.pad(lens_cum[:-1], [(1, 0)]), s)
    # Scatter ones into flattened mask
    mask_flat = tf.scatter_nd(tf.expand_dims(idx, 1), ones, [size])
    # Reshape into mask
    return tf.transpose(tf.reshape(mask_flat, shape))
Esempio n. 19
0
def _discrete_percentile_function(spacings,
                                  n_particles,
                                  on_log,
                                  weights=None,
                                  log_weights=None):
    """vectorised resampling function, can be used for systematic/stratified/multinomial resampling
    """
    if on_log:
        cumlogsumexp = tf.math.cumulative_logsumexp(log_weights, axis=1)
        log_spacings = tf.math.log(spacings)
        indices = tf.searchsorted(cumlogsumexp, log_spacings, side='left')

    else:
        cum_sum = tf.math.cumsum(weights, axis=1)
        indices = tf.searchsorted(cum_sum, spacings, side='left')

    return tf.clip_by_value(indices, 0, n_particles - 1)
Esempio n. 20
0
def _interleave_ecdfs(x1: tf.Tensor, y1: tf.Tensor, x2: tf.Tensor,
                      y2: tf.Tensor) -> Tuple[tf.Tensor, tf.Tensor, tf.Tensor]:
    """
    Interleave two eCDFs by their argument
    """

    x = tf.contrib.framework.sort(tf.concat([x1, x2], axis=0), axis=0)
    y1 = tf.concat([tf.zeros(shape=(1, tf.shape(y1)[1]), dtype=y1.dtype), y1],
                   axis=0)
    y2 = tf.concat([tf.zeros(shape=(1, tf.shape(y2)[1]), dtype=y2.dtype), y2],
                   axis=0)
    return (x,
            _T(
                tf.batch_gather(_T(y1),
                                tf.searchsorted(_T(x1), _T(x), side='right'))),
            _T(
                tf.batch_gather(_T(y2),
                                tf.searchsorted(_T(x2), _T(x), side='right'))))
Esempio n. 21
0
 def __call__(self, t):
     "Evaluate p(t)"
     # does not use horners scheme but it's probably ok
     t = tf.convert_to_tensor([t], dtype=tf.float64)
     i = tf.searchsorted(self.x, t, side="right") - 1
     ci = tf.gather(self.c, i, axis=1)  # [D, T]
     ti = t - tf.gather(self.x, i, axis=0)  # [T]
     i = tf.range(ci.shape[0], dtype=tf.float64)[::-1, None]
     return tf.reduce_sum(ci * tf.math.pow(ti[None], i), axis=0)[0]  # [T]
Esempio n. 22
0
    def compress_latents(self, posterior_means, posterior_logvars, lambs):
        float_type = self.float_type

        posterior_vars = tf.exp(posterior_logvars)
        C = posterior_vars.shape[-1]  # number of latent channels
        assert C == self.num_channels
        batch_means, batch_vars = map(
            lambda r: tf.reshape(r, (-1, C)),
            [posterior_means, posterior_vars])  # num_samples x C
        batch_stds = batch_vars**0.5

        Z_hat_dict, raw_num_bits_dict = self.compress_batch_channel_latents(
            batch_means, batch_stds, lambs, return_np=False)
        out_keys = ('Z_hat', 'raw_num_bits', 'num_bits_cl', 'num_bits')
        output = {key: dict() for key in out_keys}

        for lamb in lambs:
            tmp_res_for_lamb = dict()

            Z_hat = Z_hat_dict[lamb]
            raw_num_bits = raw_num_bits_dict[lamb]

            tmp_res_for_lamb['Z_hat'] = Z_hat
            tmp_res_for_lamb['raw_num_bits'] = raw_num_bits

            # # calculate code length using raw num bits + codelength overhead approach
            # raw_code_length_entropy_model = self.raw_code_length_entropy_models[lamb]  # C x (N+1)
            # raw_code_length_overhead_num_bits = tf.gather(raw_code_length_entropy_model,
            #                                               tf.transpose(raw_num_bits), batch_dims=1)  # C x B
            # raw_code_length_overhead_num_bits = tf.transpose(raw_code_length_overhead_num_bits)  # B x C
            # num_bits_cl = tf.cast(raw_num_bits, float_type) + \
            #               tf.cast(raw_code_length_overhead_num_bits, float_type)  # B x C

            # calculate code length using direct entropy coding approach
            I = tf.searchsorted(self.code_points_by_channel,
                                tf.transpose(Z_hat))  # C x B; requires TF
            # assert tf.reduce_all(tf.equal(tf.gather(self.code_points_by_channel, I, batch_dims=1),
            #                               tf.transpose(Z_hat)))
            entropy_model = self.entropy_models[
                lamb]  # C x quantization_levels
            num_bits = tf.gather(entropy_model, I,
                                 batch_dims=1)  # gather across innermost axis
            num_bits = tf.transpose(num_bits)  # B x C

            # tmp_res_for_lamb['num_bits_cl'] = num_bits_cl
            if self.raw_code_length_entropy_models:
                tmp_res_for_lamb['num_bits_cl'] = raw_num_bits
            tmp_res_for_lamb['num_bits'] = num_bits

            for key in out_keys:
                # tmp_res_for_lamb[key] = np.reshape(item, posterior_means.shape)
                output[key][lamb] = np.reshape(
                    tmp_res_for_lamb[key], posterior_means.shape
                )  # same shape as latents; np.reshape moves to CPU

        return output
 def interp(x, xp, fp):
     i = tf.clip_by_value(tf.searchsorted(xp, x, side='right'), 0,
                          xp.shape[0] - 1)
     df = tf.gather(fp, i) - tf.gather(fp, i - 1)
     dx = tf.gather(xp, i) - tf.gather(xp, i - 1)
     delta = x - tf.gather(xp, i - 1)
     f = tf.where((dx == 0), tf.cast(tf.gather(fp, i), tf.float32),
                  tf.cast(tf.gather(fp, i - 1), tf.float32) +
                  (delta / dx) * tf.cast(df, tf.float32))
     return f * 0.99999
Esempio n. 24
0
 def sample_batch(_):
     values = tf.random.uniform((sample_batch_size, ), 0.0,
                                weight_sum[-1])
     ind = tf.searchsorted(weight_sum, values)
     return (tf.gather(self.states, ind,
                       0), tf.gather(self.actions, ind, 0),
             tf.gather(self.next_states, ind,
                       0), tf.gather(self.rewards, ind,
                                     0), tf.gather(self.masks, ind, 0),
             tf.gather(self.weights, ind,
                       0), tf.gather(self.steps, ind, 0))
Esempio n. 25
0
def weighted_quantile(x, quantiles, weights=None, side="middle"):
    """Very close to numpy.percentile, but supports weights.
    NOTE: quantiles should be in [0, 1]!
    :param x: tensor with data
    :param quantiles: array-like with many quantiles needed
    :param weights: array-like of the same length as `x`
    :return: numpy.array with computed quantiles.
    """
    if weights is None:
        return tfp.stats.percentile(x, 100 * quantiles)
    x = znp.array(x)
    quantiles = znp.array(quantiles)
    quantiles = znp.reshape(quantiles, (-1, ))
    weights = znp.array(weights)

    sorter = znp.argsort(x)
    x = tf.gather(x, sorter)
    weights = tf.gather(weights, sorter)

    weighted_quantiles = znp.cumsum(weights) - 0.5 * weights

    weighted_quantiles /= znp.sum(weights)
    if side == "middle":
        quantile_index_left = tf.searchsorted(weighted_quantiles,
                                              quantiles,
                                              side="left")
        quantile_index_right = tf.searchsorted(weighted_quantiles,
                                               quantiles,
                                               side="right")

        calculated_left = tf.gather(x, quantile_index_left)
        calculated_right = tf.gather(x, quantile_index_right)
        calculated = (calculated_left + calculated_right) / 2
    elif side in ("left", "right"):

        quantile_index = tf.searchsorted(weighted_quantiles,
                                         quantiles,
                                         side=side)

        calculated = tf.gather(x, quantile_index)
    return calculated
Esempio n. 26
0
def inverse_transform_sampling_1d(
        bins: TensorLike,
        pdf: TensorLike,
        num_samples: int,
        name="inverse_transform_sampling_1d") -> tf.Tensor:
    """Sampling 1D points from a distribution using the inverse transform.

     The target distrubution is defined by its probability density function and
     the spatial 1D location of its bins. The new random samples correspond to
     the centers of the bins.

  Args:
    bins: A tensor of shape `[A1, ..., An, M]` containing 1D location of M bins.
      For example, a tensor [a, b, c, d] corresponds to
      the bin structure |--a--|-b-|--c--|d|.
    pdf: A tensor of shape `[A1, ..., An, M]` containing the probability
      distribution in M bins.
    num_samples: The number N of new samples.
    name:  A name for this op that defaults to "inverse_transform_sampling_1d".

  Returns:
    A tensor of shape `[A1, ..., An, N]` indicating the new N random points.
  """

    with tf.name_scope(name):
        bins = tf.convert_to_tensor(value=bins)
        pdf = tf.convert_to_tensor(value=pdf)

        shape.check_static(tensor=bins,
                           tensor_name="bins",
                           has_rank_greater_than=0)
        shape.check_static(tensor=pdf,
                           tensor_name="pdf",
                           has_rank_greater_than=0)
        shape.compare_batch_dimensions(tensors=(bins, pdf),
                                       tensor_names=("bins", "pdf"),
                                       last_axes=-2,
                                       broadcast_compatible=True)
        shape.compare_dimensions(tensors=(bins, pdf),
                                 tensor_names=("bins", "pdf"),
                                 axes=-1)
        # Do not consider the last bin, as the cdf contains has +1 dimension.
        pdf = _normalize_pdf(pdf[..., :-1])
        cdf = _get_cdf(pdf)
        batch_shape = tf.shape(pdf)[:-1]
        # TODO(krematas): Use dynamic values
        batch_dims = tf.get_static_value(tf.rank(pdf) - 1)
        target_shape = tf.concat([batch_shape, [num_samples]], axis=-1)
        uniform_samples = tf.random.uniform(target_shape)
        bin_indices = tf.searchsorted(cdf, uniform_samples, side="right")
        bin_indices = tf.maximum(0, bin_indices - 1)
        z_values = tf.gather(bins, bin_indices, axis=-1, batch_dims=batch_dims)
        return z_values
Esempio n. 27
0
def tf_argsort_based_on_two_cols(v):

    c2_log = tf.log(1 + v[:, 1])
    max_c2 = tf.reduce_max(c2_log) + 1

    us_c1_u, _ = tf.unique(v[:, 0])
    c1_u = tf.sort(us_c1_u)
    c1_inds = tf.searchsorted(c1_u, v[:, 0], side='left')

    eq_num = tf.cast(c1_inds, tf.float64) * max_c2 + c2_log

    return tf.argsort(eq_num)
def backtest_rolling_forecast_aggregates(params, historic_types, historic_times, event_types, event_times,
    batch_size, window, n_events, n_simulations, score_against, score_shape=[], pred_window_multiple=1, n_splits=1): # our time step is the same as the window size. params may contain multiple processes once again
  interval_event_types, interval_event_times, n_intervals = chop_record_by_time_interval(event_types, event_times, window)
  leftover_excitation = tf.zeros_like(params.excitation_coef)
  leftover_suppression = tf.zeros_like(params.suppression_coef)
  time_of_leftover = historic_times[0]
  n_evaluations = (n_intervals - 1 if historic_types is None else n_intervals) - pred_window_multiple + 1 # if we are given (historic_types, historic_times), then we may evaluate every single interval by kickstarting on e.g. the training set. Helps especially when the test set is tiny.
  n_processes = params.excitation_coef.shape[0] if len(params.excitation_coef.shape) == 3 else 1 # static version of `tf.rank`
  scores = tf.zeros([n_evaluations, n_processes] + list(score_shape), dtype=event_times.dtype)
  anchor_time = tf.cast(0, dtype=event_times.dtype) # should really be set with the first interval, otherwise might produce garbage until changed
  prev_hard_window = tf.cast(window, event_times.dtype)
  for interval in tf.range(n_evaluations): # all completely dynamic. funny that this is a desideratum now that static unrolling has become a bottleneck, contraty to how it is in most programming environments!
    if historic_times is None:
      prelude_types, prelude_times = interval_event_types[interval, ...], interval_event_times[interval, ...]
    else:
      if interval == 0:
        prelude_types, prelude_times = historic_types, historic_times
      else:
        prelude_types, prelude_times = interval_event_types[interval-1, ...], interval_event_times[interval-1, ...]
    if tf.size(prelude_times) == 0:
      hard_window = prev_hard_window
    else:
      anchor_time = prelude_times[-1] # basically `prelude_times[-1]`, with the added functionality of tracking the last non-empty one
      # this shouldn't be needed now that the last interval is thrown away anyways. keep it as a failsafe
      hard_window = tf.math.minimum(event_times[-1] - anchor_time, window * pred_window_multiple) # if we are at the end of the record, our last interval must be subjected to a hard cutoff. pred_window_multiple allows us to achieve a crude version of overlapping sliding windows: make the intervals small, then forecast over a collection of them.
    sub_windows = tf.linspace(tf.cast(0, event_times.dtype), hard_window, n_splits+1)[1:]
    aggregates, max_n_events_counted, leftover_excitation, leftover_suppression, time_of_leftover = \
      forecast_window_aggregates(params, prelude_types, prelude_times, batch_size, hard_window, n_events, n_simulations, sub_windows,
        warm_start_excitation=leftover_excitation, warm_start_suppression=leftover_suppression, time_of_warm_start=time_of_leftover, return_leftovers=True)
    tf.print("Counted at most", max_n_events_counted, "simulated events out of", n_events, "in interval", interval+1, "out of", n_evaluations, "\b.")
    real_deal_intervals = interval_event_types[(interval+1):(interval+1+pred_window_multiple), ...] if historic_times is None \
      else interval_event_types[interval:(interval+pred_window_multiple), ...]
    real_deal_types = tf.concat([real_deal_intervals[i, ...] for i in range(pred_window_multiple)], axis=0) # how is it so hard to unstack and flatten a ragged tensor?
    real_deal_time_intervals = interval_event_times[(interval+1):(interval+1+pred_window_multiple), ...] if historic_times is None \
      else interval_event_times[interval:(interval+pred_window_multiple), ...]
    real_deal_times = tf.concat([real_deal_time_intervals[i, ...] for i in range(pred_window_multiple)], axis=0)
    real_instances = tf.math.equal(real_deal_types, tf.range(params.n_dims, dtype=real_deal_types.dtype)[:, None]) # (n_types x window events)
    if n_splits == 1:
      real_aggregates = tf.math.count_nonzero(real_instances, axis=1, dtype=event_times.dtype)
    else:
      real_instance_indicators = tf.transpose(tf.cast(real_instances, tf.int32)) # (window events x n_types)
      real_assignments = tf.searchsorted(sub_windows, real_deal_times - anchor_time) # shift the frame of reference
      split_real_aggregates = tf.math.segment_sum( # see `forecast_window_aggregates` for explanation
        tf.concat([real_instance_indicators, tf.broadcast_to([[0]], [1, params.n_dims])], axis=0),
        tf.concat([real_assignments, [n_splits]], axis=0) ) # (n_splits+1 x n_types)
      real_aggregates = tf.cast(tf.transpose(split_real_aggregates[:-1, :]), event_times.dtype) # touched-up/refined version of the above
    interval_scores = score_against(aggregates, real_aggregates)# real_aggregate if n_splits==1 else real_aggregates -- for some reason this is not treated purely like a static evaluation.. must be something with the decorator
    # ^ must return a tensor with one entry (row? hyper-row?) for each process
    selector = tf.reshape(tf.one_hot(interval, n_evaluations, dtype=scores.dtype), [-1, 1] + [1]*len(score_shape))
    scores += tf.ensure_shape(interval_scores, [n_processes] + score_shape) * selector
    prev_hard_window = hard_window
  return scores
Esempio n. 29
0
 def _cdf(self, x):
   x = tf.convert_to_tensor(value=x, name='x')
   flat_x = tf.reshape(x, shape=[-1])
   upper_bound = tf.searchsorted(self.outcomes, values=flat_x, side='right')
   values_at_ub = tf.gather(
       self.outcomes,
       indices=tf.minimum(upper_bound,
                          dist_util.prefer_static_shape(self.outcomes)[-1] -
                          1))
   should_use_upper_bound = self._is_equal_or_close(flat_x, values_at_ub)
   indices = tf.where(should_use_upper_bound, upper_bound, upper_bound - 1)
   return self._categorical.cdf(
       tf.reshape(indices, shape=dist_util.prefer_static_shape(x)))
Esempio n. 30
0
def inverse(x, R_in):
    ''' Require tensorflow '''
    ''' Input: 
	x: a real number
	R: a neuron netweek with one hidden layer and RELU activation 
       Return:
	It computes the inverst of R_in by regarding R_in as a piecewise linear continuous function
	Example of R_in (built in keras):
	
	R_in = keras.Sequential(
    [
        keras.Input(shape=(1,)),
        layers.Dense(H, activation="relu", name="hidden"),
        layers.Dense(1, activation=None, name="output"),
    ]
)
  '''
    x = tf.dtypes.cast(x, tf.float32)
    w, b = R_in.get_layer('hidden').weights
    v, v0 = R_in.get_layer('output').weights

    num_layer = w.shape[1]

    b_over_w = -b / w  # the negative sign is important
    b_over_w = tf.reshape(b_over_w, [-1])  # change it to row vector
    # Then we need to compute range for the inverse function
    r_x = tf.reshape([
        tf.matmul((tf.nn.relu(w * b_over_w[i] + b)), v) + v0 for i in range(1)
    ], [-1])
    # pad r_x with 0 and inf
    # right side gives us the right index
    pos = tf.searchsorted(tf.sort(tf.concat([[0], r_x, [np.inf]], 0)),
                          x,
                          side='right')  # get the interval index
    # tf.print('pos',pos)
    pos = tf.reshape(pos, [])  # get only numerical value
    # change it to row vector
    v = tf.reshape(v, [-1])
    w = tf.reshape(w, [-1])

    index = tf.argsort(r_x)
    # tf.print(pos,"\n")

    # sort according to the index
    v_b = tf.gather(v * b, index)
    v_w = tf.gather(v * w, index)

    num = x - v0 - tf.reduce_sum(v_b[:(pos - 1)])
    deo = tf.reduce_sum(v_w[:(pos - 1)])

    return tf.math.divide_no_nan(num, deo)[0]