max_unpool3d(x: Tensor, indices: Tensor, kernel_size: int | tuple[int, int, int], stride: int | tuple[int, int, int] | None = None, padding: int | tuple[int, int, int] = 0, output_size: tuple[int, ...] | None = None)Inverse of max_pool3d via scatter at saved argmax indices.
Volumetric version of max_unpool2d. Scatters the pooled
values back to their saved (D, H, W) positions (encoded as
flat D × H × W indices) on a zero canvas.
Parameters
Pooled values, shape
(N, C, D_in, H_in, W_in).indicesTensorFlattened argmax positions, same shape as
x.kernel_sizeint or (int, int, int)Original pooling window size.
strideint or (int, int, int)= NoneOriginal stride.
paddingint or (int, int, int)= 0Original padding.
output_sizetuple of int= NoneTarget spatial shape
(..., D_out, H_out, W_out). Defaults, as
the reference's does, to the shape pooling with these settings
shrinks to x's, (in - 1) * stride - 2 * padding + kernel_size per axis.Returns
TensorOutput of shape (N, C, D_out, H_out, W_out).
Notes
Implemented via scatter_add over a flattened spatial axis
(so the gradient flows back to x and indices is treated
as a non-differentiable lookup). See max_unpool1d for
the math.
Examples
>>> import lucid
>>> from lucid.nn.functional import max_pool3d, max_unpool3d
>>> x = lucid.randn(1, 1, 4, 4, 4)
>>> pooled, idx = max_pool3d(x, kernel_size=2, return_indices=True)
>>> y = max_unpool3d(pooled, idx, kernel_size=2, output_size=(4, 4, 4))
>>> y.shape
(1, 1, 4, 4, 4)