t5lab.mvprop¶
mvprop
¶
MVProp — learned max-propagation navigation planner (Value/Max-Propagation Networks,
Nardelli 2018). A per-cell value field floods outward from the goal, discounted per step and
blocked by walls; the value at the agent's move-neighbours are the move scores
(differentiable -> trainable). Drop-in for ctde_v0's classical nav_distance_field.
Root-cause note (probe_mvprop.py, 2026-08-02). A from-scratch MVProp whose reward map r AND
passability w are both free conv outputs does NOT train under RL: at init w = sigmoid(0)
~ 0.5 so the flood decays ~0.5 per step and dies within ~5 cells; the field is ~0 and flat
where agents actually are, the move scores are identical, and the gradient through K max-prop
sweeps (max-sparsity x w^K decay) vanishes -> stuck. Two structural fixes make it trainable:
- ANCHOR the reward to the goal.
ris the goal one-hot channel (a unit spike AT the goal), not a free conv — the flood always originates strongly at the goal. - FLOOD FAR AT INIT.
w = sigmoid(gain_conv(x) + w_init_bias)with a large positivew_init_biasso free cells start atw ~ 0.9and the flood reaches the whole map; the only thing left to LEARN is to dropw -> 0at walls so the field routes around them.
With those, the value field at init is already a usable gamma^dist gradient, and
distillation toward the classical wavefront (controller.nav_distance_field) drives it to route.
MVProp
¶
MVProp(in_ch, K, *, key, gamma=0.9, goal_ch=-1, w_init_bias=2.0)
Bases: Module
Learned MVProp planner. A conv turns the map channels into per-cell passability
w in (0,1); the reward map r is the goal one-hot channel (anchored spike);
propagate floods the value field; move_scores reads V at the agent's neighbours.
Input x is (C,H,W); channel goal_ch (default the LAST channel) is the goal
one-hot. All other channels feed the passability conv.
Source code in experiments/t5lab/mvprop.py
70 71 72 73 74 75 76 77 78 79 | |
field
¶
field(x)
(C,H,W) input -> (H,W) value field. r = goal one-hot; w = sigmoid(conv(x)).
Source code in experiments/t5lab/mvprop.py
81 82 83 84 85 | |
move_scores
¶
move_scores(x, rc)
(C,H,W) input, (2,) agent cell -> (5,) neighbour values in ACTION_DELTAS order. Higher = better move (ascends the value field toward the goal).
Source code in experiments/t5lab/mvprop.py
87 88 89 90 91 92 93 | |
propagate
¶
propagate(r, w, K, gamma=0.9)
Max-propagation value field.
V0 = r; V_{k+1}(x) = max( r(x), gamma * w(x) * max_4nbr(V_k)(x) ) for K sweeps.
With r = goal reward (positive at the goal, ~0 elsewhere) and w = passability
(0 at walls, 1 on free cells), value floods from the goal, decays by gamma per step,
and does NOT cross walls (w=0 blocks the product). Reachable free cells get gamma^d
times the goal reward; walls and cut-off cells stay ~0. Higher V = closer to the goal.
Source code in experiments/t5lab/mvprop.py
42 43 44 45 46 47 48 49 50 51 52 53 54 | |