Running Monty zero-shot on real RGB-D data (BOP YCB-V): what breaks and what cheap fixes buy

Hi everyone,

I’ve been following the Thousand Brains theory and this project for a while, and I recently decided to move from reading along to actually building — doing some engineering validation and a bit of exploratory research. This is the first thing I picked up: running Monty’s pretrained models zero-shot on real RGB-D data, to see what happens when object models learned in simulation meet a real camera. The data is YCB-V from the BOP benchmarks (real captures, with ground-truth camera poses provided, so it’s reproducible). This post is a record of what worked out of the box, what broke, and how much the cheap fixes buy back. I didn’t touch Monty’s core code — all adaptation is done through subclasses.

Setup

  • Models: the official supervised-pretrained 77-object graphs (the surf_agent_1lm_77obj family), no re-training.
  • Data: YCB-V test scenes converted into the format SaccadeOnImageEnvironment expects (a depth image + RGB). That environment was written for iPad captures, and it turns out to be a ready-made bridge between simulation and real images.
  • Two small adaptations (in a subclass): widen the depth clip from the iPad’s 0.4 m to 2 m; use the dataset’s intrinsics for field of view (the environment hard-codes the iPad’s hfov).
  • Test set: 8 YCB objects × 4 frames each = 32 recognition episodes.

First results: two failure modes

Outcome (official CSV category) Episodes Share
correct (converged, right object) 4 12%
correct_mlh (timed out, most likely hypothesis was right) 9 28%
confused (converged, wrong object) 12 38%
confused_mlh (timed out, most likely hypothesis also wrong) 4 12%
patch_off_object (saccade never landed on the object) 3 9%

A model that scores near 100% on the simulated benchmark is confidently-correct only 12% here; add the timed-out-but-right episodes and 41% get the answer right. Setting aside the 3 pipeline misses (patch_off_object, where the saccade never found the object), the recognition failures fall cleanly into two kinds (Fig. 1):

  • Failure A — the answer is actually right (the most likely hypothesis points at the correct object), but the episode times out before the terminal condition is met. The model won’t commit. (correct_mlh, 9 episodes.)
  • Failure B — it converges quickly onto the wrong object, which is worse than not committing. (confused, 12 episodes.)

(Fig. 1: the 32 episodes broken down by outcome category.)

A tiny logging tool

The official step-by-step log (DetailedJSONHandler) is ~1.3 GB per episode here, too heavy to leave on. I wrote a lightweight logger that records, per step, only the top-5 candidate objects’ evidence and the sensor’s pixel location — about 150 KB per episode. Every diagnosis below comes from it (Fig. 2).

(Fig. 2: evidence of the top candidates vs. step count for one episode — the winner never pulls far enough ahead of the runner-up to trigger termination.)

Diagnosis without new experiments

Re-reading the existing logs is enough to locate the mechanism behind each failure:

  • Of the timed-out episodes, every one is stuck at the same place: the possible matches (the set of still-viable objects) never narrows to one. The terminal condition needs the runner-up’s evidence to fall below 80% of the leader’s (x_percent_threshold=20), and from a single real viewpoint there are always a few geometrically-similar objects staying close.
  • Of the wrong-object episodes, most converge at a very low absolute evidenceobject_evidence_threshold defaults to 1, which is essentially no floor.

Both failures share one root cause: from a single viewpoint, local geometry doesn’t separate similar objects. A small patch of a can’s wall and a small patch of a pitcher’s wall look nearly the same at patch scale.

Cheap fixes and where they stop

Fix (config-level only) Effect
object_evidence_threshold 1 → 50 stops most low-evidence wrong convergences; 4 episodes flip from wrong to correct
library 77 → 8 objects marginal — the runner-up confuser simply takes over
background masking (GT masks) pitcher_base 0/4 → 4/4; background depth was polluting the patches
frame-quality filter (visibility ≥ 90%, depth coverage ≥ 70%) one object’s frames turned out to be 83–89% occluded — it had never been fairly tested
all combined confident-correct 12% → 28%; precision 60%

Config-level fixes have a clear ceiling. Past 28%, the remaining failures all point the same way — not enough information, rather than bad judgment.

A few observations for the team

  1. Timed-out episodes are all stuck on the possible-matches convergence criterion; the symmetry-confirmation logic never runs in these episodes (it comes after object uniqueness).
  2. object_evidence_threshold defaults to 1, which is effectively off on real data — an empirical sweet spot is around 50 (for this 8-object, single-view setup).
  3. SaccadeOnImageEnvironment hard-codes hfov and the depth clip for the iPad; these would be worth parameterizing (I plan to send a small PR).
  4. Real-sensor depth dropout (depth = 0) is currently unprojected into “a surface at the camera origin”; treating it as an invalid observation would be more correct (also a small PR).

