Skip to content

t5lab.probe_mvprop

probe_mvprop

Root-cause probe + distillation feasibility for the MVProp planner.

Part A — WHY RL-only MVProp never sharpens: at init the value field is near-flat / near-zero where agents actually are, so the derived move is uninformative and the RL gradient through K max-prop sweeps (max sparsity x w^K flood-decay) vanishes -> stuck.

Part B — the fix: distil MVProp's field toward the classical wavefront (controller.nav_distance_field, free + already in the codebase). Dense per-cell target -> gradients everywhere. Show the field then matches the teacher and the derived von-Neumann move matches the classical navfield move.

Run

V=/Users/bijanmehr/Project.Zymera/zymera_lab/.venv/bin/python PYTHONPATH=.:/Users/bijanmehr/Project.Zymera/zymera_lab $V -m t5lab.probe_mvprop

vn_move_from_field

vn_move_from_field(V, cell)

argmax over the 5 von-Neumann neighbour values -> action index (STAY,N,E,S,W).

Source code in experiments/t5lab/probe_mvprop.py
39
40
41
42
def vn_move_from_field(V, cell):
    """argmax over the 5 von-Neumann neighbour values -> action index (STAY,N,E,S,W)."""
    nb = jnp.clip(cell[None] + _DELTAS, 0, jnp.array([H - 1, W - 1]))
    return int(jnp.argmax(V[nb[:, 0], nb[:, 1]]))

vn_move_from_dist

vn_move_from_dist(D, cell)

argmin over the 5 von-Neumann neighbour distances -> the classical navfield move.

Source code in experiments/t5lab/probe_mvprop.py
45
46
47
48
def vn_move_from_dist(D, cell):
    """argmin over the 5 von-Neumann neighbour distances -> the classical navfield move."""
    nb = jnp.clip(cell[None] + _DELTAS, 0, jnp.array([H - 1, W - 1]))
    return int(jnp.argmin(D[nb[:, 0], nb[:, 1]]))

rand_wall

rand_wall(key)

~half open, ~half a few random axis-aligned wall segments (like local clutter).

Source code in experiments/t5lab/probe_mvprop.py
51
52
53
54
55
56
57
58
59
60
61
def rand_wall(key):
    """~half open, ~half a few random axis-aligned wall segments (like local clutter)."""
    k1, k2, k3 = jax.random.split(key, 3)
    if jax.random.uniform(k1) < 0.5:
        return jnp.zeros((H, W), bool)
    b = np.zeros((H, W), bool)
    for kk in jax.random.split(k2, 3):
        r = int(jax.random.randint(kk, (), 1, H - 1))
        c0 = int(jax.random.randint(kk, (), 0, W // 2))
        b[r, c0:c0 + W // 3] = True
    return jnp.asarray(b)