Parameter Sources¶
quivers.continuous.param_source provides the map from a conditional
family's input to its distribution parameters. A morphism declared
~ Family over a continuous domain is a Kleisli arrow whose
parameters are produced by a ParamSource, so the source is where a
kernel's dependence on its input is computed, and where any
nonlinearity in that dependence lives.
The concrete sources cover the standard architectures: LinearSource
is a single nn.Linear; MLPSource is a multi-layer perceptron with
configurable widths and activation; AttentionSource is a
self-attention head; LookupSource and EmbeddingSource handle
discrete domains; IdentitySource, FunctionSource, and
ComposeSource cover pass-through, a fixed callable, and composition
of two sources.
make_param_source is the factory the families call, and
param_source_from_option parses the DSL's [param_source=<kind>]
morphism option. The default for a continuous domain is LinearSource,
so a kernel is linear unless it asks for something else; a SetObject
domain always uses LookupSource regardless of the requested kind. The
Bayesian Neural Network example selects the
MLP source explicitly and relies on it for its nonlinearity.
The hidden widths come either from the option's arguments or from
hidden_dim, one width per hidden layer:
morphism f : X -> Y [param_source=mlp] ~ Normal # (64, 64)
morphism f : X -> Y [param_source=mlp(64, 32)] ~ Normal # (64, 32)
morphism f : X -> Y [param_source=mlp, hidden_dim=[64, 32]] ~ Normal # (64, 32)
morphism f : X -> Y [param_source=mlp, hidden_dim=64] ~ Normal # (64,)
A width given to a source with no hidden layers to apply it to is an
error rather than a silent no-op, and so is param_source on a family
whose parameters do not come from a source at all (Horseshoe,
GaussianProcess, Independent, Transformed).
param_source
¶
Pluggable parameter sources for conditional distribution families.
A ParamSource
produces a (batch, param_dim) tensor from a per-row input. Every
ConditionalX family in
quivers.continuous.families uses
one to convert its input into the flattened parameter vector its
underlying distribution needs.
The primitives:
LinearSource: the default; onenn.Linear, no nonlinearity. Matches the single-linear layer the transpile backends emit exactly, so a kernel morphism on this source is numerically equivalent to its transpiled counterpart.MLPSource: a multi-layer perceptron with user-configurable hidden widths and activation. Selected by[param_source=mlp]; a kernel is linear unless it asks for this.LookupSource: a learnable per-entry embedding table, the discrete-domain standard.EmbeddingSource: an embedding table piped through a downstreamParamSource(embedding + MLP head, the standard categorical-input pattern).AttentionSource: single-head self-attention over the input dimension, a useful primitive for set-valued inputs.IdentitySource: pass the input through unchanged (parameters supplied as data).FunctionSource: wraps an arbitraryCallable, letting a user drop in anynn.Modulewithout subclassing.ComposeSource: categorical composition of two param sources, useful for building sequential architectures out of primitives.
The DSL surface accepts a [param_source=...] option on
morphism declarations, with the hidden widths given either as the
option's arguments or through hidden_dim:
morphism trans : State -> State [param_source=linear] ~ Normal
morphism trans : State -> State [param_source=mlp] ~ Normal
morphism trans : State -> State [param_source=mlp(64, 64)] ~ Normal
morphism trans : State -> State [param_source=mlp, hidden_dim=[64, 32]] ~ Normal
One width per hidden layer, so the sequence says how many as well as
how wide; a bare hidden_dim=64 is the one-layer case. The call form
is parsed by
param_source_from_option.
ParamSource
¶
Bases: Module, ABC
A learnable map from per-row input to a flat parameter vector.
Every conditional distribution family holds a ParamSource
instance and defers its parameter computation to it. Subclasses
override forward and declare param_dim.
LinearSource
¶
LinearSource(domain_dim: int, param_dim: int, bias: bool = True)
Bases: ParamSource
Single nn.Linear(domain_dim, param_dim); no nonlinearity.
This is the parameter source that matches the transpile
backends' emit: the DSL morphism f : A -> B [role=kernel] ~
Family lowers to a single linear layer Family(loc = W x, ...)
on every backend. Configuring a runtime kernel with
LinearSource(...) makes the runtime numerically equivalent to
its transpiled counterpart.
Source code in src/quivers/continuous/param_source.py
96 97 98 99 100 | |
MLPSource
¶
MLPSource(domain_dim: int, param_dim: int, hidden_dims: Sequence[int] = (64, 64), activation: type[Module] = Tanh, bias: bool = True)
Bases: ParamSource
Multi-layer perceptron with configurable hidden widths and
activation. The default hidden_dims=(64, 64) yields a
two-hidden-layer, tanh-activated network; a user who wants a
wider, deeper, or differently-activated network drops in the
same constructor.
Source code in src/quivers/continuous/param_source.py
120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 | |
LookupSource
¶
LookupSource(n_entries: int, param_dim: int)
Bases: ParamSource
Per-entry learnable parameter table indexed by an integer
input. The categorical / discrete-input parameter source: the
input is a LongTensor of category indices, the output is the
per-index parameter vector.
Source code in src/quivers/continuous/param_source.py
156 157 158 159 160 | |
EmbeddingSource
¶
EmbeddingSource(n_entries: int, embed_dim: int, head: ParamSource)
Bases: ParamSource
Embedding table followed by a downstream ParamSource. The
canonical embedding + MLP head pattern: categorical inputs pass
through an nn.Embedding and the resulting dense vector feeds a
user-supplied head (linear, MLP, or attention).
Source code in src/quivers/continuous/param_source.py
178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 | |
AttentionSource
¶
AttentionSource(domain_dim: int, param_dim: int, num_heads: int = 4, bias: bool = True)
Bases: ParamSource
Single-head self-attention over the input feature dimension, followed by an aggregation and a linear head. Useful when the input is a set of features whose ordering carries no information and the model should be permutation-equivariant.
For a (batch, seq_len, domain_dim) input, computes
scaled-dot-product attention across the sequence dimension,
aggregates via mean-pool, and projects to param_dim via a
linear head. When the input is (batch, domain_dim), treats it
as a length-one sequence.
Source code in src/quivers/continuous/param_source.py
217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 | |
IdentitySource
¶
IdentitySource(param_dim: int)
Bases: ParamSource
Passes the input through unchanged. Useful when parameters
come directly from the host (e.g. a design matrix or an already-
computed feature vector) and no further transformation is
needed. param_dim equals the input's last-axis size and must
be declared at construction.
Source code in src/quivers/continuous/param_source.py
257 258 259 | |
FunctionSource
¶
FunctionSource(fn: Callable[[Tensor], Tensor], param_dim: int)
Bases: ParamSource
Wraps an arbitrary nn.Module or callable as a ParamSource.
The user supplies the module and declares its output dim; the
machinery around conditional families sees a uniform interface.
Source code in src/quivers/continuous/param_source.py
277 278 279 280 281 282 283 284 285 | |
ComposeSource
¶
ComposeSource(outer: ParamSource, inner: ParamSource)
Bases: ParamSource
Categorical composition of two param sources: outer(inner(x)).
inner.param_dim must equal outer._domain_dim. Enables
building sequential architectures from primitives (e.g.
Compose(MLPSource(...), LinearSource(...))).
Source code in src/quivers/continuous/param_source.py
305 306 307 308 309 310 311 312 313 314 | |
make_param_source
¶
make_param_source(domain: AnySpace, param_dim: int, kind: str = _DEFAULT_SOURCE_KIND, **kwargs) -> ParamSource
Factory that dispatches the [param_source=...] DSL option
to the concrete class.
The default is LinearSource, so a morphism declared
f : X -> Y ~ Normal maps its input to the family's parameters
the way its arrow reads: linearly. A model that wants a
nonlinearity between its input and its parameters asks for one,
and the fact then appears in the source rather than in a default.
Recognised kinds:
* "lookup" — always used when the domain is a SetObject,
regardless of the requested kind.
* "linear" — the default; one nn.Linear.
* "mlp" — hidden_dims=(64, 64) unless overridden by
hidden_dims or hidden_dim kwargs.
* "identity" — pass through.
* "attention" — self-attention head.
Source code in src/quivers/continuous/param_source.py
359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 | |
param_source_from_option
¶
param_source_from_option(domain: AnySpace, param_dim: int, option_value: str | None) -> ParamSource
Parse a [param_source=...] option string into a
ParamSource. Accepts:
"mlp","linear","identity","attention""mlp(64, 64)"— parenthesised hidden widths"mlp(32)"— single hidden width"attention(heads=4)"— keyword-only options
Unrecognised syntax raises ValueError so parse errors surface
at compile time rather than as silent identity fallthrough.
Source code in src/quivers/continuous/param_source.py
453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 | |