src.model.deeplearn.layer.upsampling_spconv3d_layer
Classes
|
- class src.model.deeplearn.layer.upsampling_spconv3d_layer.UpsamplingSpConv3DLayer(*args, **kwargs)
- Author:
Alberto M. Esmoris Pena
Upsampling sparse 3D convolution from hierarchy depth \(t + 1\) to depth \(t\), driven by a dense upsampling neighbor table emitted by the C++ pre-processor and concatenated across receptive fields by
DLSparseConcatSequencer.The layer’s call expects two inputs:
\(\pmb{F} \in \mathbb{R}^{(1 + R_{t+1}) \times n_f}\) — the concatenated per-cell features at depth \(t + 1\), with row 0 reserved as the shared ground row.
\(\pmb{U} \in \mathbb{Z}^{(1 + R_t) \times w_U^3}\) — the upsampling neighbor table. Row 0 is the ground marker. Row \(v \in [1, R_t]\) contains the one-based indices in depth-\((t + 1)\) row space of the cells in the \(w_U^3\)-cell upsampling window whose min vertex is the \(v\)-th active cell at depth \(t\). Entries equal to 0 mark inactive neighbors.
The convolution is:
\[\pmb{G}_{v*} = \sum_{p = 0}^{w_U^3 - 1} \pmb{F}_{\pmb{U}_{v p} *} \pmb{W}_{p}\]Implemented as
tf.einsum('ijk,jkm->im', tf.gather(F, U[1:]), W), binding the kernel-position axisjbetween gathered features and weights so each kernel position has its own weight slice.- Variables:
wU (int) – Full upsampling window edge length. The window covers \(w_U^3\) cells.
f (int) – Number of convolutional filters / kernel positions. Equals \(w_U^3\) by construction.
nf (int) – Input feature dimension at depth \(t + 1\).
ng (int) – Output feature dimension at depth \(t\).
W (
tf.Variable) – Kernel of shape \((f, n_f, n_g)\).
- __init__(wU, f, nf, ng, built_W=False, W_initializer=None, W_regularizer=None, W_constraint=None, **kwargs)
See
Layerandlayer.Layer.__init__().
- build(dim_in)
Build the convolutional kernel weights.
- call(inputs, training=False, mask=False)
Apply the upsampling convolution.
- Parameters:
inputs –
inputs[0]is \(\pmb{F}\);inputs[1]is the upsampling neighbor table \(\pmb{U}\).- Returns:
(1 + R_t, n_g)tensor with row 0 reserved as the ground row and rows \(v \in [1, R_t]\) holding the convolved features at depth \(t\).- Return type:
tf.Tensor
- static up_spconv3d_on_elem(F, U_active, W)
Pad-based variant of the upsampling convolution.
- Parameters:
F – Padded depth-\(t + 1\) features
(1 + R_{t+1}, n_f)— ground row at index 0.U_active – Upsampling neighbor index table
(R_t, w_U^3)with values in[0, R_{t+1}]; value 0 fetches the ground row.W – Kernel
(w_U^3, n_f, n_g).
- Returns:
(R_t, n_g)— no ground row.
- static up_spconv3d_on_elem_active(F_active, U_active, W)
Active-form variant. See
SubmanifoldSpConv3DLayer.spconv3d_on_elem_active()for the equivalence proof.- Parameters:
F_active – Depth-\(t + 1\) features
(R_{t+1}, n_f)— no ground row.U_active – Upsampling neighbor index table
(R_t, w_U^3)with values in[0, R_{t+1}]; 0 is the “missing neighbor” sentinel.W – Kernel
(w_U^3, n_f, n_g).
- Returns:
(R_t, n_g).
The underlying matmul is the reshape-then-matmul form so cuBLAS receives a clean GEMM rather than the
Reshape → Transpose → BatchMatMul → Reshapechain thattf.einsumwould lower to.
- static up_spconv3d_on_idx_real(F_active, idx, real, W)
Variant of
up_spconv3d_on_elem_active()taking pre-resolvedidxandreal. SeeSubmanifoldSpConv3DLayer.spconv3d_on_idx_real()for the rationale.The
(idx_U, real_U)cache is per-table:Uhas a different shape (R_trows,wU^nxcolumns) and different contents from the submanifoldS_active, so it cannot be shared with the submanifold path. Feeding submanifold’s(idx_S, real_S)into this kernel would index the wrong space and silently corrupt the upsampling output.
- get_config()
Return necessary data to serialize the layer.