demo.html lets you watch the hand-written networks drive. It is a single HTML file
with no build step and no server code: the network weights are embedded in the page,
and every move is computed by a forward pass in your browser.
Live: https://gaberger.github.io/experiments/mini-jev/demo.html
Locally: open demo.html in any browser.
┌───┬───┬───┐
│ │ │ ▓ │ ← 5 rows ahead (top)
│ │ ▓ │ │
│ ▓ │ │ │
│ │ │ ▓ │
│ │ ▓ │ ▓ │ ← next row the car enters
├───┼───┼───┤
│ │ ● │ │ ← the car
└───┴───┴───┘
Left, Stay
and Right for the current road. The highlighted bar is the top choice, and that is
the move the car makes.| Control | What it does |
|---|---|
| Deep net | The 11-layer network that computes which lanes can still reach a clear path. |
| Shallow net | The 2-layer network that scores how clear each neighbouring lane looks. |
| Random | Picks a move uniformly at random. Its bars always show 33% each. |
| Play / Pause | Steps the road every 0.38 s. After a crash it starts a new road on its own. |
| New road | Starts a fresh road and resets the best score. |
Each step the page builds the same 18-number input the Python script uses:
It runs that through the network layer by layer (W·x + b, ReLU on hidden layers),
applies a softmax to the 3 outputs, and moves in the direction with the highest
probability. Hitting an obstacle ends the run.
| Network | Layers | Layer widths |
|---|---|---|
| Deep | 11 | 18 → 21 → 15 → 18 → 12 → 15 → 9 → 12 → 6 → 9 → 3 |
| Shallow | 2 | 18 → 9 → 3 |
The deep network’s layers alternate between two jobs, working from the far row back toward the car: keep the inputs it still needs, and compute, for each lane of a row, “this cell is clear AND a clear cell is reachable in the row after it”. See the main README for the ReLU tricks that do the AND and OR.
The road follows the same rules as mini_jev.py: each cell is an obstacle with
probability 0.45, and a hidden safe lane that drifts by at most one lane per row is
always kept clear, so a drivable path always exists. The page uses its own random
number generator, so its roads differ from the 500 benchmark roads in the Python
script.
The weights live in the WJ constant near the top of the <script> block: for each
network, a list of [W, b] pairs, one per layer, where W has one row per output
unit. Change a number and reload the page to see what it does to the driving.