微信扫一扫,关注公众号

  • 科技行者

  • 算力行者

见证连接与计算的「力量」

首页 FreeFlow:一个不靠"偏见"吃饭的光流估计模型

FreeFlow:一个不靠"偏见"吃饭的光流估计模型

2026-10-14 20:48
分享至:
----..---.-...-/--...-.-......./-...-....-..--../-............-.- ----..---.-...-/--...-.-......./-...-....-..--../-............-.- ----..---.-...-/--...-.-......./-...-....-..--../-............-.- ----..---.-...-/--...-.-......./-...-....-..--../-............-.-
2026-10-14 20:48 • 科技行者

2015年,一个叫FlowNet的模型第一次证明了神经网络能直接学会预测光流。

**光流**:描述视频中每个像素从一帧到下一帧移动方向和距离的技术,是自动驾驶、视频修复、动作识别等一大堆应用的底层基础。

这本该是个好消息,深度学习又一次用简单粗暴的办法碾压了传统方法。可接下来发生的事有点反直觉:整个领域并没有沿着"越简单越好"的方向走下去,反而越做越复杂。RAFT引入了迭代优化和全局相关性体积,PWC-Net把金字塔、特征扭曲、局部相关体积全部塞进模型,后续的方法在这个基础上继续叠加遮挡处理、时序线索、各种训练技巧。到了2024年前后,一个能打的光流模型往往意味着一套相当复杂的流水线:你得算相关性体积,得做特征扭曲,得设计迭代更新机制,还得考虑怎么把预测结果上采样回原始分辨率。

这就是这篇论文要挑战的现状。FreeFlow的作者们提出一个听起来有点冒犯的问题:这些东西真的都是必需品吗,还是说,我们只是在过去十年里习惯了给光流模型加"作弊码"?

光流估计到底难在哪

想弄清楚FreeFlow的野心,得先明白光流这件事本身的难点。

给你两张连续的视频帧,你要算出画面里每一个像素点从第一帧到第二帧挪到哪去了。这事听起来简单,实际上有两个互相拧巴的要求。

第一,你得看清楚细节。一根树枝的边缘、一个人手指的轮廓,这些细微结构如果处理不好,光流场里就会出现毛边和错位,尤其是在运动边界的地方。第二,你还得看得远。如果画面里有个东西移动得特别快,比如一辆疾驰的车或者一次挥拳,那对应的像素在第二帧里可能已经跑到了画面的另一端,这时候局部信息完全不够用,你需要模型有能力在整张图里"搜索"这个像素到底跑哪去了。

**局部信息**:只关注图像中一小块区域的细节特征,比如某个像素周围8x8范围内的纹理和颜色。

**全局信息**:整张图像范围内的关联性,能捕捉到相隔很远的两个区域之间的对应关系。

传统方法处理这个矛盾的思路是"分而治之":用相关性体积(correlation volume)暴力枚举所有可能的匹配位置,再用迭代更新机制一步步修正预测结果,外加卷积上采样把低分辨率的预测放大回原图大小。RAFT就是这套思路的代表,效果确实好,但每一个环节都是针对光流这个任务量身定做的,换个任务基本用不上。

**相关性体积**:把第一帧里每个像素和第二帧里所有候选位置的相似度都算一遍,存成一个巨大的表格,本质上是暴力搜索。

这种做法就像你找钥匙时,不是凭记忆去想上次放在哪了,而是把家里每一个抽屉、每一个角落都翻一遍,记录下每个地方有没有钥匙的可能性,然后再根据这份记录去判断钥匙最可能在哪。这样做准确率确实高,但代价是你得把整个"翻找过程"设计成一套复杂机制,而且这套翻找逻辑只适用于"找钥匙"这一件事,换成"找眼镜"就得重新设计一遍流程。

FreeFlow想干的事,是让模型自己学会怎么找,而不是替它把搜索流程写死。

三种注意力,一套拼图

