src.utils.ptransf.receptive_field_gs
Classes
|
- class src.utils.ptransf.receptive_field_gs.ReceptiveFieldGS(**kwargs)
- Author:
Alberto M. Esmoris Pena
Class representing a receptive field based on grid subsampling.
Receptive fields constitute a discrete representation of a point cloud of m points using R points. More formally, the receptive field can be defined as a transformation \(\mathcal{R}(\pmb{X})\) such that:
\[\mathcal{R}: \mathbb{R}^{m \times n} \rightarrow \mathbb{R}^{R \times n}\]The receptive field transformation is modelled using an indexing matrix \(\pmb{N} \in \mathbb{Z}_{\geq -1}^{R \times R^*}\), where \(R^*\) represents the number of correspondences of the point in \(\mathcal{R}\) that corresponds to the maximum number of points in \(\pmb{X}\). Each row \(\pmb{n}_{i*} \in \mathbb{Z}_{\geq -1}^{R^*}\) contains the indices of the points in \(\pmb{X}\) that are associated to the point \(i\) in \(\mathcal{R}\). Furthermore, the greater-than-or-equal-to-zero integer universe is extended with a \(-1\) symbol that does not represent the minus one number, but instead it is the shadow element of the universe. This shadow index is interpreted in the context of the receptive field as a mask that disables certain computations for some empty cells in the receptive field. It is used to model \(\pmb{N}\) as a matrix, for convenience.
The baseline receptive field is implemented as an n-dimensional grid that supports axis-wise steps for its definition. It can be used to build a representation of a point cloud, do some computation on the representation, and then propagate the values back to the original point cloud. For example, the computation can be a classification computed by a neural network that works on sets of \(R\) points.
See
ReceptiveFieldandGridSubsamplingPreProcessor.- Variables:
cell_size (
np.ndarray) – The cell size with respect to the radius. It is noted as \(\pmb{s} = (s_1, \ldots, s_n)\). Each \(s_i \in [0, 2]\) defines how many times the radius must be considered as the step. A value of 2 means there is only one partition along the axis i, and a value of 1 means there are two partitions because the total considered length is twice the radius per axis. In general, a value of \(0 \leq s_i \leq 2\) leads to \(\left\lceil{\dfrac{2}{s_i}}\right\rceil\) partitions.dimensionality (int) – The dimensionality of the space where the points are defined. Typically, it refers to the dimensionality of the structure space, i.e., the points without the features. For example, considering the \((x, y)\) coordinates of the points implies a dimensionality \(n=2\), while considering the \((x, y, z)\) coordinates of the points implies a dimensionality \(n=3\).
bounding_radii (
np.ndarray) –The radii vector \(\pmb{r} = (r_1, \ldots, r_n)\) that defines the radius for each axis. The length of the axis \(i\) represented by the receptive field is given by \(2 \times r_i\), i.e., twice the axis radius.
One simple way to compute the bounding radius for a set of coordinates \(X_i = \{x_{1i}, \ldots, x_{mi}\}\) is:
\[r_i = \dfrac{\max X_i - \min X_i}{2}\]num_cells (int) –
The number of cells \(R\) composing the receptive field. It is computed as:
\[R = \Biggl\lfloor\biggl({ \prod_{i=1}^{n}{\dfrac{s_i}{2}} }\biggr)^{-1}\Biggr\rceil\]Where \(\lfloor x \rceil\) means rounding to the nearest integer of x with round half toward positive infinity as tie-breaking rule.
N (
np.ndarray) – The indexing matrix \(\pmb{N}_{\geq -1}\) described above. It is computed when callingreceptive_field_gs.ReceptiveFieldGS.fit().x (
np.ndarray) – The center point of the receptive field. It is assigned when callingreceptive_field_gs.ReceptiveFieldGS.fit().m (int) – The number of points represented in the receptive fields. It is assigned when calling
receptive_field_gs.ReceptiveFieldGS.fit().
- __init__(**kwargs)
Initialize/instantiate a receptive field object.
- Parameters:
kwargs – The key-word specification to instantiate the ReceptiveFieldGS.
- Keyword Arguments:
bounding_radii (
np.ndarray) – The bounding radius for each axis defining the receptive field. SeeReceptiveFieldGSfor a more detailed description.cell_size (
np.ndarray) – The cell size defining the receptive field. By default it is \((0.05, 0.05, 0.05)\). SeeReceptiveFieldGSfor a more detailed description.
- fit(X, x, structure_float_type=<class 'numpy.float64'>)
Fit the receptive field to represent the given points by building a grid containing them.
The matrix of indices \(\pmb{N} \in \mathbb{Z}_{\geq -1}^{R \times R^*}\) is computed here. See also
receptive_field_gs.ReceptiveFieldGS.shadow_indexing_matrix_from_points().- Parameters:
X (
np.ndarray) – The input matrix of m points in an n-dimensional space.x (
np.ndarray) – The center point used to define the origin of the receptive field.structure_float_type (
np.dtype) – The decimal type for the structure space.
- Returns:
The fit receptive field itself (for fluent programming).
- Return type:
- centroids_from_points(X, interpolate=False, fill_centroid=False)
Compute the centroids, i.e., for each cell in the receptive field the point that represents the cell assuming the receptive field is applied to the rows of \(\pmb{X} \in \mathbb{R}^{m \times n}\) understood as points.
Let \(\pmb{Y} \in \mathbb{R}^{R \times n}\) be the matrix whose rows represent the centroids. Besides, consider the set of neighbors for a given point \(i\) as \(\mathcal{N}_i = \lvert\left\{n_{ij} \geq 0 : 1 \leq j \leq R^* \rvert\right\}\) , where \(n_{ij}\) is the element at row \(i\) column \(j\) in the matrix \(\pmb{N}\) (see
ReceptiveFieldGS). For then, each centroid can be computed such that:\[\pmb{y}_{i*} = \lvert\mathcal{N}_{i}\rvert^{-1} \sum_{j \in \mathcal{N}_{i}}{\pmb{x}_{j*}}\]Regarding the interpolation, any missing centroid is defined considering the midrange point of the cell (i.e., the geometric center) and its \(3^{n}-1\) closest neighbors. The coordinate-wise mean of these points yields the interpolated value. The reason why \(3^{n}-1\) is selected as the number of neighbors for the interpolation is based on the idea that for 2D and 3D neighborhoods considering a cell in a grid and all its neighbor cells yields \(3^{n}\) neighbors. One is discarded because it corresponds to the cell itself being interpolated. Consequently, \(3^{n}-1\) is expected to be a reasonable compromise to avoid considering too much points so the interpolated point represents the entire receptive field instead of the local region where it belongs to. At the same time, the number of neighbors also scales with the dimensionality to provide an acceptable sample for a reliable interpolation.
- Parameters:
X (
np.ndarray) – The matrix of input pointsinterpolate (bool) – True to interpolate missing centroids from non-missing centroids, False otherwise.
fill_centroid (bool) – When interpolate is False and fill_centroid is True, all missing points will be fill as the centroid of the input point cloud.
- Returns:
A matrix which rows are the points representing the centroids.
- Return type:
np.ndarray
- propagate_values(v, safe=True, **kwargs)
Propagate given values, so they are associated to the points in \(\pmb{X}\).
Propagating can be seen as a pseudo-injective map. Clearly, when \(R<m\), there is no injective map between \(\mathcal{R}\) and \(\pmb{X}\) because a single point in \(\mathcal{R}\) can correspond to more than one point in \(\pmb{X}\). However, when propagating, each point in \(\mathcal{R}\) can be associated to each corresponding point in \(\pmb{X}\) thanks to the \(\pmb{N}\) matrix.
More concretely, propagating values can be seen as a map that transforms the given sequence of values \(v_1, \ldots, v_{R_p}\), where \(R_p \leq R\) is the number of non-empty rows in \(\pmb{N}\). Note a row i is said to be empty when \(n_{ij} = -1, \forall 1 \leq j \leq R^*\). The output of the transformation is the sequence of values \(y_1, \ldots, y_m\) such that \(y_i = v_j\), satisfying the point i in \(\pmb{X}\) corresponds to the non-empty cell j in \(\mathcal{R}\).
- Parameters:
v (list) – The values to be propagated. There must be one value per non-empty cell in the receptive field. The values must preserve the order of the non-empty cells. In other words, \(v_j\) must either belong to the cell \(j\) or the cell \(j+k\) where k is the number of empty cells with index \(<j\).
safe (bool) – True to compute the propagation in safe mode, i.e., raising an exception when there are NaN in the propagation. False otherwise.
- Returns:
The output as a matrix when there are more than two values per point or the output as a vector when there is one value per point.
- Return type:
np.ndarray
- reduce_values(X, v, reduce_f=<function mean>, fill_nan=False)
Let \(\pmb{X} \in \mathbb{R}^{R \times n}\) be the matrix of row-wise points such that the row i is the centroid that represents the cell i in the receptive field. Let \(\pmb{v} \in \mathbb{K}^{m}\) be a vector that must be reduced to the receptive field to produce \(\pmb{y} \in \mathbb{K}^{R}\).
For a given reduce function \(f\) that maps an arbitrary number of input values to a single value, let \(u\) represent its input. Note that \(u\) represents any vector whose components are a subset of the set of components defining the vector \(v\). For then, the
reduce_values()procedure can be expressed as \(y_{i} = f(u_i)\).It might happen that some cells are empty and thus, no value is assigned to them during reduction. In those cases, it is possible to apply a filling rule that consists of assuming each empty cell has a value equal to that of its closest neighbor.
- Parameters:
X (
np.ndarray) – The centroid representing each cell in matrix form. Each row i of X represents the centroid of a cell i from the receptive field.v – The vector of values to reduce. The \(m\) input components will be reduced to \(R\) output components.
reduce_f (callable) – The function to reduce many values to a single one. By default, it is mean.
fill_nan (bool) – True to fill NaN values with the value of the closest non-empty cell in the receptive field.
- Returns:
The reduced vector.
- Return type:
np.ndarray
- shadow_indexing_matrix_from_points(X)
Compute the indexing matrix (supporting shadow indices) \(\pmb{N} \in \mathbb{Z}_{\geq -1}^{R \times R^*}\) from the given points \(\pmb{X} \in \mathbb{R}^{m \times n}\).
In this function, the points in \(\pmb{X}\) are assumed to be expressed in the internal reference system of the receptive field. In other words, the points must have been translated to the origin and scaled so the considered interval for each axis is \([-1, 1]\) instead of the defined by the original units of the boundary radii.
First, the dimensional factors \(f_1, \ldots, f_n\) are computed such that \(f_1 = 1\) and \(f_{i>1} = f_{i-1} \left\lceil\dfrac{2}{s_{i-1}}\right\rceil\).
Then, the point-wise indices \(i_1, \ldots, i_m\) can be computed such that:
\[i_j = \sum_{k=1}^{n}{\min \biggl\{{ f_k \biggl( \biggl\lfloor{\dfrac{2}{s_k}}\biggr\rfloor - 1 \biggr), f_k \biggl\lfloor{{ \dfrac{x_{jk}+1}{s_k} }\biggr\rfloor} }\biggr\}}\]The previous computation guarantees that extreme points, as the maximum vertex of the axis aligned bounding box containing the point cloud, are assigned to a proper cell. In other words, they are associated to an index inside the boundaries of the indexing space, i.e., no greater than the greatest supported index.
Now, since the \(i_1, \ldots, i_m\) indices are computed, it is known that the point \(j\) must be represented in the \(i_j\) row of matrix \(\pmb{N}\). Consequently, there must be one component of row \(\pmb{n}_{i_j}\), namely \(\pmb{n}_{i_jk}\), such that \(\pmb{n}_{i_jk} = j\). And thus, the matrix \(\pmb{N} \in \mathbb{Z}_{\geq -1}^{R \times R^*}\) is built.
- Parameters:
X – The matrix representing the m input points to build the indexing matrix. The points must have been centered and scaled, so they are expressed in the internal reference system of the receptive field. See
receptive_field_gs.ReceptiveFieldGS.center_and_scale()for more information.- Returns:
The built indexing matrix.
- Return type:
np.ndarray
- center_and_scale(X)
Let \(\pmb{o}\) be the origin of the receptive field (also referred to as center point), and \(\pmb{r}\) be the bounding radii vector.
Any row in \(\pmb{X}\) is assumed to represent a point in the canonical reference system. Thus, it is possible to obtain a matrix \(\pmb{Y}\) which rows are the points in \(\pmb{X}\) transformed to the internal reference system of the receptive field. Each point in this matrix can be computed as:
\[\pmb{y}_{i*} = \left[\begin{array}{ccc} \dfrac{x_{i1} - o_1}{r_1} & \cdots & \dfrac{x_{in} - o_n}{r_n} \end{array}\right]\]- Parameters:
X (
np.ndarray) – The matrix of points to be transformed.- Returns:
The matrix of transformed points.
- Return type:
np.ndarray
- undo_center_and_scale(X)
The inverse transform of the
receptive_field_gs.ReceptiveFieldGS.center_and_scale()method.\[\pmb{x}_{i*} = \left[\begin{array}{ccc} r_1 x_{i1} + o_1 & \cdots & r_n x_{in} + o_n \end{array}\right]\]- Parameters:
X (
np.ndarray) – The matrix of transformed points to be transformed back to their original representations.- Returns:
The matrix of points after reversing the transformation.
- Return type:
np.ndarray
- get_center_of_empty_cells(missing_indices=None)
Obtain the center point (computed as the midrange) for each empty cell.
- Parameters:
missing_indices – The indices of empty cells. It can be None, in that case it will be computed internally.
- Returns:
Matrix of geometric centers, one row per empty cell.
- Return type:
np.ndarray
- static num_cells_from_cell_size(cell_size)
Compute the number of cells for a receptive field defined by the given cell size.
- Parameters:
cell_size – The cell size for which the number of cells must be computed. See
ReceptiveFieldGSfor further details.- Returns:
The number of cells composing the receptive field.
- Return type:
int
- canibalize(rf)