Kernel Adaptive Gaussian#
adaptive_gaussian
#
| CLASS | DESCRIPTION |
|---|---|
AdaptiveGaussianKernel |
Adaptive Gaussian kernel with neural network-based bandwidth prediction. |
| FUNCTION | DESCRIPTION |
|---|---|
adaptive_gaussian_kernel |
Compute adaptive Gaussian kernel from distance matrix (functional interface). |
Classes#
AdaptiveGaussianKernel(bandwidth_network: torch.nn.Module, prediction_mode: str = 'sample', normalization: KernelNormalizer | str | dict | None = None, dtype: torch.dtype = torch.float32)
#
Bases: Kernel
Adaptive Gaussian kernel with neural network-based bandwidth prediction.
Implements a data-adaptive Gaussian kernel where the bandwidth is predicted by a neural network from the distance matrix. This enables the kernel to learn optimal, sample-specific bandwidths during training based on the pairwise distance structure.
The kernel form is: \(K(d_{kl}) = \exp(-d_{kl}^2 / \sigma_{kl}^2)\), but now \(\sigma_{kl}\) is predicted by a neural network from the distance matrix rather than being fixed or estimated via heuristics.
| PARAMETER | DESCRIPTION |
|---|---|
bandwidth_network
|
Neural network that predicts bandwidth from distance matrix. Expected input/output shapes depend on
TYPE:
|
prediction_mode
|
Mode for bandwidth prediction.
TYPE:
|
normalization
|
Kernel normalization.
TYPE:
|
dtype
|
Data type for tensors.
TYPE:
|
| ATTRIBUTE | DESCRIPTION |
|---|---|
bandwidth_network |
The neural network used for bandwidth prediction.
TYPE:
|
prediction_mode |
The bandwidth prediction mode being used.
TYPE:
|
bw |
Predicted squared bandwidth matrix with shape matching the input distance matrix. Set after each forward pass.
TYPE:
|
Examples:
Basic usage with sample-wise bandwidth prediction:
>>> import torch
>>> from spectre.kernel import AdaptiveGaussianKernel
>>>
>>> # Define a bandwidth predictor network that takes distance matrix
>>> # and outputs per-sample bandwidth
>>> class SampleBandwidthNet(torch.nn.Module):
... def __init__(self):
... super().__init__()
... self.net = torch.nn.Sequential(
... torch.nn.Linear(1, 10),
... torch.nn.ReLU(),
... torch.nn.Linear(10, 1),
... torch.nn.Softplus(), # Ensure positive output
... )
...
... def forward(self, D):
... # Use mean distance per sample as feature
... features = D.mean(dim=1, keepdim=True)
... return self.net(features).squeeze(-1)
>>>
>>> bandwidth_net = SampleBandwidthNet()
>>>
>>> # Create adaptive kernel
>>> kernel = AdaptiveGaussianKernel(
... bandwidth_network=bandwidth_net,
... prediction_mode="sample",
... )
>>>
>>> # Compute distances (from any source)
>>> X = torch.randn(100, 10)
>>> D = torch.cdist(X, X, p=2)
>>>
>>> # Apply kernel (only needs D)
>>> K = kernel(D)
>>> K.shape
torch.Size([100, 100])
Scalar bandwidth mode (single bandwidth for entire matrix):
>>> class ScalarBandwidthNet(torch.nn.Module):
... def __init__(self):
... super().__init__()
... self.net = torch.nn.Sequential(
... torch.nn.Linear(1, 10),
... torch.nn.ReLU(),
... torch.nn.Linear(10, 1),
... torch.nn.Softplus(), # Ensure positive output
... )
...
... def forward(self, D):
... # Use median distance as feature
... median_dist = D.median().unsqueeze(0)
... return self.net(median_dist)
>>>
>>> kernel = AdaptiveGaussianKernel(
... bandwidth_network=ScalarBandwidthNet(),
... prediction_mode="scalar",
... )
>>> K = kernel(D)
With normalization:
>>> from spectre.kernel import KernelNormalizer
>>> normalization = KernelNormalizer(norm_type="markov_symmetric")
>>> kernel = AdaptiveGaussianKernel(
... bandwidth_network=bandwidth_net,
... normalization=normalization,
... )
>>> K_normalized = kernel(D)
Integration with SpectralMap for end-to-end learning:
>>> from spectre.parametric import SpectralMap
>>> from spectre.kernel import AdaptiveGaussianKernel
>>>
>>> # Encoder network
>>> encoder = torch.nn.Sequential(
... torch.nn.Linear(10, 20),
... torch.nn.ReLU(),
... torch.nn.Linear(20, 3),
... )
>>>
>>> # Bandwidth predictor learns from latent space distances
>>> class LatentBandwidthNet(torch.nn.Module):
... def __init__(self):
... super().__init__()
... self.net = torch.nn.Sequential(
... torch.nn.Linear(1, 10),
... torch.nn.ReLU(),
... torch.nn.Linear(10, 1),
... torch.nn.Softplus(), # Ensure positive output
... )
...
... def forward(self, D):
... features = D.mean(dim=1, keepdim=True)
... return self.net(features).squeeze(-1)
>>>
>>> kernel = AdaptiveGaussianKernel(bandwidth_network=LatentBandwidthNet())
>>>
>>> # SpectralMap computes distances in latent space and passes to kernel
>>> spectral_map = SpectralMap(model=encoder, kernel_fn=kernel, n_states=3)
>>>
>>> # Train - kernel learns optimal bandwidth from distance patterns
>>> spectral_map.fit(data, n_epochs=100)
Notes
- The bandwidth network should output positive values (use Softplus, ReLU, or exponential activation)
- The network can use any features derived from the distance matrix (e.g., row means, medians, quantiles, k-NN distances)
| METHOD | DESCRIPTION |
|---|---|
forward_step |
Compute adaptive Gaussian kernel matrix. |
get_kernel_params |
Return current predicted bandwidth from last forward pass. |
Source code in spectre/kernel/adaptive_gaussian.py
Functions#
forward_step(D: torch.Tensor, weights: torch.Tensor | None = None, **kwargs) -> torch.Tensor
#
Compute adaptive Gaussian kernel matrix.
| PARAMETER | DESCRIPTION |
|---|---|
D
|
Pairwise distance matrix of shape (n_samples, n_samples).
TYPE:
|
weights
|
Sample weights (not used in bandwidth prediction, but may be used by normalization).
TYPE:
|
**kwargs
|
Additional keyword arguments passed to the kernel.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
Tensor
|
Adaptive Gaussian kernel matrix of shape (n_samples, n_samples). |
Notes
- Predicts bandwidth using
bandwidth_networkfrom distance matrixD - Computes kernel using predicted bandwidth
- Caches predicted squared bandwidth in
self.bw - Normalization is handled by parent
Kernel.forward()if specified
Source code in spectre/kernel/adaptive_gaussian.py
get_kernel_params() -> dict[str, torch.Tensor]
#
Return current predicted bandwidth from last forward pass.
Returns the actual bandwidth matrix used in kernel computation. This is the squared bandwidth matrix (σ²) from the most recent forward pass.
| RETURNS | DESCRIPTION |
|---|---|
dict[str, Tensor]
|
Dictionary with "bandwidth" key containing the predicted squared
bandwidth matrix from the last forward pass. Returns empty dict if
|
Examples:
>>> import torch
>>> from spectre.kernel import AdaptiveGaussianKernel
>>>
>>> class SimpleBandwidthNet(torch.nn.Module):
... def __init__(self):
... super().__init__()
... self.net = torch.nn.Sequential(
... torch.nn.Linear(1, 1),
... torch.nn.Softplus(),
... )
...
... def forward(self, D):
... features = D.mean(dim=1, keepdim=True)
... return self.net(features).squeeze(-1)
>>>
>>> kernel = AdaptiveGaussianKernel(bandwidth_network=SimpleBandwidthNet())
>>> D = torch.rand(50, 50)
>>> _ = kernel(D)
>>> params = kernel.get_kernel_params()
>>> params["bandwidth"].shape
torch.Size([50, 50])
Notes
The returned bandwidth is σ², not σ, representing the actual values used in the kernel computation: K = exp(-D²/σ²).
Source code in spectre/kernel/adaptive_gaussian.py
Functions#
adaptive_gaussian_kernel(D: torch.Tensor, bandwidth_network: torch.nn.Module, prediction_mode: str = 'sample') -> GaussianKernelResult
#
Compute adaptive Gaussian kernel from distance matrix (functional interface).
Pure function that computes an unnormalized adaptive Gaussian kernel where bandwidth is predicted by a neural network from the distance matrix.
For normalized kernels, use the :class:AdaptiveGaussianKernel class with
a normalization.
| PARAMETER | DESCRIPTION |
|---|---|
D
|
Pairwise distance matrix of shape (n_samples, n_samples).
TYPE:
|
bandwidth_network
|
Neural network that predicts bandwidth from distance matrix.
TYPE:
|
prediction_mode
|
Mode for bandwidth prediction.
TYPE:
|
dtype
|
Data type for tensors.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
GaussianKernelResult
|
NamedTuple containing:
|
Source code in spectre/kernel/adaptive_gaussian.py
300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 | |