FreeFlow的核心思路是用一个统一的Transformer架构,同时兼顾"看细节"和"看得远"这两个需求。

**Transformer**:一种依靠"注意力机制"处理序列数据的神经网络架构,最早用在自然语言处理,后来被大量应用到视觉领域,能让模型自主学习数据之间的关联,而不依赖手工设计的规则。

具体做法是把每张输入图片切成8×8像素的小方块,这些小方块叫做**patch**(图像块),每个patch被编码成一个向量,也就是**token**(词元,本质是模型能理解的最小信息单元)。整张图切完之后,会变成一堆token组成的序列,模型接下来就在这堆token上做各种注意力计算。

FreeFlow用了三种注意力方式,轮流交替处理这些token。

第一种叫窗口注意力。它把整张图的token网格切成4×4共16个不重叠的小窗口,每个窗口内部做注意力计算,窗口之间互不通信。这一步负责处理局部细节,比如一根树枝的走向、一个物体边缘的形状。

第二种叫移位窗口注意力。既然窗口是死的,那相邻两个窗口边界处的信息就传不过去。解决办法很直接:把窗口整体挪半个身位再重新划分一次,这样原来处于两个窗口交界处的token,现在被划进了同一个窗口里,就能互相"看到"对方了。

这两种设计合在一起,像极了小区物业分片打扫卫生。如果永远按同一种划分方式分片,那两个片区交界的走廊角落永远没人管,因为两边的保洁员都觉得那不归自己负责。移位窗口相当于每隔一段时间重新划一次片区边界,让原来的"三不管地带"总能被某个片区完整覆盖到。如果不做这个移位操作,会发生什么?窗口边界附近的运动信息会被硬生生切断,模型没法知道一个跨越窗口边界的物体到底该怎么连续运动,光流场里就会在窗口交界处出现明显的接缝。

第三种叫全局注意力,专门负责"看得远"这件事。做法是先把特征图下采样2倍,缩小分辨率之后做一次全图范围的完整注意力计算,再上采样回原来的大小。这一步的目的是让模型能捕捉到跨越整个画面的运动关系,比如画面一角的物体快速冲到另一角。

三种注意力按照固定顺序:窗口、移位窗口、全局,在编码器和解码器里反复堆叠。

FreeFlow整体架构沿用了CroCo系列模型的编码器解码器结构:两张输入图片各自过一遍共享权重的孪生编码器,得到两组特征,然后送进解码器。解码器里每一层既做自注意力(处理当前特征内部的关系),也做交叉注意力(让第一帧的特征去"查询"第二帧的特征,找到对应关系)。最后解码出来的token经过一个很简单的三层卷积头,直接映射成稠密的光流场,不用迭代、不用卷积上采样这类专门设计的机制。

