ETraceConfig#
- class braintrace.ETraceConfig#
A point in the learning-rule axis space.
Six categorical axes carry the coordinate; four numeric fields carry the coefficients. Instances are canonicalised and validated at construction, so a coordinate has exactly one spelling and an illegal combination cannot be built at all.
- Parameters:
trace_factorization (str, default ‘per_param’) – How the eligibility trace is stored, and therefore which engine runs it.
'per_param'keeps a trace per parameter element (ParamDimVjpAlgorithm,O(P*H));'io_factorized'keeps an input-side and an output-side factor (IODimVjpAlgorithm,O(I+O));'random_projection'keeps a rank-1(hidden, parameter)factor pair carrying UORO’s unbiased estimator (RandomProjectionVjpAlgorithm,O(|theta| + P*S)of carrier storage). It is the only coordinate whose trace is unbiased, and it requiresrecurrence_scope='coupled'– see rule 11.temporal_recursion (str or tuple of str, default ‘jacobian’) – The structural operator
Rin the trace recurrence.'jacobian'uses the hidden-to-hidden JacobianD,'scalar_leak'replaces it withdecay * I,'none'with0. Under'io_factorized'this is a(x_side, f_side)pair; a scalar expands to both sides, with an x-side'jacobian'demoted to'scalar_leak'because the input-side trace never involves a Jacobian.recurrence_scope (str, default ‘diagonal’) – How much hidden-to-hidden coupling enters
D.'diagonal'keeps only each state’s own recurrence;'coupled'traces recurrent mixing between states of a hidden group;'sparse_n'retains influence over ann-step neighbourhood derived from the model’s own transition (SnAp-n), withnsupplied assparse_n. The last two form one scale: SnAp-1 is'coupled'(the instantaneous pattern propagated zero times), andsparse_n=1canonicalises onto it.'diagonal'sits below the scale – it drops the recurrent mixing primitive from the transition before differentiating – so nonreaches it.learning_signal (str, default ‘symmetric’) – Where the per-hidden-group signal comes from.
'symmetric'uses the truedL/dh;'random_feedback'projects it through a fixed random matrix (feedback alignment);'modulatory'replaces it with a user-supplied neuromodulator (three-factor learning – one array expanded to every group, never a per-group sequence, and single-step only);'bootstrapped'leaves it alone and instead injects a learned estimate of the future-loss gradient at the window’s exit cotangent (DNI), which reaches the plain parameters only – the eligibility trace already carries the ETP parameters’ cross-window credit.trace_filter (str, default ‘none’) – Optional low-pass on the trace.
'kappa'appliese_bar <- kappa * e_bar + e, e-prop’s filter.update_schedule (str, default ‘per_step’) – When the weight gradient is emitted.
decay (float or tuple of float, optional) – Per-step discount of the previous trace. Required by
'io_factorized'(where it is a(x, f)pair, a scalar expanding to both sides) and by'per_param'with'scalar_leak'. Must lie in[0, 1).kappa (float, optional) – Coefficient of
trace_filter='kappa', in[0, 1).sparse_n (int, optional) – Coefficient of
recurrence_scope='sparse_n': the SnAp order, an integer>= 1. Any order at or above a hidden group’s diameter saturates to full within-group RTRL, so there is no “infinity” spelling – saturation is a property of the model, not the vocabulary.window_size (int, optional) – Coefficient of
update_schedule='window'.
- Raises:
ValueError – If a field carries a value outside its vocabulary, a coefficient is out of range, or the combination is rejected by the compatibility matrix.
TypeError – If a coefficient is not a number.
Notes
Canonicalisation runs before validation, so no rule ever fires on a spelling that canonicalisation would have removed:
'scalar_leak'withdecay == 0becomes'none'— they are one rule — and'none'pins its decay side to0.0.Under
'io_factorized'a scalartemporal_recursion/decayexpands to a pair.trace_filter='kappa'withkappa == 0becomes'none', matchingEProp(kappa_filter_decay=0)’s documented reduction toD_RTRL.recurrence_scope='sparse_n'withsparse_n == 1becomes'coupled'with no coefficient — SnAp-1 and the block-diagonal recursion are one rule.
Examples
>>> import braintrace >>> braintrace.ETraceConfig().trace_factorization 'per_param' >>> # pp_prop's coordinate: a leaky input trace, a Jacobian output trace >>> cfg = braintrace.ETraceConfig( ... trace_factorization='io_factorized', decay=0.9) >>> cfg.temporal_recursion ('scalar_leak', 'jacobian') >>> # a coefficient with no category is a typo, not a configuration >>> braintrace.ETraceConfig(kappa=0.5) Traceback (most recent call last): ValueError: `kappa=0.5` is set but `trace_filter` is 'none'...
- property decay_f#
The f-side smoothing coefficient.
io_factorizedonly.
- property decay_x#
The x-side smoothing coefficient.
io_factorizedonly.
- describe()#
One-line human-readable coordinate, for reports and error messages.
- Returns:
str – The non-default axes, or
'default'when the config is the default coordinate.
- property include_recurrent_mixing#
Whether the compiler should trace hidden-to-hidden ETP mixing.
The graph executor’s spelling of
recurrence_scope.Truefor both non-diagonal scopes:'coupled'needs the coupled transition to take its per-position block diagonal, and'sparse_n'needs the same transition to gather its widened operator out of.
- property is_factorized#
Whether the trace is stored as an input/output factor pair.
- property recursion_f#
The f-side (output factor) recursion.
io_factorizedonly.
- property recursion_x#
The x-side (input factor) recursion.
io_factorizedonly.
- replace(**changes)#
Return a copy with
changesapplied, re-canonicalised and re-checked.- Parameters:
**changes – Field values to override.
- Returns:
ETraceConfig – The new configuration.
Notes
The receiver is already canonical, so a field left unchanged is passed on in canonical form. That is only lossless because canonicalisation is idempotent — a canonical value always canonicalises to itself.
- ETraceConfig.__init__(trace_factorization='per_param', temporal_recursion='jacobian', recurrence_scope='diagonal', learning_signal='symmetric', trace_filter='none', update_schedule='per_step', decay=None, kappa=None, sparse_n=None, window_size=None)#