mixle.models.quotient module

A cyclic-translation quotient leaf and a capacity-matched position-sensitive baseline.

TranslationQuotientLeaf(module) wraps a Torch module whose forward pass factors as periodic conv_stack -> uniform spatial reduction -> linear. Its exact finite action is the cyclic group Z_H x Z_W on an H x W input, implemented by rolling the two spatial axes. Circular padding makes the feature stack equivariant to that action and uniform reduction removes the group coordinate exactly.

UnpooledConvLeaf uses the identical feature extractor, reduction operation count, and linear head but a fixed non-uniform spatial weighting. It is position-sensitive without gaining spatial_size**2 more head parameters, so comparisons isolate the quotient operation rather than confounding it with capacity.

Follows the declare-a-leaf/fit-via-optimize() pattern used elsewhere in mixle.models (see mixle.models.softmax_leaf.NeuralCategorical) rather than a bespoke torch loop: both leaves here are thin torch.nn.Module builders plus a group/declared_group() tag; fitting goes through NeuralCategorical(module).estimator() and mixle.inference.optimize exactly like any other softmax leaf.

Requires torch. Treat this as an experimental modeling option and compare it against the unpooled baseline before making a release claim about benefit.

class CyclicTranslationGroup(name='cyclic_translation_2d', boundary='periodic', axes=(-2, -1))[source]

Bases: object

Finite periodic translations acting on the last two axes of an image tensor.

Parameters:
order(height, width)[source]

Return |Z_height x Z_width| after validating the image extent.

Parameters:
Return type:

int

conv_feature_stack(in_channels=3, hidden_channels=16, out_channels=32)[source]

A small two-layer circular-padding conv feature extractor, shared by both leaves.

Circular padding makes every cyclic spatial shift of the input exactly the same shift of the feature map, including at the boundary.

Parameters:
  • in_channels (int)

  • hidden_channels (int)

  • out_channels (int)

Return type:

Any

build_translation_quotient_module(n_classes, in_channels=3, hidden_channels=16, out_channels=32)[source]

Build an importable quotient module for the periodic Z_H x Z_W action.

Uniform pooling erases cyclic spatial position, so every periodic integer shift has the same logits.

Parameters:
  • n_classes (int)

  • in_channels (int)

  • hidden_channels (int)

  • out_channels (int)

Return type:

Any

build_unpooled_conv_module(n_classes, spatial_size, in_channels=3, hidden_channels=16, out_channels=32)[source]

Build a parameter/FLOP-matched position-sensitive baseline.

It has the identical conv stack, spatial reduction tensor shape, and out_channels -> n_classes head as the quotient module. Only the fixed reduction weights differ: uniform for the quotient and anchored to absolute position here.

Parameters:
  • n_classes (int)

  • spatial_size (int)

  • in_channels (int)

  • hidden_channels (int)

  • out_channels (int)

Return type:

Any

class TranslationQuotientLeaf(module, **neural_categorical_kwargs)[source]

Bases: object

p(y | x) = softmax(module(x)) for a conv->global-pool module, declaring the “translation” group.

Thin wrapper around mixle.models.softmax_leaf.NeuralCategorical that adds the group-declaration part of the leaf contract: leaf.group == "translation" (also exposed as leaf.declared_group() for callers that prefer a method). Fitting/serialization/log-density all delegate to the wrapped NeuralCategorical – this class does not reimplement the leaf contract, it just tags a NeuralCategorical built from a pooled conv module with its symmetry group.

Parameters:
  • module (Any)

  • neural_categorical_kwargs (Any)

declared_group()[source]

Return the symmetry group this leaf’s density is invariant to.

Return type:

CyclicTranslationGroup

log_density(xy)[source]

Delegate log p(y | x) scoring to the wrapped neural-categorical leaf.

Parameters:

xy (Any)

Return type:

float

seq_log_density(enc)[source]

Delegate vectorized conditional log-probability scoring to the wrapped leaf.

Parameters:

enc (Any)

Return type:

Any

predict(x)[source]

Return class predictions from the wrapped neural-categorical leaf.

Parameters:

x (Any)

Return type:

Any

estimator(pseudo_count=None)[source]

Return the wrapped leaf’s estimator.

Parameters:

pseudo_count (float | None)

Return type:

Any

sampler(seed=None)[source]

Return the wrapped leaf’s conditional sampler.

Parameters:

seed (int | None)

Return type:

Any

class UnpooledConvLeaf(module, **neural_categorical_kwargs)[source]

Bases: object

Same-capacity baseline: p(y | x) = softmax(module(x)) for a conv->flatten->dense module.

No symmetry group is declared (group is None) – this baseline has no built-in translation invariance, which is exactly the property TranslationQuotientLeaf is compared against.

Parameters:
  • module (Any)

  • neural_categorical_kwargs (Any)

declared_group()[source]

Return None because this baseline declares no invariance group.

Return type:

str | None

log_density(xy)[source]

Delegate log p(y | x) scoring to the wrapped neural-categorical leaf.

Parameters:

xy (Any)

Return type:

float

seq_log_density(enc)[source]

Delegate vectorized conditional log-probability scoring to the wrapped leaf.

Parameters:

enc (Any)

Return type:

Any

predict(x)[source]

Return class predictions from the wrapped neural-categorical leaf.

Parameters:

x (Any)

Return type:

Any

estimator(pseudo_count=None)[source]

Return the wrapped leaf’s estimator.

Parameters:

pseudo_count (float | None)

Return type:

Any

sampler(seed=None)[source]

Return the wrapped leaf’s conditional sampler.

Parameters:

seed (int | None)

Return type:

Any

shift_image_batch(x, dy, dx)[source]

Apply the exact periodic group action to an (n, c, h, w) NumPy batch.

Pixels leaving one side re-enter at the opposite side, so this is a closed finite group action rather than zero-padding corruption.

Parameters:
Return type:

Any