COBRA belief filter#

COBRA: a context-rotated density-matrix belief filter for robots that read people.

A robot watching a person receives a stream of sensor frames (gaze, hand motion, force). What a reading means often depends on what came just before it: the same hand movement signals a hand-over after a look at the robot and a retrieval after a look away. A classical Bayes filter treats the frames as conditionally independent and cannot represent that. COBRA keeps the robot’s belief as a density matrix \(\rho\) over \(d\) hypotheses and updates it with a generalised measurement whose basis is rotated by the previous frame:

\[ \begin{align}\begin{aligned}M_t = U(x_{t-1})\,\mathrm{diag}\bigl(e^{(Wx_t + b)/2}\bigr)\,U(x_{t-1})^\dagger , \qquad \rho_t \propto M_t \rho_{t-1} M_t ,\\U(x) = \exp\bigl(-i\,[\,H_0 + \textstyle\sum_k \tanh(\beta x_k)\,H_k\,]\bigr),\end{aligned}\end{align} \]

followed by partial dephasing \(\rho \leftarrow (1-g)\rho + g\,\mathrm{diag}(\rho)\). The probability of hypothesis \(z\) is \(\rho_{zz}\) (Born rule). The \(H_k\) are learned Hermitian matrices.

Two special cases make the model honest about what is quantum-like in it. With \(H = 0\) it is a classical Bayes filter with log-linear likelihoods. With \(g = 1\) it is a classical incoherent context-dependent filter: the previous frame still changes the meaning of the next one, but no phase survives between frames. Comparing the three isolates the effect of the context rotation and of the coherence.

This is a classical simulation of the quantum-probability formalism; it needs only NumPy and does not claim a quantum computational advantage. Training uses finite-difference Adam with symmetry-breaking restarts, because the rotation and the evidence weights must grow together (a product of two near-zero terms is a saddle); the benchmark in benchmarks/context_intent_benchmark.py shows that the context mechanism is found on some restarts and seeds and not on others.

Classes

COBRA

Context-rotated density-matrix belief filter (see the module docstring for the equations).

BeliefTrace

Per-frame outputs of a COBRA forward pass.

OnlineBelief

A COBRA belief updated one frame at a time, as a robot would run it.

GaussianBayesFilter

Commutative naive-Bayes filter with independent Gaussian features per hypothesis.

Functions

min_cost_action

Action with minimum expected cost under a belief.

class COBRA(n_hyp=3, n_features=3, *, beta=2.0, steps=100, batch=160, lr=0.1, l2=0.0001, restarts=4, seed=0)[source]#

Bases: object

Context-rotated density-matrix belief filter (see the module docstring for the equations).

Parameters:
  • n_hyp (int, optional) – Number of latent hypotheses (the Hilbert-space dimension), for example intents.

  • n_features (int, optional) – Sensor features per frame.

  • beta (float, optional) – Gain of the tanh squashing applied before the rotation generator.

  • steps (optional) – Adam settings. Gradients are central finite differences, which is exact enough for the few dozen parameters.

  • batch (optional) – Adam settings. Gradients are central finite differences, which is exact enough for the few dozen parameters.

  • lr (optional) – Adam settings. Gradients are central finite differences, which is exact enough for the few dozen parameters.

  • l2 (float, optional) – Weight decay on all parameters.

  • restarts (int, optional) – Symmetry-breaking initialisations tried before full training; the one with the best validation loss after a short run is trained fully.

  • seed (int, optional) – Deterministic initialisation and minibatch order.

Variables:

theta (numpy.ndarray) – All learned parameters (n_params values).

Examples

>>> import numpy as np
>>> from quantum_mind.belief import COBRA
>>> rng = np.random.default_rng(0)
>>> x = rng.normal(size=(60, 3, 2)); y = (x[:, :, 0].sum(1) > 0).astype(int)
>>> model = COBRA(2, 2, steps=20, restarts=1).fit(x, y)
>>> model.predict_proba(x).shape
(60, 2)
property n_params#

Number of learned parameters.

property dephasing#

The learned dephasing strength \(g\) in (0, 1).

fit(x, y)[source]#

Train on sequences x of shape (N, T, n_features) and integer labels y of shape (N,).

Returns:

COBRA – self, so calls can be chained.

Raises:

ValueError – If the shapes do not match the model or a label is outside range(n_hyp).

predict_proba(x)[source]#

Hypothesis probabilities after the last frame, shape (N, d).

trace(x)[source]#

Probabilities, coherence and density matrix after every frame (a BeliefTrace).

coherence(x)[source]#

l1 coherence of the final belief (0 for a classical belief), shape (N,).

start()[source]#

Begin an OnlineBelief for streaming use.

class BeliefTrace(probs, coherence, rho)[source]#

Bases: object

Per-frame outputs of a COBRA forward pass.

Variables:
  • probs (numpy.ndarray, shape (N, T, d)) – Hypothesis probabilities after each frame.

  • coherence (numpy.ndarray, shape (N, T)) – l1 coherence (sum of off-diagonal moduli) of \(\rho\) after each frame.

  • rho (numpy.ndarray, shape (N, T, d, d)) – Density matrix after each frame.

Parameters:
class OnlineBelief(model, rho, prev)[source]#

Bases: object

A COBRA belief updated one frame at a time, as a robot would run it.

Create it with COBRA.start(). Call update() with each new sensor frame; read probs and coherence after every update.

Examples

>>> import numpy as np
>>> from quantum_mind.belief import COBRA
>>> belief = COBRA(3, 3, restarts=1, steps=1).start()
>>> p = belief.update([0.5, -0.2, 0.1])
>>> bool(abs(p.sum() - 1) < 1e-9)
True
update(frame)[source]#

Fold one sensor frame into the belief and return the new probabilities.

class GaussianBayesFilter(n_hyp=3)[source]#

Bases: object

Commutative naive-Bayes filter with independent Gaussian features per hypothesis.

The classical reference for COBRA: frames are conditionally independent given the hypothesis, so reordering them cannot change the belief.

Examples

>>> import numpy as np
>>> from quantum_mind.belief import GaussianBayesFilter
>>> rng = np.random.default_rng(0)
>>> y = rng.integers(0, 2, 80); x = rng.normal(size=(80, 3, 2)) + y[:, None, None]
>>> GaussianBayesFilter(2).fit(x, y).predict_proba(x).shape
(80, 2)
min_cost_action(probs, cost)[source]#

Action with minimum expected cost under a belief.

Parameters:
  • probs (array_like, shape (N, d) or (d,)) – Belief over the hypotheses.

  • cost (array_like, shape (n_actions, d)) – cost[a, z] is the cost of action a when hypothesis z is true. Include an “ask” or “wait” row so the robot can hedge under ambiguity.

Returns:

numpy.ndarray of int – Index of the best action for each belief.

Examples

>>> from quantum_mind.belief import min_cost_action
>>> cost = [[0, 6, 10], [1.5, 0, 0], [0.8, 0.8, 0.8]]      # hand over, wait, ask
>>> min_cost_action([[0.97, 0.02, 0.01], [0.7, 0.2, 0.1]], cost).tolist()
[0, 2]