0. 前言#
Depth Anything 是一种单目深度估计(Monocular Depth Estimation, MDE)的方法,旨在训练一个大模型,能够估计静态图像的深度图。由于数据量不够,Depth Anything V2 提出了构建大量伪样本训练的方法,从而提高了模型的性能。然而,Depth Anything 只对静态图像的效果好,对于连续帧的视频效果不佳,有闪烁等问题,因此 Video Depth Anything 就改进了 Depth Anything 的架构,从而实现了在视频上的优秀效果。
Depth Anything 的原论文:《Depth Anything: Unleashing the Power of Large-Scale Unlabeled Data》
Depth Anything V2 的原论文:《Depth Anything V2》
Video Depth Anything 的原论文:《Video Depth Anything: Consistent Depth Estimation for Super-Long Videos》
1. Depth Anything#
Depth Anything(DA)的核心思想是数据驱动。DA 旨在训练一个单目深度估计的基础模型(Foundation Model),而这需要大量的数据。但是在公共数据集中的数据不够多,于是文中提到可以利用大量无标注的单目图像数据与公共数据集中的少量有标注数据进行半监督学习。这种方法在 NLP 与 CV 领域十分常见,核心思想是:用海量无标注数据学习通用表征,用少量标注数据对齐具体任务。
具体来说,DA 收集了大量的无标注图像数据,并利用已有的深度估计模型(如 MiDaS)生成伪标签,同时利用公开数据集中的带有真值的有标注数据矫正伪标签的误差。使用这样一种基于知识蒸馏的半监督学习,既能保证模型的泛化性能,又能保持准确性。
然而文中发现,这种无脑堆数据的做法并不能提升原有模型的性能,虽然提升了数据量,但并不能激发模型的潜力。这是因为伪标签质量参差不齐,网络结构和训练方式也未能充分利用大规模的数据,无法在其中进行甄别,也就没有性能提升。打个比方来说,教师给了学生大量的带错题的习题集,学生又无法辨别对错,做再多的题也没有效果。
因此,DA 一方面在未标记数据中加入强扰动,让模型的训练任务更加困难;另一方面,使用一个冻结的 Encoder,保留语义特征,使得模型具有语义先验,辅助模型进行学习。这两个方法目的就是提升模型对数据的利用效率,激发模型的潜力。如下图所示:

浅色的 encoder 和 decoder 是待训练的学生模型,深色的 encoder 是冻结 encoder,能够获取图像的语义特征。实箭头代表有标签图像的流动路径,虚箭头则是无标签图像的流动路径。无标签图像流入模型 encoder 前需要加入扰动,提升模型的学习能力。有标签图像使用真值标签进行监督,无标签图像则利用预训练的教师模型产生的伪标签进行监督。
1. 有标签数据的训练#
首先需要使用有标签数据对教师模型进行训练。值得注意的是,教师模型并不是使用现成的模型,而是自己利用公开数据集进行训练的,过程类似于 MiDaS。
首先将深度取倒数投影到视差空间,之后进行归一化,采用仿射不变损失避免尺度问题。最后使用 DINO v2 预训练权重初始化 Encoder,再用一个预训练的语义检测模型,将天空视为无穷远。
2. 无标签数据的训练#
利用之前训练好的教师模型,先将大量的无标签数据输入,得到伪标签。之后,将有标签数据和伪标签数据混合,重新训练一个模型,之所以不对原来的教师模型进行微调是为了取得更好性能。
在训练模型时,对伪标签数据输入进行扰动。一种是强颜色失真,包括颜色抖动和高斯模糊,另一种是强空间失真。它迫使模型积极寻求额外的视觉知识,并从这些未标记的图像中获取不变的表示。
3. 语义辅助感知#
文中认为,其他任务的辅助监督对文中的半监督学习方法是有益的,因此选择提取语义特征作为辅助。然而采用离散的分类标签来进行语义分割并没有提升效果,而采用 DINO v2 的预训练权重的 Encoder 能够提升效果。因此将此 Encoder 权重冻结,只用于产生语义特征,并使用辅助特征对齐损失(auxiliary feature alignment loss)来辅助监督。
同时,DINO v2 对同一个物体的不同区域产生的语义特征相似,而对于深度估计来说并没有这样的相似关联,因此辅助特征对齐损失并不应该起决定性作用。
2. Depth Anything V2#
原来的 DA 的教师模型也是由真值数据训练出来的,而真值数据也存在不准确的标签以及粗糙的细节,产生的无标签数据的伪标签也只能达到一定的准确性。因此模型训练的上限被数据的精度所限制。
从模型架构的角度来说,深度估计任务一类基于判别模型(如 BEiT、DINO v2 和 DepthAnything),一类基于生成模型(如 Stable Diffusion 和 Marigold)。通过对比,可以看出 Marigold 在细节建模方面更胜一筹,而 Depth Anything 则对复杂场景产生更可靠的预测。如图:

为了提升模型的精度,文中依然秉承数据驱动的思想,旨在提升数据的精度和质量,并进一步提升数据规模,从而提升模型的精度和性能。于是,文中提出使用合成数据来代替真实数据训练教师模型,再使用具有伪标签的真实图像训练学生模型。
1. 真实标注数据的缺点#
标签噪声,即深度图中的标签不准确,并且容易忽略深度图中的细节。
由于各种收集程序固有的局限性,真实标记的数据不可避免地包含不准确的估计。这种不准确性可能由多种因素引起,例如:深度传感器无法准确捕获透明物体的深度,立体匹配算法对无纹理或重复图案的脆弱性,SfM 方法在处理动态对象或异常值方面的易感性等。这些真实数据集也经常忽略其深度图中的某些细节,难以在物体边界或细孔内提供详细的监督,导致深度预测过度平滑,使得模型也无法学习到细节。
2. 合成数据的优缺点#
合成数据的深度标签非常精确,所有精细细节(例如,边界、细孔、小物体等)都正确标记,即使是所有薄网状结构和叶片都标注了真实深度,同时也可以获取透明物体和反射表面的实际深度。如图:

然而,合成数据之所以没有大范围普及,正是因为它比较完美。合成数据的画面过于干净有序,没有噪声和随机性,与真实世界的分布有所差异。其次,合成数据的来源比较少,覆盖场景少,对真实世界的泛化能力差。
若使用真实数据和合成数据联合训练,真实数据的噪声会使细粒度预测效果很差;若要采集更多的合成数据模拟真实数据,数据量又远远不够,合成引擎也无法生成各种场景。
3. 解决方案#
真实数据的标签精度差,而纯合成数据又太少,于是文中提出一种想法:将大量的无标签真实数据赋予合成标签,这样技能解决合成数据量不够的问题,还能提高真实数据的精度。
这种想法的具体做法也很简单:当前最强大的 MDE 模型 DINO v2-G 最初纯粹是根据高质量的合成图像进行训练的,因此精度很高。输入大量无标签的真实图像,让它在这些未标记的真实图像上分配伪深度标签。最后,仅使用大规模和精确伪标记的图像训练新的模型。
文中的方法并不是纯粹的知识蒸馏,而是利用教师模型赋予伪标签,再利用大量数据训练学生模型,通过伪标签来传递知识,这种方法比起学习教师模型的特征和分布更加稳定。这种方法相当于在真实数据和合成数据中搭了一座桥梁,选择了一种折中的方法。
对于小模型来说,使用合成数据训练然后预测真实数据的效果是不好的。但 DINO v2-G 是参数量很大的一个大模型,通过标签的传递进行知识蒸馏,这样得到的小模型效果就要好很多。
训练过程与 Depth Anything V1 基本一致,使用两个损失对标记图像进行优化:尺度和移位不变损失(scale-and-shift-invariant loss)和梯度匹配损失(gradient matching loss),这两个损失是由 MiDaS 提出的,但值得注意的是,使用合成图像时,梯度匹配损失对深度清晰度非常有效。
4. DA 2K#
DA 2K 是文中提出的新 Benchmark,作者认为广泛应用的 Benchmark 也是有噪声的,并且分辨率低、场景少,不满足现代的要求,于是提出了新的 Benchmark。
目标是构建一个通用的相对单眼深度估计评估基准,它可以提供精确的深度关系,覆盖广泛的场景,以及主要包含供现代使用的高分辨率图像。
3. Video Depth Anything#
现有的单目深度估计模型已经达到了不错的效果,但只能处理单帧图像。对于连续帧的视频,预测会出现闪烁和动态模糊。
现有的方法中,一种方法是设计一个即插即用模块,以增强具有时间一致性的单眼深度模型预测。这种模块的训练高度依赖于光流(optical flow)或相机位姿(camera poses)的一致性约束,使得模块容易受到相应的误差的影响。
另一种方法将预训练的视频扩散模型重新利用为视频深度模型。这些方法擅长生成细粒度细节,但计算效率低,无法利用现有的深度基础模型,并且只能处理长度有限的视频。
为了解决泛化性和长视频的深度估计问题,本文提出了 Video Depth Anything(VDA)方法,继承了 DA v2 的基础模型,并在输出头部分做了改动,使之在时间上具有相关性;并且提出了一种新的分段处理策略(segment-wise processing strategy),用于推理时处理超长视频。
1. 网络架构#