What I’m trying next

The single-view wall is an information wall: the local geometry one patch sees isn’t enough to separate similar objects. Next I want to let the sensor move — accumulating evidence across several real viewpoints within one episode (using the dataset’s ground-truth camera poses for a shared world frame) — and see how much “recognition through movement” delivers on real data.

(Reproduction commands, the converter, and all configs are here: monty-realworld. Happy to hear where my adaptation choices are wrong.)

6 Likes

Continued in Recognition through movement on real RGB-D data: what one moving sensor buys, and the failure it introduces

Hi @W_Foxalike

first of all, amazing work! Thanks a lot for sharing all this here. This is super interesting for us.

Great idea about testing on the YCB-V dataset for sim-to-real transfer. This is a nice reproducible test bed. To get a better idea of this task, could you share some of the images that you use to test Monty on? As far as I understand, YCB-V is a video dataset, how did you select the frames, and do they contain several objects or only one?

Those are some really good catches and fixes (hfov is definitely a gotcha, so if you can make a PR for that, this would be great!).

In my mind the terminal condition is mostly there to have some criterion for terminating an episode early to avoid computational cost. If we only show one object and Monty has low evidence for all others, we don’t have to keep matching. But one could also set it less strictly to shorten episodes or more strictly to always take max_steps before ending an episode. I think of this as mostly an experiment parameter as opposed to a Monty feature that you can adjust depending on what you want to measure. Monty itself has a most likely hypothesis at every step and can use this to act. It doesn’t need to wait until any terminal threshold is reached to be able to use its hypotheses for intelligent action. This is why we, for example, group correct and correct_mlh together in our recent publication evaluating Monty (https://direct.mit.edu/neco/article/38/6/845/136222/Thousand-Brains-Systems-Sensorimotor-Intelligence) (while still separating them in some plots like figure 5 since, of course, being more confident earlier is better).
We will probably need to work more on this parameter as we introduce more hierarchy (since it also plays a role in when an LM sends a message to another LM) since, as you pointed out, being able to uniquely identify an object isn’t always possible if you just have one viewpoint and know about several objects that look similar/identical from this view.

The object_evidence_threshold and the finding that confused episodes often have a low confidence are also interesting results. Thanks for sharing this. I wonder whether adjusting the object_evidence_threshold would also help with our performance on the Monty Meets World Benchmarks.

Finally, one small tip: It looks like you wrote a nice custom logger and plotting for what you need already, but you might be interested in the tbp.teleop tool @rmounir published recently Controlling the Monty agent live with `tbp.teleop`. It’s been a useful debugging tool for our research team lately and can make some nice live visualizations of what Monty sees during an experiment and what its hypotheses look like without having to save large detailed stats files. As far as I know, we haven’t tried it on the SaccadeOnImageEnvironment yet, so I am not 100% sure if it will work out of the box for what you are doing, but maybe worth a try.

Again thanks a lot for sharing this here and I’m looking forward to reading your further updates!

  • Viviane
1 Like

Hi Viviane, thanks so much for the detailed feedback — this is really helpful.

To your questions:

  • Frame selection / images: YCB-V is indeed a video dataset. I pick frames with a quality filter (target visibility ≥ 90%, depth coverage ≥ 70%), and each episode targets a single object — the scenes contain several objects, but I crop the target out using its ground-truth box and invalidate the background depth, so Monty only matches on the object. A few of the actual frames I use are attached (RGB + the depth channel Monty matches on).

  • Terminal condition: thanks for the clarification — you’re right that correct_mlh means Monty can already act on its MLH. I’ll group correct and correct_mlh as “answer available” going forward (matching the framing in your Neco paper), rather than emphasizing only the 12% confident-correct.

  • object_evidence_threshold: good idea — I’ll sweep it on the Monty Meets World benchmark and see whether it helps there too.

  • hfov: I’ll make the PR.

  • tbp.teleop: thanks, I’ve been wanting a lighter visualization — I’ll try it on SaccadeOnImageEnvironment.

Thanks again, and I’ll keep posting updates.

1 Like

Hi vclay

Made the PR for the hfov parameterization you suggested — thousandbrainsproject/tbp.monty#1100. Thanks!

1 Like

Amazing, thank you! And also thinks for sharing those images, that helps visualize things :slight_smile: