惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

腾讯CDC
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
P
Proofpoint News Feed
D
DataBreaches.Net
D
Docker
云风的 BLOG
云风的 BLOG
大猫的无限游戏
大猫的无限游戏
月光博客
月光博客
J
Java Code Geeks
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
罗磊的独立博客
Martin Fowler
Martin Fowler
U
Unit 42
Engineering at Meta
Engineering at Meta
IT之家
IT之家
Vercel News
Vercel News
B
Blog RSS Feed
人人都是产品经理
人人都是产品经理
博客园 - Franky
博客园 - 【当耐特】
Stack Overflow Blog
Stack Overflow Blog
G
Google Developers Blog
MongoDB | Blog
MongoDB | Blog

DEV Community

Authentication Security Deep Dive: From Brute Force to Salted Hashing (With Java Examples) Why AI Systems Don’t Fail — They Drift Spilling beans for how i learn for exam😁"Reinforcement Learning Cheat Sheet" I Replaced Chrome with Safari for AI Browser Automation. Here's What Broke (and What Finally Worked) How Python Borrows Other People's Work The $40 Architecture: Processing 1 Billion API Requests with 99.99% Uptime Vibe Coding: A Workflow Guide (From Zero to SaaS) Most webhook security guides protect the wrong side. The scary part is delivery. Headless CMS for TanStack Start: Build a Blog with Cosmic EU Age Verification App "Hacked in 2 Minutes" — What Actually Happened Comfy Cloud’s delete function does not actually remove files Running AI Models on GPU Cloud Servers: A Beginner Guide Event-driven media intelligence with AWS Step Functions and Bedrock I scored 500 AI prompts across 8 quality dimensions — here's what broke How to Call Google Gemini API from Next.js (Free Tier, No Backend Needed) The Portal Protocol: Reclaiming Human Connection in the Age of AI How to Fix Your Team's Scattered Knowledge Problem With a Self-Hosted Forum Intro to tc Cloud Functors: A Graph-First Mental Model for the Modern Cloud Designing Multi-Tenant Backends With Both Ownership and Team Access I Built a Neumorphic CSS Library with 77+ Components — Here's What I Learned PostgreSQL Performance Optimization: Why Connection Pooling Is Critical at Scale Cómo construí un SaaS multi-rubro para gestionar expensas en Argentina con FastAPI + Vue 3 🚀 I Built an Ethical Hacking Scanner Tool – Open Source Project I Replaced /usage and /context in Claude Code With a Single Statusline A Pythonic Way to Handle Emails (IMAP/SMTP) with Auto-Discovery and AI-Ready Design I Collected 8.9 Million Polymarket Price Points — Here's What I Found About How Markets Really Move EcoTrack AI — Carbon Footprint Tracker & Dashboard Everyone's Using AI. No One Agrees How. 5 self-hosted ebook managers worth trying in 2026 Building Your First AI Agent with LangChain: From Chatbot to Autonomous Assistant
Our event-camera detector lost 6 mAP to a badly chosen ac...
Marco Rinaldi · 2026-06-01 · via DEV Community

TL;DR: We spent three weeks chasing a 6 mAP regression in an event-camera object detector. The model was fine. The bug was the accumulation window we used to turn raw events into tensors, and we had picked it once, eighteen months earlier, on a different dataset. Here is how we tune it now.

So, the thing is, with event cameras you do not get frames. You get a stream of events, each one a tuple of (x, y, t, polarity), fired asynchronously whenever a pixel sees a brightness change. Microsecond timestamps. No global shutter, no exposure. Beautiful for high-speed motion. Annoying when you want to feed a convolutional detector that expects a dense tensor.

So everyone accumulates. You take all the events inside a time window, say 10 ms, and you build a representation out of them. A 2D histogram, a voxel grid, a time surface. That window length is a hyperparameter. And in my experience at Prophesee, it is the one people set once and never look at again.

