def sample_pdf(bins, weights, N_samples, det=False): """Sample additional points for training fine network Args: bins: int. Height in pixels. weights: int. Width in pixels. N_samples: float. Focal length of pinhole camera. det Returns: samples: array of shape [batch_size, 3]. Depth samples for fine network """ weights += 1e-5 pdf = weights / F.sum(weights, axis=-1, keepdims=True) cdf = F.cumsum(pdf, axis=-1) # if isinstance(pdf, nn.Variable): # cdf = nn.Variable.from_numpy_array(tf.math.cumsum(pdf.d, axis=-1)) # else: # cdf = nn.Variable.from_numpy_array(tf.math.cumsum(pdf.data, axis=-1)).data cdf = F.concatenate(F.constant(0, cdf[..., :1].shape), cdf, axis=-1) if det: u = F.arange(0., 1., 1 / N_samples) u = F.broadcast(u[None, :], cdf.shape[:-1] + (N_samples, )) u = u.data if isinstance(cdf, nn.NdArray) else u else: u = F.rand(shape=cdf.shape[:-1] + (N_samples, )) indices = F.searchsorted(cdf, u, right=True) # if isinstance(cdf, nn.Variable): # indices = nn.Variable.from_numpy_array( # tf.searchsorted(cdf.d, u.d, side='right').numpy()) # else: # indices = nn.Variable.from_numpy_array( # tf.searchsorted(cdf.data, u.data, side='right').numpy()) below = F.maximum_scalar(indices - 1, 0) above = F.minimum_scalar(indices, cdf.shape[-1] - 1) indices_g = F.stack(below, above, axis=below.ndim) cdf_g = F.gather(cdf, indices_g, axis=-1, batch_dims=len(indices_g.shape) - 2) bins_g = F.gather(bins, indices_g, axis=-1, batch_dims=len(indices_g.shape) - 2) denom = (cdf_g[..., 1] - cdf_g[..., 0]) denom = F.where(F.less_scalar(denom, 1e-5), F.constant(1, denom.shape), denom) t = (u - cdf_g[..., 0]) / denom samples = bins_g[..., 0] + t * (bins_g[..., 1] - bins_g[..., 0]) return samples
def ray_march(self, camloc, raydir, t0, t1, N, n_chunks, t_argmin=False): # Points computation BR, _ = t0.shape t0 = F.reshape(t0, (BR, 1, 1)) t1 = F.reshape(t1, (BR, 1, 1)) camloc = F.reshape(camloc, (BR, 1, 3)) raydir = F.reshape(raydir, (BR, 1, 3)) step = (t1 - t0) / (N - 1) intervals = F.reshape(F.arange(0, N), (1, N, 1)) ts = t0 + step * intervals points = camloc + ts * raydir points = F.reshape(points, (BR * N, 3)) # SDF computation sdf_points = [] batch = (BR * N) // n_chunks for r in range(0, BR * N, batch): sdf_points.append(self.sdf(points[r:r + batch, :])) sdf_points = F.reshape(F.concatenate(*sdf_points, axis=0), (BR, N, 1)) if n_chunks != 1 else \ F.reshape(sdf_points[0], (BR, N, 1)) # t_argmin computation if t_argmin: idx_min = F.min(sdf_points, axis=1, keepdims=True, only_index=True) t_argmin = F.reshape(F.gather(ts, idx_min, axis=1, batch_dims=1), (BR, 1)) return t_argmin # Intersection check points = F.reshape(points, (BR, N, 3)) sdf_pos = F.greater_equal_scalar(sdf_points[:, :-1, :], 0) sdf_neg = F.less_equal_scalar(sdf_points[:, 1:, :], 0) mask_hit = sdf_pos * sdf_neg decreasing_consts = F.reshape(F.arange(N, 1, -1), (1, N - 1, 1)) vals = mask_hit * decreasing_consts idx_max = F.max(vals, axis=1, only_index=True) points = points[:, :-1, :] x_hit = F.gather(points, idx_max, axis=1, batch_dims=1) x_hit = F.reshape(x_hit, (BR, 3)) mask_hit = F.greater_scalar(F.sum(mask_hit, axis=1), 0) mask_hit = F.reshape(mask_hit, (BR, 1)) x_hit_rm0 = x_hit step = F.reshape(step, (BR, 1)) raydir = F.reshape(raydir, (BR, 3)) x_hit_rm1 = x_hit_rm0 + step * raydir return x_hit_rm0, x_hit_rm1, mask_hit
def generate_z_anchor(self): z_anchor_list = [] for _ in range(2): z_anchor_var = F.gather( self.init_z_var, combination( self.n_train, self.batch_size)) + F.randn( sigma=self.anch_std, shape=(self.batch_size, self.latent_dim)) z_anchor_list.append(z_anchor_var) return z_anchor_list
def _extract(a, t, x_shape=None): """ Extract some coefficients at specified timesteps. If x_shape is not None, reshape the extracted one to [batch_size, 1, 1, 1, 1, ...] corrensponding to x_shape for broadcasting purposes. """ B, = t.shape out = F.gather(a, t, axis=0) if x_shape is None: return out assert x_shape[0] == B assert out.shape == (B, ) out_shape = np.array(list(x_shape)) out_shape[1:] = 1 return F.reshape(out, out_shape)
def pack_padded_sequence(padded_sequence, lengths, batch_first=False, enforce_sorted=True): r"""Pack a padded variable-length sequences. This method packs a padded variable-length sequences. :math:`T` is the max length over the lengths of sequences. :math:`B` is the batch size equal to the length of the sequences. :math:`*` is the remaining dimensions including none. .. note:: This function **must** be used the dynamic computation mode. Example: .. code-block:: python import numpy as np import nnabla as nn import nnabla.functions as F import nnabla.utils.rnn as rnn_utils nn.set_auto_forward(True) l2v = lambda ldata: nn.Variable.from_numpy_array(np.asarray(ldata)) a = l2v([1, 1, 1, 1]) b = l2v([2, 2, 2]) c = l2v([2, 2, 2]) d = l2v([3, 3]) e = l2v([3, 3]) sequences = [a, b, c, d, e] lengths = l2v([seq.shape[0] for seq in sequences]) padded_sequence = rnn_utils.pad_sequence(sequences) print(padded_sequence.d) packed_sequence = rnn_utils.pack_padded_sequence(padded_sequence, lengths) print(packed_sequence.data.d) print(packed_sequence.batch_sizes.d) Args: padded_sequence (:obj:`nnabla.Variable`): Padded sequence of (:math:`T \times B \times *`) or (:math:`B \times T \times *`) shape. lengths (:obj:`nnabla.Variable`): Sequence length for each batch and always resides in CPU. batch_first (bool): `padded_sequence` is of (:math:`T`, :math:`B`, :math:`*`) shape if False, otherwise (:math:`B`, :math:`T`, :math:`*`). enforce_sorted (bool): Sequences are sorted by the length in a decreasing order if True. Default is True. Returns: :obj:`PackedSequence` """ if enforce_sorted: sorted_indices = None unsorted_indices = None else: # TODO: replace cuda context when the bug fix of the sort with nn.context_scope(nn.Context()): lengths, sorted_indices = F.sort(lengths, axis=0, reverse=True, with_index=True) B = sorted_indices.shape[0] unsorted_indices = F.scatter_nd(F.arange(0, B), sorted_indices.reshape((1, B)), shape=(B, )) axis = 0 if batch_first else 1 padded_sequence = F.gather(padded_sequence, sorted_indices, axis) packed_sequence, batch_sizes = F.pack_padded_sequence( padded_sequence, lengths, batch_first) packed_sequence0 = PackedSequence() packed_sequence0.data = packed_sequence packed_sequence0.batch_sizes = batch_sizes packed_sequence0.sorted_indices = sorted_indices packed_sequence0.unsorted_indices = unsorted_indices return packed_sequence0
def pad_packed_sequence(sequence, batch_first=False, padding_value=0.0, total_length=None): """Pad packed sequence. This method unpacks the packed sequqnce and pad it, the inverse operation of :func:`pack_padded_sequence`. :math:`T_i` is the length of the :math:`i`-th Variable in the sequences. :math:`B` is the batch size equal to the length of the sequences. :math:`T` is the max of :math:`T_i` for all :math:`i`. :math:`*` is the remaining dimensions including none. .. note:: This function **must** be used the dynamic computation mode. Example: .. code-block:: python import numpy as np import nnabla as nn import nnabla.functions as F import nnabla.utils.rnn as rnn_utils nn.set_auto_forward(True) l2v = lambda ldata: nn.Variable.from_numpy_array(np.asarray(ldata)) a = l2v([3, 3]) b = l2v([2, 2, 2]) c = l2v([2, 2, 2]) d = l2v([1, 1, 1, 1]) e = l2v([3, 3]) sequences = [a, b, c, d, e] packed_sequence = rnn_utils.pack_sequence(sequences, enforce_sorted=False) print(packed_sequence.data.d) print(packed_sequence.batch_sizes.d) padded_sequence, lengths = rnn_utils.pad_packed_sequence(packed_sequence) print(padded_sequence.d) print(lengths.d) Args: sequence (:obj:`PackedSequence`): PackedSequence. batch_first (bool): If False, output is of (:math:`T`, :math:`B`, :math:`*`) shape, otherwise (:math:`B`, :math:`T`, :math:`*`). padding_value (float): Padding value. total_length (int): If not None, the outputs are padded up to the `total_length`. If the `total_length` is less than the max length in the `sequences`, the error is thrown. This is normally used in the distributed training to align with the longest sequence in a distributed system. Returns: :obj:`nnabla.Variable` of (:math:`T`, :math:`B`, :math:`*`) or (:math:`B`, :math:`T`, :math:`*`) shape """ packed_sequence = sequence.data batch_sizes = sequence.batch_sizes sorted_indices = sequence.sorted_indices unsorted_indices = sequence.unsorted_indices T = batch_sizes.shape[0] if total_length is not None: if total_length < T: raise ValueError( "`total length ({})` must be greater than or equal to the maximum length ({})." .format(total_length, T)) padded_sequence, lengths = F.pad_packed_sequence(packed_sequence, batch_sizes, batch_first, padding_value, total_length) if unsorted_indices is not None: axis = 0 if batch_first else 1 padded_sequence = F.gather(padded_sequence, unsorted_indices, axis) lengths = lengths[unsorted_indices] return padded_sequence, lengths