Live2D

Note -「SNN Tracker」什么东西飞过去了?

\[\mathscr{Lorain~wy~Lora~blea.} \newcommand{\DS}[0]{\displaystyle} % operators alias \newcommand{\opn}[1]{\operatorname{#1}} \newcommand{\card}[0]{\opn{card}} \newcommand{\lcm}[0]{\opn{lcm}} \newcommand{\char}[0]{\opn{char}} \newcommand{\Char}[0]{\opn{Char}} \newcommand{\Min}[0]{\opn{Min}} \newcommand{\rank}[0]{\opn{rank}} \newcommand{\Hom}[0]{\opn{Hom}} \newcommand{\End}[0]{\opn{End}} \newcommand{\im}[0]{\opn{im}} \newcommand{\tr}[0]{\opn{tr}} \newcommand{\diag}[0]{\opn{diag}} \newcommand{\coker}[0]{\opn{coker}} \newcommand{\id}[0]{\opn{id}} \newcommand{\sgn}[0]{\opn{sgn}} \newcommand{\Res}[0]{\opn{Res}} \newcommand{\Ad}[0]{\opn{Ad}} \newcommand{\ord}[0]{\opn{ord}} \newcommand{\Stab}[0]{\opn{Stab}} \newcommand{\conjeq}[0]{\sim_{\u{conj}}} \newcommand{\cent}[0]{\u{\degree C}} \newcommand{\Sym}[0]{\opn{Sym}} \newcommand{\Var}[0]{\opn{Var}} \newcommand{\wg}[0]{\wedge} \newcommand{\Wg}[0]{\bigwedge} \newcommand{\sq}[0]{\opn{\square}} % symbols alias \newcommand{\E}[0]{\exist} \newcommand{\A}[0]{\forall} \newcommand{\l}[0]{\left} \newcommand{\r}[0]{\right} \newcommand{\ox}[0]{\otimes} \newcommand{\lra}[0]{\leftrightarrow} \newcommand{\llra}[0]{\longleftrightarrow} \newcommand{\iso}[1]{\overset{\sim}{#1}} \newcommand{\eps}[0]{\varepsilon} \newcommand{\Ra}[0]{\Rightarrow} \newcommand{\Eq}[0]{\Leftrightarrow} \newcommand{\d}[0]{\mathrm{d}} \newcommand{\e}[0]{\mathrm{e}} \newcommand{\i}[0]{\mathrm{i}} \newcommand{\j}[0]{\mathrm{j}} \newcommand{\k}[0]{\mathrm{k}} \newcommand{\Ex}[0]{\mathbb{E}} \newcommand{\D}[0]{\mathbb{D}} \newcommand{\oo}[0]{\infty} \newcommand{\tto}[0]{\rightrightarrows} \newcommand{\mmap}[0]{\hookrightarrow} \newcommand{\emap}[0]{\twoheadrightarrow} \newcommand{\actl}[0]{\curvearrowright} \newcommand{\actr}[0]{\curvearrowleft} \newcommand{\nsubg}[0]{\triangleleft} \newcommand{\nsupg}[0]{\triangleright} \newcommand{\lin}[0]{\lim_{n\to\oo}} \newcommand{\linf}[0]{\liminf_{n\to\oo}} \newcommand{\lsup}[0]{\limsup_{n\to\oo}} \newcommand{\ser}[0]{\sum_{n=1}^\oo} \newcommand{\serz}[0]{\sum_{n=0}^\oo} \newcommand{\isoto}[0]{\overset\sim\to} \newcommand{\F}[0]{\mathbb F} \newcommand{\x}[0]{\times} \newcommand{\M}[0]{\mathbf{M}} \newcommand{\T}[0]{\intercal} \newcommand{\Co}[0]{\complement} \newcommand{\alp}[0]{\alpha} \newcommand{\lmd}[0]{\lambda} \newcommand{\mmid}[0]{\parallel} \newcommand{\loop}[0]{\circlearrowleft} \newcommand{\go}[0]{\triangleright} % symbols with parameters \newcommand{\der}[1]{\frac{\d}{\d #1}} \newcommand{\ul}[1]{\underline{#1}} \newcommand{\ol}[1]{\overline{#1}} \newcommand{\wt}[1]{\widetilde{#1}} \newcommand{\br}[1]{\l(#1\r)} \newcommand{\bk}[1]{\l[#1\r]} \newcommand{\ev}[1]{\l.#1\r|} \newcommand{\wh}[1]{\widehat{#1}} \newcommand{\eval}[1]{\l[\!\l[#1\r]\!\r]} \newcommand{\abs}[1]{\l|#1\r|} \newcommand{\bs}[1]{\boldsymbol{#1}} \newcommand{\dat}[1]{\bs{\mathrm{#1}}} \newcommand{\env}[2]{\begin{#1}#2\end{#1}} \newcommand{\ALI}[1]{\env{aligned}{#1}} \newcommand{\CAS}[1]{\env{cases}{#1}} \newcommand{\pmat}[1]{\env{pmatrix}{#1}} \newcommand{\algo}[1]{\begin{array}{r|l}#1\end{array}} \newcommand{\dary}[2]{\l|\begin{array}{#1}#2\end{array}\r|} \newcommand{\pary}[2]{\l(\begin{array}{#1}#2\end{array}\r)} \newcommand{\pblk}[4]{\l(\begin{array}{c|c}{#1}&{#2}\\\hline{#3}&{#4}\end{array}\r)} \newcommand{\u}[1]{\mathrm{#1}} \newcommand{\t}[1]{\text{#1}} \newcommand{\tb}[1]{\textbf{#1}} \newcommand{\os}[2]{\overset{#1}{#2}} \newcommand{\lix}[1]{\lim_{x\to #1}} \newcommand{\ops}[1]{#1\cdots #1} \newcommand{\seq}[3]{{#1}_{#2}\ops,{#1}_{#3}} \newcommand{\dedu}[2]{\u{(#1)}\Ra\u{(#2)}} \newcommand{\prv}[3]{\DS{{\DS #1} \over {\DS #2}}~(#3)} \]

  对 reference 中论文的精读笔记, 介绍 SNN Tracker 的技术细节. SNN Tracker 是 (当时) 第一个完全使用 SNN 对脉冲相机的数据流直接处理并完成运动检测的模型, 其规避了传统方法中对 中间帧重建 -> 图像识别/分析 的路径依赖, 极大增强了运动检测的实时性, 对诸如自动驾驶等领域有很高的应用价值. 文中 "评注" 块的内容是 Codex 在 review 论文官方实现仓库后生成的, 其他部分是手码的. (我也不知道为什么很多地方与文中建模存在不小的差异.)

动态适应

  我们首先回忆脉冲相机 (spike camera) 的工作特性. 它在每个像素累计光照强度 \(I\), 即

\[V(t)=V(t-\Delta t)+I(t)\Delta t, \]

直到 \(V(t)\ge\theta\), 这时此像素发出脉冲并重置 \(V(t)\gets 0\). 这样, 一个 \(H\x W\) 像素, \(T\) 时间步的脉冲流

\[S\in\{0,1\}^{H\x W\x T} \]

就能由脉冲相机记录生成. 对特定像素, 设其脉冲发生频率为 \(f_s\), 显然 \(f_s\propto\frac{I(t)}{\theta}\).

  现在, 我们只关心运动带来的脉冲, 而不关心那些虽然产生但周期性过强的脉冲. 为此, 我们模拟生物神经元的短时可塑性 (short-term plasticity), 引入短期易化主导 (short-term facilitation dominated) 模型来进行时间滤波, 定义

  • \(R_n\in[0,1]\): 表示第 \(n\) 个脉冲到来之前, 突触前膜可释放的囊泡比例;
  • \(u_n\in[0,1]\): 表示第 \(n\) 个脉冲到来时, 突触前膜释放的可用囊泡比例.

  建模它们的动力学行为如下:

\[R_{n+1}=1-\br{1-R_n(1-u_n)}\e^{-\frac{\Delta t_n}{\tau_D}},\\ u_{n+1}=U+\br{u_n+C(1-u_n)-U}\e^{-\frac{\Delta t_n}{\tau_F}}. \]

其中 \(\tau_D\), \(\tau_F\), \(U\), \(C\) 分别为延迟时间常数, 易化时间常数, 释放基线和易化因子, 都是常数. 它们共同描述如下行为:

  • \(n\) 次释放后, 前膜囊泡待补充量 \(1-R_n(1-u_n)\) 以负指数补充满;
  • \(n\) 次释放后, 前膜产生易化效应, \(u_n'\gets u_n+C(1-u_n)\), 此后负指数衰减到基线 \(U\).

最后, 后膜兴奋条件为

\[\mathcal I_{ij}=[|R_{n+1}-R_n|\ge\vartheta]. \]

评注 (实现差异): 论文中定义了常量阈值 \(\vartheta\). 但在官方代码实现中, 此处使用了动态自适应阈值 \(\vartheta_{ij}^{\text{adj}} = \frac{\vartheta}{\sqrt{\text{EMA}(|\Delta R|/R)}+1}\). 代码按梯度衰减平滑来提供更鲁棒的滤波.

  时间滤波过滤掉了非运动脉冲, 不过它在空间上可能对噪声非常敏感. 为此, 我们在 \(\mathcal I_{ij}\) 的输出后再加入一层由 LIF 神经元构成的空间滤波. 神经元动力学满足

\[\tau_m\frac{\d v(t)}{\d t}=-\br{v(t)-v_{\t{rest}}}+R\mathbb I(t). \]

其中 \(v(t)\) 为膜电位, \(\tau_m\) 为膜时间常数, \(v_{\t{rest}}\) 为静息电位, \(R\) 为膜等效电阻 (recall: LIF 的建模), 而 \(\mathbb I(t)\) 是来自八连通区域的电流和 (含自己, 下同), 即

\[\mathbb I_{ij}(t)=\sum_{(a,b)\in\t{neighbor}(i,j)}\mathcal I_{ij}(t). \]

如果 \(v(t)\) 超过阈值 \(\Theta\), 神经元立即放电并立即回到静息电位.

评注 (实现差异): 论文公式描述的是连续时间的硬重置 LIF. 官方代码离散化采用了更高效且平滑的方式: 使用 \(3\times3\) 全为 \(3\) 的卷积核作为近邻感受野, 离散步进时无 spike 像素电压 \(-1\), 而触发阈值的神经元仅进行软重置 (v *= 0.8).

  加上这两层过滤, 我们就从脉冲相机的原始图像过滤出了稀疏, 去噪的运动相关脉冲图.

运动估计

  对每个像素, 我们定义 \(8\x4\) 个运动神经元用于感知八个方向的四种速度的运动, 运动模式 \(\bs m\) 定义为

\[\bs m=\sum_{k=1}^{32}w^k\bs v^k. \]

(注意上标只是 index 而非 power.) 其中 \(w^k\) 为突触权重, \(\bs v^k\) 是预设定的速度矢量.

评注 (实现差异): 论文中主张 \(8\times4=32\) 种模式, 在官方实现在中通常默认设定的速度类数为 \(2\) (即 speed=[1, 2]), 这产生了 \(8\times2=16\) 种模式组合. 此为论文宽泛与代码实现简化的差异.

  对每个神经元, 它有一个 \(3\x3\) 的感受野, 根据其预设的感知方向和速度, 我们能够预设出感受野中每个突触前神经元的理想激活时间, 也即用预设速度将图像整体位移, 越能保持时间一致性的预设速度的权重应当越大. (存疑: 离散模拟时 \(t\) 的意义是什么? 真的能用 \(\Gamma\) 这样的跳变函数来做 LTP 吗?)

\[\Delta w_x^k=\eta\frac{\kappa* A_x}{N_x},\\ A_x=\br{A_+\Gamma\br{t_{k,y}^{\t{pre}}-t_{k,y}^{\t{post}}}-A_-\abs{t_{k,y}^{\t{pre}}-t_{k,y}^{\t{post}}}}_{y\in\t{neighbor}(x)},\\ N_x=\sum_{y\in\t{neighbor}(x)}\Gamma\br{t_{k,y}^{\t{post}}-t}. \]

其中 \(\Gamma(x)=[x=0]\), \(\kappa\) 为二维高斯分布, \(\mu=1\).

评注 (实现差异): 这里回应了刚才的存疑. 代码实现没有使用严密的连续 \(\Delta t\) 函数求交. 它将其翻译成了极其实用的 "一帧前向位移对比": 把当前 \(S_t\) 按模式 \(k\) 发生仿射位移, 得到预测图 \(\hat{S}_t\). 若 \(\hat{S}_t=1 \land S_{t-1}=1\) 算作 LTP; \(\hat{S}_t=1 \land S_{t-1}=0\) 算作 LTD. 用这两者进行归一化池化来离散更新权重.

  然而, 单纯的 STDP 无法解决密集脉冲区域的运动混淆 (motion confusion) 问题. 为此, 我们在 STDP 神经元后加入 WTA (winner take all) 竞争机制来引入侧向抑制 (lateral inhibition), 它拥有比 STDP 更大的感受野, 如果发现感受野内的最强的运动

\[k_x^*:=\arg\max_k\sum_{y}w_y^k \]

与次大者的差距未达到给定阈值, 则抑制区域内所有运动模式. 最后将中心像素的运动模式输出为 \(k^*\).

注意力扫视

  我们用动态神经场 (dynamic neural field, DNF) 聚类来自每个物体的脉冲. 以 \(z\) 为空间坐标, \(t\) 为时间坐标, 动态估计层输出为 \(I^{\t{ext}}(z,t)\), 则本层神经元强度动力学描述为

\[\tau\dot u(z,t)=-u(z,t)+\int_{z'}J(z,z')r(z',t)\d z'+I^{\t{ext}}(z,t). \]

其中

\[J(z,z'):=\frac{J_0}{\sqrt{2\pi}a}\exp\br{-\frac{(z-z')^2}{2a^2}} \]

是一个 Gauss 分布;

\[r(z,t):=\frac{u_+(z,t)^2}{\int_{z'}u_+(z',t)^2\d z'} \]

为激活函数, \(u_+(z,t):=\opn{relu}(u(z,t))\).

  这样, 由于 \(r\) 中的 L2 归一化, 只有强脉冲 (\(I^{\t{ext}}\) 大) 的区域会形成自持续的稳定激活峰, 称为吸引子 (attractor). 感性上, 它将运动输出聚类为若干个不同强度的吸引子, 这些吸引子也会自然地随着物体的运动而运动, 并保持时空的对应关系, 以模拟生物眼动的注意力机制. 反过来, 为了追踪物体的移动, 我们就只需要追踪这些吸引子的移动.

评注 (实现差异): 官方实现里, DNF 被离散化为欧拉更新格式 \(U_{t+1}=U_t+\tau_u(\mathcal{J} * I_t + \mathcal{J} * r_t - U_t)\). 其激活函数的实现加入了平滑参数, 形态为 \(r_t = \frac{\max(0, U_t)^2}{1+\lambda \sum \max(0, U_t)^2}\).

  通过 simple yet unspecified 的处理, 我们能够框定一个吸引子对应物体的范围 \(\mathbb B(x,y,w,h)\), 并将这个区域内的 \(I^{\t{ext}}\) 展开为 \(\{0,1\}^{wh}\), 附加边界框坐标和尺寸等信息编码, 输入给下一层.

评注 (实现细节): 所谓 "simple yet unspecified 的处理",官方代码中即对 \(U_t > \text{Threshold}\) 取布尔掩码后执行连通域标记求边界框框选. 然后将框内裁剪为 \(31\times 31\) 特征并附加 4 行绝对位置对应的二进制编码, 共同输出进聚类网络.

在线追踪

  我们在这一步的目标是: 识别上一步框选的小区域内的脉冲特征向量 \(x_i(t)\), 为它分配正确的运动物体编号.

  不妨设注意力追踪层输出的向量维度为 \(n\). 我们首先引入一个 \(n\x K\) 的 WTA 聚类网络, 其中 \(K\) 是预设的最大可追踪目标数量. 网络是全连接的, 有权重 \(\{w_{ij}\}_{[1:K]\x[1:n]}\) 和偏置 \(\{b_i\}_{[1:K]}\) (即文中 \(\{w_{i0}\}\)). 网络输出

\[u_k(t)=b_k+\sum_{i=1}^n w_{ki}\cdot x_i(t). \]

输出神经元 \(z_k\) 的放电概率为

\[\Pr[z_k~\t{fires at}~t]\propto\opn{softmax}(u_{:}(t))_k. \]

我们规定同一时刻至多一个神经元放电. 这样, condition on \(t\) 时刻存在神经元放电, 则放电来自 \(z_k\) 的概率为

\[q_k(t)=\opn{softmax}(u_{:}(t))_k. \]

便能以此模拟离散时间步的放电情况.

评注 (实现差异): 虽然论文表述了泊松和 softmax 概率模型,但官方代码中利用 Gumbel-Max 采样 (\(k^* = \arg\max(W_k x + b_k + g_k), g_k\sim\text{Gumbel}\)) 来实现 WTA 等效随即抽签. 它简单, 快速且精准无偏地拟合了论文原本提出的 Softmax 分布.

\(t\) 时刻神经元 \(z_k\) 放电, intuitively, 我们的目标是:

  • \(z_k\) 更易被当前模式激发 (winner take!), 让其他神经元更难被当前模式激发.

因而, 只对放电的 \(z_k\), 我们更新上游权重

\[\Delta w_{ki}=\e^{-w_{ki}}x_i(t)-1,\quad w_{ki}^t=w_{ki}^{t-1}+\Delta w_{ki}. \]

它 (相对地) 强化了来自 \(x_i(t)=1\) 的贡献, 削弱了来自 \(x_i(t)=0\) 的贡献, 并保持权重的数值稳定性.

评注 (实现差异): 官方实现在 STDP 偏置/权重推导的基础上增加了一层工程防卫机制:更新的权重通常会向 \([-8, 1]\) 进行截断 (clamp) 防止突变过大发散,最后强制做一次 log-softmax 加速归一化收敛.

  对所有神经元 \(i\), 更新偏置 (注意 \(z_i=[i=k]\)):

\[\Delta b_i=\e^{-b_i}z_i-1,\quad b_i^t=b_i^{t-1}+\eta\Delta b_i. \]

同样, 它 (相对地) 让 \(z_k\) 更易激活, 让其他神经元更难激活.

  值得注意的是, 这种在线学习策略天然地适应物体的非平移运动 (例如旋转), 因为相邻帧之间的物体形态差别总是不大, 负责识别某一物体的神经元权重会渐变地学习这种变化过程.

  最后的基于运动预测的矫正和纠错机制比较简单: 如果上一帧位置 + 上一帧速度度得到的位置预测与当前检测位置的 IoU 过小, 我们就相信预测位置并回滚本次权重更新.


Reference

  • Zheng, Y., Li, C., Zhang, J., Yu, Z., & Huang, T. (2025). SNNTracker: Online High-speed Multi-Object Tracking with Spike Camera. IEEE Transactions on Pattern Analysis and Machine Intelligence (TPAMI).
  • CFXTGJD. (n.d.). snnTracker [GitHub repository]. Retrieved from https://github.com/CFXTGJD/snnTracker/
posted @ 2026-04-18 11:28  Rainybunny  阅读(205)  评论(0)    收藏  举报