fovi.arch.pooling
Retinal pooling: 2D windows for _as_grid sensors, KNN for sample sets.
- class fovi.arch.pooling.SamplingCoords(fov, cmf_a, res, device='cpu', style='isotropic', dtype=torch.float, max_val=1, isotropic_plotting_type='v1like', fov_type='circular', field_geometry='planar', radius_norm=2.0)[source]
Bases:
objectObject for storing multiple coordinate systems relevant to a set of visual field samples.
- Parameters:
fov (float) – Field-of-view in degrees.
cmf_a (float) – A parameter from the CMF: M(r)=1/(r+a). Smaller a = stronger foveation.
res (int) – Resolution, corresponding to the side length of a cartesian grid or the number of radii in polar (before any adjustments are made to match a target cartesian grid).
device (str) – What device to operate on.
style (str) – What type of sampling.
dtype (torch.dtype) – What data type to use.
fov_type (str) – One of
'circular','square', or'wang'. The last is only valid for warped Cartesian sensor styles.radius_norm (float) – Norm measuring native-plane radius for warped Cartesian styles.
2.0gives circular iso-eccentricity shells;infgives square shells, which pair withfov_type='square'to retain every cell.
- __init__(fov, cmf_a, res, device='cpu', style='isotropic', dtype=torch.float, max_val=1, isotropic_plotting_type='v1like', fov_type='circular', field_geometry='planar', radius_norm=2.0)[source]
- as_grid(values: Tensor, sample_dim: int = -1) Tensor[source]
Replace a canonical sample axis with the sensor’s image axes.
Cartesian grids return upright rows down and columns right. Log-polar grids retain their radius/angle ordering. Other axes are unchanged.
- Parameters:
values – Tensor with one axis containing all canonical samples.
sample_dim – Sample axis; use zero for coordinates shaped (N, 2).
- Returns:
Tensor with the sample axis replaced by height and width.
- native_to_visual(coordinates: Tensor) Tensor[source]
Map (…, 2) native Cartesian warp coordinates to the visual chart.
Visual chart radius one is half the configured FoV. For spherical geometry this is angular eccentricity, not a pinhole projection. The unbounded chart includes masked cells outside the model footprint; renderers must handle their own angular padding domain.
- visual_to_native(coordinates: Tensor) Tensor[source]
Map (…, 2) normalized visual-chart positions to the native grid.
- pad_cartesian(padding_distance=0.5, device=None, dtype=None)[source]
Generate additional cartesian coordinates for padding around the sampling grid.
- Parameters:
padding_distance (float) – Padding extent in normalized coordinates. For spherical radial grids, measured from the real retinal rim, retaining at least one complete neighboring ring. Planar/legacy radial grids retain the historical interval starting at the first outer ring, which can overshoot the requested rim margin by one ring. Preserve that behavior for checkpoint KNN compatibility. Warped Cartesian and log-polar layouts pad in their own grid coordinates using a whole number of grid intervals.
device (str, optional) – Device to place the coordinates on. Defaults to None.
dtype (torch.dtype, optional) – Data type for the coordinates. Defaults to None.
- Returns:
Additional cartesian coordinates for padding.
- Return type:
- get_strided_coords(stride, auto_match_cart_resources=0, in_cart_res=None, force_less_than=True, max_val=1)[source]
Return a strided version of the coordinates.
- Parameters:
stride (int) – Stride factor for downsampling coordinates.
auto_match_cart_resources (int) – Automatic matching parameter for cartesian resources.
in_cart_res (int, optional) – Input cartesian resolution. Required for ‘fixn’ style.
force_less_than (bool, optional) – Whether to force less than target resolution. Defaults to True.
max_val (float, optional) – Maximum value for coordinates. Defaults to 1.
- Returns:
- A tuple containing:
SamplingCoords: New SamplingCoords object with strided coordinates.
int: Number of output radii.
int: Corresponding output cartesian resolution.
- Return type:
- to(device=None, dtype=None)[source]
Move the SamplingCoords object to a different device and/or change data type.
- Parameters:
device (str, optional) – Target device. Defaults to None.
dtype (torch.dtype, optional) – Target data type. Defaults to None.
- Returns:
SamplingCoords object on the specified device/dtype.
- Return type:
- get_scatter_sizes()[source]
Calculate approximate size to be used for plotting in scatter plots.
Scales linearly with eccentricity, as occurs in KNN-sampling of the sensor manifold. However, this is not precisely tuned to the particular warping parameters.
- Returns:
Receptive field sizes for each sampling point.
- Return type:
- clone(fov=None, cmf_a=None, resolution=None, device=None, style=None, dtype=None, max_val=None, isotropic_plotting_type=None, fov_type=None, field_geometry=None, radius_norm=None)[source]
Return a deep copy of the SamplingCoords object with optional parameter overrides.
- Parameters:
fov (float, optional) – Field-of-view in degrees. Defaults to current value.
cmf_a (float, optional) – A parameter from the CMF. Defaults to current value.
resolution (int, optional) – Resolution parameter. Defaults to current value.
device (str, optional) – Device to place coordinates on. Defaults to current value.
style (str, optional) – Sampling style. Defaults to current value.
dtype (torch.dtype, optional) – Data type. Defaults to current value.
max_val (float, optional) – Maximum coordinate value. Defaults to current value.
- Returns:
A new SamplingCoords object with the specified parameters.
- Return type:
- class fovi.arch.pooling.KNNPoolingLayer(k, in_coords, out_coords, mode='max', device='cuda', sample_cortex=True, gauss_sigma=10, batch_size=None)[source]
Bases:
Module,KNNBaseLayerK-Nearest Neighbors pooling layer for foveated vision.
This layer performs pooling operations over k-nearest neighbors in either visual or cortical space, supporting various pooling modes.
- Parameters:
k (int) – Number of nearest neighbors to consider.
in_coords (SamplingCoords) – Input sampling coordinates object.
out_coords (SamplingCoords) – Output sampling coordinates object.
mode (str) – Pooling mode (‘max’, ‘avg’, ‘sum’, ‘gaussian’).
device (str) – PyTorch device to run on.
sample_cortex (bool or str) – Whether/how to sample cortical space: - False: Sample visual field - True: Sample cortical space using Euclidean distances (fast, approximate) - ‘geodesic’: Sample cortical space using geodesic distances (slower, more accurate)
gauss_sigma (float) – sigma for mode=’gaussian’ pooling; not used for other modes
batch_size (int, optional) – Number of output coordinates to process at once for memory efficiency. If None, uses a default based on available memory.
- __init__(k, in_coords, out_coords, mode='max', device='cuda', sample_cortex=True, gauss_sigma=10, batch_size=None)[source]
Initialize internal Module state, shared by both nn.Module and ScriptModule.
- _compute_knns(batch_size: int | None = None) tuple[Tensor, Tensor][source]
Query native 2-D pooling neighborhoods without an all-pairs matrix.
The CPU tree is used only during construction. Masked cells and spatial padding remain candidates so boundary receptive fields do not stretch. As with topk, equally distant candidates at the cutoff may be tied.
- _compute_gaussian_weights()[source]
Compute Gaussian weights for local pooling based on distances between output nodes and their input neighbors.
- Returns:
Gaussian weights of shape (k, num_output_nodes)
- Return type:
- forward(X_l)[source]
Apply KNN pooling to input features.
- Parameters:
X_l (torch.Tensor) – Input features of shape [batch_size, channels, num_nodes].
- Returns:
Pooled features of shape [batch_size, channels, num_output_nodes].
- Return type:
- class fovi.arch.pooling.GridPoolingLayer(k: int | None, in_coords: SamplingCoords, out_coords: SamplingCoords, mode: str = 'avg', gauss_sigma: float = 10.0)[source]
Bases:
ModuleMask-normalized pooling between aligned
_as_gridsensor images.Inputs and outputs use canonical
(B, C, N)sample ordering. Pooling operates on the sensor image (upright for Cartesian grids, angle x eccentricity for log-polar grids) with stride equal to the integer resolution ratio.kis the neighborhood size (squared kernel side), matching KNN pooling’s neighbor count; None uses the squared ratio.Spatial axes use SAME-style padding: symmetric windows when kernel and stride have matching parity, otherwise the window sits half a sample toward larger indices; kernels smaller than the stride crop the margins. Padding is excluded from the normalization like masked retinal units. Polar grids pad the angular axis circularly (as
PolarPadder), centering each window on its output angle, which coincides with high-res anglei * stride. Their eccentricity axis keeps the spatial convention; because log-polar radii include both endpoints at every resolution, windows there are index-aligned rather than centered on output radii. Gaussian sigma uses distances normalized to [0, 1], as in KNN pooling.- __init__(k: int | None, in_coords: SamplingCoords, out_coords: SamplingCoords, mode: str = 'avg', gauss_sigma: float = 10.0) None[source]
Initialize internal Module state, shared by both nn.Module and ScriptModule.
- fovi.arch.pooling.build_retinal_pooler(in_coords: SamplingCoords, out_coords: SamplingCoords, *, k: int | None, mode: str, sample_cortex: bool | str, gauss_sigma: float, device: str | device) tuple[KNNPoolingLayer | GridPoolingLayer, int][source]
Build a retinal pooler and return its resolved neighbor count.
_as_gridsensors always use 2D grid pooling; sample sets use KNN.