data
NeuralODEConfig
extends
NormalizingFlowConfigNeuralODEConfig(sample_size: int | tuple[int, int] = 32, in_channels: int = 3, out_channels: int = 3, act_fn: GenerativeActivation = 'silu', prior: FlowPrior = 'gaussian', field: VectorFieldKind = 'planar', hidden_dim: int = 64, num_blocks: int = 2, solver: str = 'dopri5', rtol: float = 1e-05, atol: float = 1e-05, use_adjoint: bool = True, trace_method: TraceMethod | None = None, trace_noise: TraceNoise = 'rademacher', exact_trace_max_dim: int = 32)Frozen configuration for every Neural ODE (CNF) variant.
Parameters
sample_sizeint or tuple of int= 32Spatial resolution of a sample. The flow itself is defined on the
flattened vector, so this and
in_channels only fix its width.in_channelsint= 3Channels per sample.
out_channelsint= 3Kept equal to
in_channels: the flow is a bijection, so it
cannot change the dimension it acts on.act_fn(silu, swish, relu, gelu)= "silu"Activation between the vector field's gated blocks. A smooth one
is worth preferring here for a reason that does not apply to a
discrete flow: the solver estimates its own error from how
polynomial the trajectory looks locally, so a kinked right-hand
side costs steps.
prior(logistic, gaussian)= "logistic"Base distribution the latent is measured against. Unlike the
discrete flows, which use a logistic prior on dequantised pixels,
the continuous flow integrates to a standard normal.
hidden_dimint= 64Width of each function in the gated sum — the paper's CNF
experiments use
64.num_blocksint= 2How many gated blocks the vector field stacks.
solverstr= "dopri5"Method name handed to
lucid.diffeq.odeint. Any adaptive
method works; the fixed-step ones trade accuracy for a predictable
cost per sample.rtolfloat= 1e-5, 1e-5Solver tolerances. Looser than the
lucid.diffeq defaults on
purpose: the flow is trained, so solving it to twelve digits buys
nothing the gradient can use.atolfloat= 1e-5, 1e-5Solver tolerances. Looser than the
lucid.diffeq defaults on
purpose: the flow is trained, so solving it to twelve digits buys
nothing the gradient can use.use_adjointbool= TrueIntegrate the backward pass with
lucid.diffeq.odeint_adjoint
rather than differentiating through the solver's own steps. This is
the paper's constant-memory result; turning it off costs memory
proportional to the number of steps taken but gives gradients that
are exact for the discretisation actually used.trace_method(exact, hutchinson)= "exact"How the divergence is obtained.
None picks by dimension —
exact below exact_trace_max_dim, Hutchinson above it — so the
default is the paper's method exactly where the paper's method is
affordable.trace_noise(rademacher, gaussian)= "rademacher"Probe distribution for the Hutchinson estimate.
exact_trace_max_dimint= 32Dimension below which
trace_method=None resolves to "exact".Notes
in_channels and out_channels must agree: a flow is a bijection.
Examples
>>> from lucid.models.generative.neural_ode import NeuralODEConfig
>>> NeuralODEConfig().hidden_dim
64
>>> NeuralODEConfig(sample_size=(1, 2), in_channels=1,
... out_channels=1).data_dim
2Used by 3
Constructors
1dunder
__init__
→None__init__(sample_size: int | tuple[int, int] = 32, in_channels: int = 3, out_channels: int = 3, act_fn: GenerativeActivation = 'silu', prior: FlowPrior = 'gaussian', field: VectorFieldKind = 'planar', hidden_dim: int = 64, num_blocks: int = 2, solver: str = 'dopri5', rtol: float = 1e-05, atol: float = 1e-05, use_adjoint: bool = True, trace_method: TraceMethod | None = None, trace_noise: TraceNoise = 'rademacher', exact_trace_max_dim: int = 32)Properties
2int: Flattened width of one sample, the dimension the flow acts on.
TraceMethod: trace_method, or the one implied by the dimension.
Exact where exact is affordable and Hutchinson where it is not, so that the default reproduces the paper at the paper's scale without making the same choice unusable at image scale.