The regression that was not a model regression

Last spring we retrained a small detector for a logistics conveyor setup. Boxes moving at roughly 1.8 m/s past a Gen4 sensor. New training run, new augmentations, and the val mAP came back at 41.2 against a previous baseline of 47.5.

Six points. Gone. We blamed the LoRA-style fine-tune first, then the augmentation pipeline, then a teammate's data split. Two of us, the better part of three weeks.

The actual cause: the old baseline accumulated events over 33 ms, the new pipeline defaulted to 10 ms. At 10 ms the boxes barely produced enough events to fill the histogram. The detector was looking at near-empty tensors. Sparse input, low recall, lost mAP. Nothing wrong with the weights at all.

What the window actually trades

A short window gives you crisp spatial structure but few events, so thin or slow-moving objects vanish. A long window collects plenty of events but smears fast motion across pixels, and the network sees a blurred ghost. The right value depends on object speed and event rate, which means it depends on your scene.

Here is the core of how we build the representation now, with the window made explicit instead of buried in a default:

import torch

def events_to_voxel(events, window_us, num_bins, height, width):
    # events: (N, 4) tensor of [x, y, t_us, polarity]
    t0 = events[:, 2].min()
    rel_t = events[:, 2] - t0
    keep = rel_t < window_us
    ev = events[keep]

    bin_idx = (ev[:, 2] - t0) / window_us * num_bins
    bin_idx = bin_idx.clamp(0, num_bins - 1).long()

    voxel = torch.zeros(num_bins, height, width)
    pol = ev[:, 3] * 2 - 1  # {0,1} -> {-1, +1}
    voxel.index_put_(
        (bin_idx, ev[:, 1].long(), ev[:, 0].long()),
        pol, accumulate=True,
    )
    return voxel

We now sweep window_us as a first-class part of validation, the same way we sweep learning rate. Cheap to run, since it is a preprocessing change and the weights stay fixed for the inference-time sweep.

The numbers from our conveyor set

Same model, same checkpoint, same 4,100-frame validation set. Only the accumulation window changes. Latency measured on a Jetson Orin NX at INT8.

Window Events/frame (median) mAP@0.5 Preproc + inference
5 ms 1,900 38.0 7.4 ms
10 ms 4,300 41.2 8.1 ms
20 ms 9,800 46.9 9.3 ms
33 ms 17,400 47.6 11.0 ms
50 ms 28,500 45.1 13.8 ms

The curve is not monotonic. It climbs, plateaus around 20 to 33 ms, then falls as motion blur sets in. For this scene the sweet spot was 20 ms, which gave us almost all the accuracy of 33 ms with 1.7 ms less latency per frame. We had been leaving both accuracy and speed on the table.

How we audit windows now

We added a small step to dataset curation. For a random 300-frame subset we render the accumulated voxel back to a grayscale-ish preview and run it past a vision-language model to flag frames where the target is unreadable, blurred, or empty. It catches degenerate windows faster than a human scrubbing through previews. We route that call through Bifrost so the same code can hit one provider in CI and a cheaper one for bulk runs without rewriting anything, and that is the whole extent of the LLM involvement here. The detector itself never touches a model bigger than 6 MB.

It is not a substitute for the mAP sweep. It is a sanity filter before we trust the sweep.

Trade-offs and Limitations

The window that wins on a conveyor at 1.8 m/s is wrong for drones or automotive. Scene speed changes everything, so these exact numbers do not transfer. Treat the method, not the 20 ms.

Sweeping the window inflates validation time. Five windows means five full preprocessing passes over the val set. For us that is a few minutes; for a million-frame set it is real compute you have to budget.

A fixed window also assumes roughly constant scene dynamics. The honest answer for variable-speed scenes is an adaptive or event-count-based window, which we are testing but do not yet trust in production. And the VLM audit costs money per frame, so we cap it to a subset rather than the full set.

Further Reading