回顾 DA v2 的思路:由于无标签数据很多,而合成数据较少,于是将二者结合,借助合成数据的伪标签来训练无标签数据。VDA 的思路也有相似之处,由于数据集中视频深度标签很少,而单帧图像深度标签较多,于是将视频和图像同时输入到网络中训练。
为了使用图像 encoder 从视频帧中提取特征,文中将视频片段的时间维度折叠为批处理维度,即将多帧图像当作一个 batch 的单帧图像。尽管图像 encoder 从单个帧中提取了多尺度特征,但它忽略了帧间的时序信息交互。因此,引入时空头(Spatiotemporal Head)来模拟各帧之间的时间关系。
对于静态图像的训练与 DA v2 基本一致,是利用一个教师模型生成伪标签,从而进行训练;而对于视频的训练是采用真值来训练的。
2. 时空头#
时空头(Spatiotemporal Head, STH)建立在 DPT 头上,在 Depth Anything 中,解码器采用的是 DPT 头的 Reassemble + Fusion 结构,而 VDA 中则在其中插入时间层(Temporal layer)来捕获时间信息,时间层由多头自注意力模型和前馈网络组成。

如图,时空头从 encoder 编码的多尺度特征中均匀采样 4 个特征图(F1-F4)作为输入,然后将这些特征各自输入到重组层(Reassemble)中,重新映射到统一的维度和分辨率,以生成特征金字塔;然后,通过融合层(Fusion)将特征从低分辨率逐渐融合到高分辨率,逐渐恢复出高分辨率的深度图。
在低分辨率特征层中会插入时间层(Temporal layer),将特征输入时间层时,仅沿时间维度执行自注意力,以促进时间特征的交互。为了捕捉不同帧之间的时间位置关系,文中利用绝对位置嵌入对视频序列中的时间位置信息进行编码。简单来说,就是视频的多个帧之间具有时序关系,时间层在低分辨率特征层插入,做时序自注意力。但注意力机制是无序的,需要告诉模型某个特征属于哪一帧,即时间位置编码(Temporal Positional Encoding)。
3. 时间梯度匹配损失#
既然得到了帧间时间特征的关系,就要具有合理的监督约束。之前的方法基于光流变形(optical flow warping)来构建帧间位置的监督。具体来说,光流(optical flow)指的是像素点随时间移动的表观速度场,对于每个像素来说,就是它在下一帧的位置偏移向量。而变形(warping)指的是利用光流场把一帧的图像变换到另一帧的坐标系下,是一种映射。这种损失称为 OPW loss(Optical Flow based Warping loss)。
然而,OPW 存在一个问题,它要求前后两帧的像素点是一致的。对于深度图来说,要求前后两个深度是不变的,才能构建两帧间的联系。然而,同一个位置的深度在下一帧同样可能变化,因此这种监督损失是不合理的。
于是,文中提出一种监督损失,时间梯度匹配损失(Temporal gradient matching loss, TGM)。这里不再假设相邻帧间深度不变,而是假设相邻帧的深度变化与真值相同,从而保证跨帧相对变化的一致性。
为了避免使用光流导致开销过大,文中直接使用相同位置像素的深度变化来计算损失,这对损失函数的值并无太大影响。
4. 超长视频的推理策略#
当处理超长视频时,可能有几千或几万帧,如果直接把这些帧全部送入模型中,由于显存有限,GPU 无法同时存储这么长的特征,并且时序关系难以捕捉,因此就需要恰当的分割和拼接。然而如果分段(clip)进行推理,不同的段间的拼接可能会有尺度偏移或不连续的问题。
于是文中提出,分段推理并保留重叠帧,作为参考帧来对齐深度。如图:

蓝色的部分是已经推理过的上一个片段,长度为 N;黄色的部分是当前待推理的部分,长度为 N - T0 - Tk。T0 部分是两个片段间的重叠帧,用于对齐深度,承上启下。Tk 部分是前一个片段的关键帧(key frame),用于跨片段的尺度对齐。推理结束后,根据重叠帧进行拼接,保证深度的平滑过渡,避免闪烁和尺度漂移。
4. 参考文献#
1.Depth Anything v1 and v2 - 知乎
2.单目深度估计—Depth Anything论文详解-CSDN博客
3.ChatGPT