![](https://via.placeholder.com/图3示意图:整体流程)

论文里有张图对比了三种处理高分辨率图像的策略,很能说明问题。第一种是像CroCo、FlowFormer那样,把大图切成很多块分别预测,最后拼接平均,这种做法的毛病是各个图块之间在特征提取阶段完全没有交流,只有最后结果层面的简单平均,遇到跨越多个图块的大幅度运动就抓瞎了。第二种是像DepthPro那样,做多尺度特征提取,但只在解码器最后阶段融合各个尺度的信息,全局上下文来得太晚,可能根本传不到最终的高分辨率输出里。FreeFlow选的是第三种路线,密集特征融合,在整个网络的每一层里都反复进行跨图块和全局的信息交换,而不是攒到最后才交换一次。

这就好比写一篇多人协作的报告。如果每个人只顾埋头写自己那部分,最后拼在一起才发现前后逻辑对不上,这是第一种策略的毛病。如果大家先各自写完初稿,最后开一次会统一一下口径,这是第二种策略,比不沟通强,但很多细节层面的不一致已经很难改了。FreeFlow相当于要求写作过程中每写几段就互相看一眼对方写了什么,随时校准,这样才能保证最后拼出来的报告既有细节又前后连贯。

位置编码和注意力的小心机

除了三种注意力的搭配,FreeFlow还用了两个细节设计,虽然不起眼,但对高分辨率场景下的表现有实打实的影响。

第一个是**RoPE**(旋转位置编码),用来告诉模型每个token在图像里的空间位置。

第二个是注意力缩放因子的调整。作者发现,如果直接沿用训练时的注意力计算公式去做更高分辨率的推理,模型的泛化能力会打折扣。他们借鉴了此前MemFlow论文里的做法,给注意力的计算结果乘上一个和token数量的对数相关的缩放系数,且没有像之前的做法那样把这个系数归一化到训练时等于1,而是直接用未归一化的版本,作者说这样效果反而更好。

这个操作解决的问题是:模型在训练时可能只见过较低分辨率的图像,但实际部署时经常要处理更高分辨率的输入,如果不做任何调整,注意力权重的分布会因为token数量变化而"跑偏",导致模型在高分辨率场景下表现下降。

训练怎么练出来的

FreeFlow的训练分为两大阶段:先做跨视角补全预训练,再针对光流任务做微调。

**跨视角补全**:给模型看同一场景的两张不同视角照片,故意把其中一张的大部分区域遮住,让模型根据另一张完整的图去猜被遮住的部分长什么样。这种自监督预训练方式最早由CroCo系列论文提出,好处是能逼着模型学会理解两张图之间的对应关系,这恰好是光流任务最核心的能力。

预训练阶段用了ARKitScenes、MegaDepth、3DStreetView三个数据集,一共370万个样本,图像裁剪成224×224的固定尺寸,训练346000步。FreeFlow和原始CroCo在这一步上有个细节差异:CroCo是把被遮住的图像块直接从编码器输入里移除,只在解码器阶段补回学习到的占位符;FreeFlow由于是分层结构,选择在编码器输入阶段就把被遮住的区域替换成占位符。

微调阶段的数据配方参考了MEMFOF论文的做法,混合使用TartanAir、FlyingThings3D、Sintel、KITTI-2015、HD1K五个数据集,按照特定比例采样。这里有个值得一提的技巧:不是用固定尺寸裁剪图像,而是给每个训练样本定一个固定的token数量预算,随机决定要用哪个维度(高或宽)作为主变量,另一个维度就取能凑满token预算的最大值。这样每个训练样本的长宽比都不一样,既避免了不必要的填充浪费,也让模型见识过更丰富的运动范围。

整个训练流程,最大的模型版本在32块GPU上大约需要4到5天预训练,加上3天左右的微调。

跑分结果:三个主流榜单全部拿下

FreeFlow在三个业界公认的光流评测基准上都刷到了当时最好的成绩。

在Spring数据集上,FreeFlow-L的表现全面压制此前的各路强手:

| 方法 | 1px误差↓ | EPE↓ | Fl误差↓ |

|---|---|---|---|

| WAFT-DAv2-a2 | 3.298 | 0.304 | 1.197 |

| MEMFOF | 3.289 | 0.355 | 1.238 |

| **FreeFlow-L** | 3.192 | **0.278** | **1.048** |

**EPE**(端点误差):预测的运动向量和真实运动向量之间的欧氏距离平均值,数值越小说明预测越准。

**1px误差率**:预测位置和真实位置偏差超过1个像素的比例,同样越小越好。

对比WAFT-DAv2-a2,FreeFlow-L在EPE上提升了9%,Fl误差降低了14%。更值得说的是,FreeFlow实现这个成绩的方式是原生1080p分辨率推理,不需要切块处理,同时内存占用还控制得很低,2.58GB左右,这在同类高精度模型里算是相当克制的数字。

在Sintel数据集上,FreeFlow-L拿下Clean和Final两个子集的第一名,Clean子集EPE只有0.68,比此前最好的GeoViT(0.79)提升了14%;Final子集EPE是1.48,比VideoFlow-MOF的1.65提升了10%。

**Sintel数据集**:一个基于开源动画短片制作的光流评测基准,包含大量复杂运动和渲染特效场景,Clean版本画面干净,Final版本加入了模糊、雾气等真实感渲染效果,难度更大。

在KITTI-2015真实驾驶场景数据集上,FreeFlow-L的Fl-all误差是3.23,在不使用立体视觉和多帧输入的方法里排名第一。

值得一提的是,FreeFlow并不是靠堆参数硬刚出来的成绩。论文里对比了模型规模和内存消耗的关系,FreeFlow-S这个最小版本只有35M参数,1080p推理只需要1.02GB内存,却已经能打过不少参数量大得多的竞品。这说明FreeFlow这套架构的效率优势不是靠砸算力堆出来的,而是设计本身就比较高效。

拆掉每一块积木,看看哪块最重要

论文做了大量消融实验,逐一验证每个设计选择的必要性。

其中一个很有意思的发现是关于预训练时的遮挡比例。CroCo系列论文默认用0.9的遮挡比例(也就是90%的图像块被遮住),但FreeFlow发现,由于它用的patch比CroCo小(8×8对比16×16),可见区域和被遮区域的距离更近,任务难度天然更低,所以需要更高的遮挡比例才能让预训练任务保持足够的挑战性。实验显示0.95的遮挡比例效果最好,比默认的0.9在1px指标上提升9.3%,EPE提升7.6%。

更有意思的是,遮挡比例和全局注意力模块之间存在某种耦合关系。在遮挡比例是0.9时,去掉全局注意力模块反而对指标没什么影响,甚至略有提升;但在0.95的遮挡比例下,全局注意力就变得必不可少了。作者据此提醒,遮挡比例这个超参数不能孤立地调,得跟模型架构一起考虑。

这个现象其实很好理解。遮挡比例低的时候,模型靠局部信息就能大致猜出被遮住的区域长什么样,全局信息锦上添花但不是刚需;遮挡比例一旦拉高,可见区域变得稀少且分散,这时候没有全局视野的模型就像戴着眼罩在陌生房间里摸索,只能碰到什么算什么,而有全局视野的模型相当于先站在门口扫一眼整个房间的布局,再开始找东西,效率天差地别。

移位窗口注意力这个设计在所有消融配置里都稳定带来提升,去掉它会导致指标明显下滑,说明跨窗口的信息交流确实是刚需,不是可有可无的锦上添花。

论文还做了一个很扎实的对照实验,专门验证FreeFlow的架构设计到底是不是真正起作用的部分,而不是训练技巧在起作用。他们训练了一个把FreeFlow的编码器解码器换成普通ViT(不分窗口,直接全局注意力)的对照版本,结果显示,即便普通ViT版本用了更大的计算预算(270到410毫秒对比FreeFlow-S的131毫秒),预测误差依然更高,而参数量相近的FreeFlow和ViT版本比起来,ViT要慢将近6倍才能达到接近的效果。这个结果说明局部全局分层注意力这个设计本身确实在起作用,不只是训练配方凑巧调对了。

作者还反过来做了个实验,往FreeFlow里重新加回一些经典的光流"偏见",比如借鉴GeoViT的迭代式特征扭曲机制。结果显示加了这些机制之后,在某些配置下确实能拿到更好的精度,但代价是推理速度变慢、架构变得不再通用。这个结果挺诚实的,说明FreeFlow team没有回避"加偏见确实能提升精度"这个事实,只是想证明不加偏见也能达到SOTA水平,加不加是一个效率和精度之间的权衡,而不是非黑即白的对错问题。

零样本泛化:一个诚实的短板

论文也没回避FreeFlow目前的局限。在零样本迁移实验里,也就是只用TartanAir和FlyingThings3D这两个数据集训练,然后直接拿去Sintel和KITTI上测试,FreeFlow的表现没有随着模型规模增大而单调提升,这和主榜单上"越大越强"的规律不太一致。

作者的解释是,这种数据受限场景下,迁移效果主要取决于训练数据本身覆盖的运动和场景多样性,光靠加大模型容量并不能弥补数据覆盖面的不足。对比之下,用Kinetics-400大规模视频数据集预训练过的GeoViT在零样本Sintel上表现最好,说明预训练数据的广度对泛化能力影响很大,而这恰恰是FreeFlow目前预训练数据规模相对有限(CroCo v2的740万帧)的地方。

这就像一个只在教科书例题上刷过题的学生,和一个刷过大量社会真实场景练习题的学生,前者在考试遇到课本里没见过的题型时,表现会明显更不稳定,哪怕这个学生的"脑子"(模型容量)比另一个更大。如果不扩充训练数据的多样性,单纯把模型做大,解决不了泛化能力的问题。

写在后面

读完这篇论文,最让我意外的地方不是它刷新了几个榜单,而是它证明了一件更基础的事:过去十年光流领域默认的那些"标配",比如相关性体积、迭代优化、特征扭曲,其实更像是特定历史阶段下研究者们摸索出来的经验性技巧,而不是这个任务本身在数学上必须依赖的东西。

这让我想起一个更普遍的现象。很多领域在发展初期都会积累一堆"祖传配方",后来者往往默认这些配方是必需的,因为前人一直这么用而且确实有效,但很少有人回过头去问一句:如果把这些配方一个个拿掉,会怎么样?FreeFlow做的就是这件"拿掉再看看"的事,而结果证明,只要给模型足够合理的架构设计和预训练方式,很多手工设计的机制其实是可以被学出来的能力替代的。

论文里那个关于遮挡比例和全局注意力耦合关系的发现,其实比主榜单成绩更值得琢磨。它提示我们,一个架构的各个组件之间不是孤立可以调的,某个超参数在一种架构下无关紧要,换一种架构可能就变得性命攸关。这种"整体性"思维,其实在很多复杂系统的设计里都成立,只是我们经常不自觉地把系统拆开来单独调试,而忽略了组件之间的耦合关系。

还有一个问题我没在论文里找到答案,但很想追问:FreeFlow现在用的预训练数据规模(740万帧)相比GeoViT用的Kinetics-400(约5900万帧)小了差不多8倍,如果把FreeFlow的预训练数据也扩到同样规模,它的零样本泛化能力会不会补齐这个短板?如果补齐了,那是不是意味着"去掉所有光流偏见"这条路线,未来完全有可能在数据足够的情况下全面超越那些带着专门设计的模型?这大概是留给后续研究者的一个很实在的题目。

Q&A

Q1:FreeFlow是什么?

A:FreeFlow是一个不依赖传统光流专用设计(比如相关性体积、特征扭曲、迭代优化)的分层Transformer模型,用窗口注意力、移位窗口注意力和全局注意力三种机制组合,实现了在Sintel、KITTI-2015、Spring三大光流基准上的最优表现。

Q2:FreeFlow相比之前的光流模型有什么优势?

A:FreeFlow在保持高精度的同时大幅降低了推理内存消耗,比如最小版本FreeFlow-S仅需1.02GB内存就能完成1080p分辨率推理,且架构更简单通用,不像RAFT等模型依赖复杂的专用流水线。

Q3:FreeFlow的训练分几个阶段?

A:分两大阶段,先在跨视角补全任务上做预训练,让模型学会理解两张图之间的对应关系,然后再用光流数据集针对性微调,整个流程在32块GPU上大约需要7到8天。

分享至
0赞

好文章,需要你的鼓励

推荐文章
----..---.-...-/--...-.-......./-...-....-..--../-............-.- ----..---.-...-/--...-.-......./-...-....-..--../-............-.- ----..---.-...-/--...-.-......./-...-....-..--../-............-.- ----..---.-...-/--...-.-......./-...-....-..--../-............-.-