VideoMAE v2:使用双重掩码扩展视频掩码自编码器

文章目录

  • 一、前言
  • [二、VideoMAE v2:使用双重掩码扩展视频掩码自编码器](#二、VideoMAE v2:使用双重掩码扩展视频掩码自编码器)
  • 三、架构
    • [图1: VideoMAE V2 双重掩码机制](#图1: VideoMAE V2 双重掩码机制)
    • 一、故事开场:视频是怎么被"切"进模型的?
      • [1.1 输入视频:一段原始视频](#1.1 输入视频:一段原始视频)
      • [1.2 Cube Embedding:把视频切成"时空小方块"](#1.2 Cube Embedding:把视频切成"时空小方块")
    • [二、第一幕:Tube Masking(Encoder 端,90% 被涂黑)](#二、第一幕:Tube Masking(Encoder 端,90% 被涂黑))
      • [2.1 什么叫 Tube Masking?](#2.1 什么叫 Tube Masking?)
      • [2.2 为什么用"管子"而不是随机点?](#2.2 为什么用"管子"而不是随机点?)
    • [三、第二幕:Encoder 内部------用 10% 的碎片理解世界](#三、第二幕:Encoder 内部——用 10% 的碎片理解世界)
      • [3.1 Encoder 的输入](#3.1 Encoder 的输入)
      • [3.2 Encoder 内部在做什么?](#3.2 Encoder 内部在做什么?)
    • [四、第三幕:Running Cell Masking(Decoder 端,再次筛选)](#四、第三幕:Running Cell Masking(Decoder 端,再次筛选))
      • [4.1 90% 被遮住的区域,现在要被"二次审判"](#4.1 90% 被遮住的区域,现在要被"二次审判")
      • [4.2 为什么叫"Running Cell"?](#4.2 为什么叫"Running Cell"?)
      • [4.3 为什么再次丢弃 45%?](#4.3 为什么再次丢弃 45%?)
    • [五、第四幕:C 处的融合------"把线索和填空题拼在一起"](#五、第四幕:C 处的融合——"把线索和填空题拼在一起")
      • [5.1 融合前有什么?](#5.1 融合前有什么?)
      • [5.2 灰色方块到底是什么?](#5.2 灰色方块到底是什么?)
      • [5.3 C 处的操作:拼接(Concatenate)](#5.3 C 处的操作:拼接(Concatenate))
      • [5.4 为什么要拼接?](#5.4 为什么要拼接?)
    • [六、第五幕:Decoder 内部------"做填空题"](#六、第五幕:Decoder 内部——"做填空题")
      • [6.1 Decoder 的输入](#6.1 Decoder 的输入)
      • [6.2 Decoder 内部在做什么?](#6.2 Decoder 内部在做什么?)
      • [6.3 输出:Reconstructed Pixel(粉色方块)](#6.3 输出:Reconstructed Pixel(粉色方块))
    • 七、第六幕:损失函数------只算"被选中的填空题"
      • [7.1 损失计算范围](#7.1 损失计算范围)
      • [7.2 谁不算损失?](#7.2 谁不算损失?)
      • [7.3 为什么这样设计?](#7.3 为什么这样设计?)
    • 八、第七幕:训练流程------三阶段"渐进式毕业"
      • [阶段 1:大规模无监督预训练(Pre-training)](#阶段 1:大规模无监督预训练(Pre-training))
      • [阶段 2:有监督后预训练(Post-pretraining)](#阶段 2:有监督后预训练(Post-pretraining))
      • [阶段 3:下游任务微调(Fine-tuning)](#阶段 3:下游任务微调(Fine-tuning))
    • 九、第八幕:推理流程------"毕业后的工作"
      • [9.1 丢弃 Decoder,只用 Encoder](#9.1 丢弃 Decoder,只用 Encoder)
      • [9.2 为什么能扔掉 Decoder?](#9.2 为什么能扔掉 Decoder?)
      • [9.3 推理时的数据流](#9.3 推理时的数据流)
      • [9.4 为什么推理不用掩码?](#9.4 为什么推理不用掩码?)
    • [十、大结局:Dual Masking 的完整故事线](#十、大结局:Dual Masking 的完整故事线)
    • 十一、为什么这个设计能训练出十亿参数的模型?

一、前言

仅供参考,未经实验验证。

二、VideoMAE v2:使用双重掩码扩展视频掩码自编码器

一、论文基本信息

项目 内容
论文标题 VideoMAE V2: Scaling Video Masked Autoencoders with Dual Masking
作者 Limin Wang, Bingkun Huang, Zhiyu Zhao, Zhan Tong, Yinan He, Yi Wang, Yali Wang, Yu Qiao
机构 南京大学 (Nanjing University)、上海人工智能实验室 (Shanghai AI Lab)、中国科学院 (CAS)
发表会议 CVPR 2023 (IEEE/CVF Conference on Computer Vision and Pattern Recognition)
会议页码 Pages 14549--14560
arXiv 2303.16727
GitHub 仓库 https://github.com/OpenGVLab/VideoMAEv2

二、研究背景与动机

VideoMAE V2 是 VideoMAE (NeurIPS 2022) 的续作。随着视觉基础模型(Foundation Model)的兴起,模型规模(Scale) 成为构建强大泛化能力模型的关键因素。然而,训练具有 十亿级参数(billion-level) 的视频基础模型仍面临巨大挑战:

  1. 计算瓶颈:视频数据的高维度特性使得 Transformer 的计算和内存开销极为庞大。
  2. 数据稀缺:高质量、大规模的视频预训练数据相对图像领域更为匮乏。
  3. 训练效率 :原始 VideoMAE 虽然通过高掩码率(90%)显著降低了 Encoder 的计算量,但 Decoder 仍需处理全部 token,成为新的瓶颈。

三、核心方法

1. Dual Masking(双重掩码策略)

这是 VideoMAE V2 最核心的创新。作者在 Encoder 和 Decoder 两侧同时引入掩码,进一步挖掘视频数据的冗余性以提升训练效率:

  • Encoder Masking :沿用 VideoMAE 的 Tube Masking(时空管状掩码),以极高比率(如 90%)掩码,仅将可见 token 输入 Encoder。
  • Decoder Masking :提出 Running Cell Masking(运行单元掩码),在 Decoder 输入端再次对 token 进行掩码。Decoder 只处理 Encoder 输出特征与部分可见 token 的组合,而非全部 token。
  • 损失计算 :MSE 损失仅作用于 同时被 Encoder 和 Decoder 掩码的 token (即 M e ∩ M d M_e \cap M_d Me∩Md),既保证了重建难度,又大幅减少了计算量。

效率提升效果(相比仅 Encoder Masking):

模型 FLOPs 内存 训练时间 加速比
ViT-B 35.48G → 25.87G 631M → 328M 28.4h → 15.9h 1.79×
ViT-g 263.93G → 241.61G 1753M → 1050M 356h → 241h 1.48×

2. Progressive Training(渐进式训练范式)

为了适配更大规模的模型和数据,作者提出三阶段渐进训练策略:

  1. 无监督预训练 :在 UnlabeledHybrid (约 135 万 视频,来自 Web、YouTube、Instagram、Movies 等多源数据)上进行大规模自监督预训练。
  2. 有监督后预训练(Post-pretraining) :在 LabeledHybrid(Kinetics-400 + Kinetics-600 + Kinetics-700 混合标签数据集)上进行中间监督训练,作为从大规模无监督到小规模下游任务的桥梁。
  3. 下游任务微调:在目标数据集上进行最终微调。

3. 模型扩展(Model Scaling)

借助 Dual Masking 带来的效率提升,VideoMAE V2 首次成功将视频掩码自编码器扩展到 ViT-giant(ViT-g) 级别,达到 十亿参数规模,这在视频自监督预训练领域属于开创性工作。


四、主要实验结果

VideoMAE V2 在多个主流视频理解基准上取得了 SOTA(State-of-the-Art) 性能:

数据集 任务类型 性能
Kinetics-400 动作分类 90.0% Top-1
Kinetics-600 动作分类 89.9% Top-1
Something-Something V1 动作分类 68.7% Top-1
Something-Something V2 动作分类 77.0% Top-1
AVA 时空动作检测 SOTA
THUMOS14 / FineAction 时序动作检测 SOTA

此外,论文还验证了模型在 动作分类、动作检测、时序动作检测 等多种下游任务上的强大迁移能力,证明其作为通用视频表征学习器的有效性。


五、开源资源与模型仓库

GitHub 仓库提供了丰富的开源支持:

  • 预训练代码PRETRAIN.md
  • 微调代码FINETUNE.md
  • 模型权重:ViT-S、ViT-B、ViT-g 等多尺度模型
  • 蒸馏模型(Distilled Models):提供轻量化的学生模型
  • Hugging Face 集成:权重已迁移至 Hugging Face(VideoMAEv2-hf)
  • MMAction2 支持:已合并至 MMAction2 开发版本

六、总结与影响

VideoMAE V2 的核心贡献在于:

  1. 提出 Dual Masking :通过在 Decoder 侧引入掩码,在不显著牺牲性能的前提下,将训练速度和内存效率提升 1.5--1.8 倍,使得十亿级视频模型的自监督训练成为可能。
  2. 建立渐进式训练范式:通过无监督预训练 → 有监督后预训练 → 下游微调的流程,有效缓解了大规模模型与有限下游数据之间的鸿沟。
  3. 首次实现视频领域的 Billion-Scale MAE 训练:成功训练 ViT-g,并在 Kinetics、Something-Something 等数据集上刷新 SOTA。

该工作为后续视频基础模型(如 InternVideo 等)的发展奠定了重要基础,是视频自监督学习领域的里程碑式工作。

通俗解释

通俗解释一下,尤其是直观地说清楚它是怎么掩码的,遮住了哪里,没遮住哪里,为什么这么设计

把视频想象成一本"翻页动画书"

假设你有一段视频,有 100 帧画面(像一本100页的画册)。每一页都被切成很多小方格(比如 16×16 像素一个格子)。

在视频里,同一个位置的小方格,连续很多帧的内容都差不多(比如背景的墙壁、地板)。这就是视频的"冗余性"------信息大量重复。


第一重掩码:Tube Masking(Encoder 端,遮住 90%)

操作方式:

随机挑选 90% 的位置(比如这本书里 90% 的坐标点),然后做一个残忍的操作:

在这些被选中的位置上,把全部 100 页对应的小方格,从头到尾全部涂黑。

这就像一个"时空管子"(Tube)穿过整本画册,管子经过的地方全部看不见。

没遮住的是谁? 剩下 10% 的幸运格子,它们在所有时间帧上都是可见的。

为什么这么设计?

因为视频有很强的时间连续性。如果我只遮住某一帧的某个格子,模型可能靠"抄作业"------直接看前一帧或后一帧同一个位置的内容------就能猜出来,学不到真本事。

把一整条"管子"全部涂黑,模型就没法抄近道,必须真正理解物体的运动和场景的变化,才能猜出管子里原来是什么。


第二重掩码:Running Cell Masking(Decoder 端,再次遮住一部分)

这是 VideoMAE V2 最狠的一招。

传统 MAE 的做法:

Encoder 只看了 10% 的可见格子,输出一些理解。然后 Decoder 要把所有被涂黑的 90% 格子 全部重建出来------相当于让 Decoder 做 90% 的填空题。

VideoMAE V2 的做法:

从这 90% 被涂黑的格子里,再随机挑一部分 (比如只挑 45%),剩下的直接不管了

换句话说,Decoder 的输入端再次被"掩码"------那些被二次选中的格子才需要重建,其他的连重建任务都被取消了。

遮住哪里? 在 Decoder 输入时,大部分被 Encoder 掩码的格子再次被"遮住"(不参与 Decoder 计算)。

没遮住哪里? 只有被"双重选中"的那一小部分格子,才会进入 Decoder 并被重建。


为什么这么设计?三个原因

1. 视频冗余实在太多了

视频的信息密度比图片低得多。一帧 1920×1080 的画面,真正在动的可能只有 10% 的区域。你不需要把每个像素都重建出来,重建一半就能学到足够的本领

2. Decoder 是新的瓶颈

在 VideoMAE V1 里,Encoder 虽然只处理 10% 的 token,但 Decoder 要处理 100%(10% 的 Encoder 输出 + 90% 的 mask token)。当模型变大(比如 ViT-g,十亿参数),Decoder 的计算和内存开销变得极其恐怖。

Dual Masking 让 Decoder 也只需处理一部分 token,训练速度直接提升 1.5~1.8 倍,内存占用大幅下降

3. 为了训练"巨兽级"模型

有了这个设计,作者才第一次成功训练出了十亿参数(ViT-g)的视频自监督模型。如果没有 Dual Masking 省下来的资源,这种规模的模型在视频上根本训不动。


一句话总结

Tube Masking 是"竖着挖管子"(空间位置固定,时间轴全挖空),逼模型理解运动;

Running Cell Masking 是"重建时再偷工减料"(Decoder 只重建一部分缺失块),逼模型高效学习;

两者结合,用更少的计算,训出更大的模型

三、架构

图1: VideoMAE V2 双重掩码机制

一、故事开场:视频是怎么被"切"进模型的?

1.1 输入视频:一段原始视频

假设输入是一段 T 帧的视频(比如 16 帧),分辨率是 224×224。

1.2 Cube Embedding:把视频切成"时空小方块"

模型不会直接看像素。它先用一个 3D 卷积层 (或线性投影),把视频切成很多 16×16×2 的小立方体(Cube):

  • 空间上:每 16×16 像素一块
  • 时间上:每 2 帧一层

每个小立方体被压扁成一个 向量(token) 。假设总共切出了 N 个 token

这就是图中左下角的 "Cube embedding"(绿色方块)------它们是视频最原始的"词语"。


二、第一幕:Tube Masking(Encoder 端,90% 被涂黑)

2.1 什么叫 Tube Masking?

随机选 90% 的时空位置 ,然后在这些位置上,所有时间帧的对应格子全部涂黑

就像用一根吸管(Tube)戳穿整段视频,吸管经过的地方,从头到尾都是黑的。

状态 比例 颜色 去向
被 Tube Masking 遮住 90% 白色(图中) 不进入 Encoder
可见(Visible) 10% 绿色 进入 Encoder

2.2 为什么用"管子"而不是随机点?

因为视频有时间连续性。如果只遮某一帧的某个格子,模型可以"偷看"前一帧或后一帧同一个位置,直接抄答案。

Tube Masking 把时间维度也一并挖空,彻底堵死抄近道的路,逼模型真正理解运动。


三、第二幕:Encoder 内部------用 10% 的碎片理解世界

3.1 Encoder 的输入

只有那 10% 的绿色 Cube embedding 进入 Encoder。它们被加上位置编码 (告诉模型"我在视频的哪个时空位置"),然后送入 ViT(Vision Transformer)

3.2 Encoder 内部在做什么?

Encoder 是一个标准的 Transformer Encoder,由多层自注意力(Self-Attention)和前馈网络(FFN)组成。

核心操作:自注意力

  • 每个可见 token 都会"看"向其他可见 token
  • 比如:一个 token 看到"左边有个手在抬起来",另一个看到"右边有个球在飞"
  • 通过注意力权重,它们互相交换信息,形成全局时空理解

输出:Latent Representation(蓝色方块)

  • 每个可见 token 经过 Encoder 后,变成一个高维语义向量
  • 这个向量不再代表原始像素,而是代表"这里有一个运动的肢体边缘,速度大概是..."
  • 图中标注为 "Latent representation"(蓝色)

Encoder 的本质:从 10% 的碎片中,提炼出对整个视频时空结构的深层理解。


四、第三幕:Running Cell Masking(Decoder 端,再次筛选)

这是 VideoMAE V2 的核心创新

4.1 90% 被遮住的区域,现在要被"二次审判"

在 Tube Masking 遮住的 90% 区域中,模型再次抽签:

状态 比例 颜色 命运
被 Running Cell Masking 选中 ~45% 粉色 需要重建,进入 Decoder
被彻底丢弃 ~45% 白色 连重建任务都不给,直接忽略
原本可见 10% 蓝色 作为线索,进入 Decoder

4.2 为什么叫"Running Cell"?

"Running" 意味着这些被选中的重建目标在时空维度上是分散跳跃的(不像 Tube 那样连续),像一个个"奔跑的单元格"(Cell)。

4.3 为什么再次丢弃 45%?

因为视频的冗余度极高。如果让 Decoder 重建全部 90%,就像让小学生把整本字典抄一遍------累死人,但学不到多少真本事。

只重建一部分(比如 45%),既保留了足够的难度,又大幅降低了计算量。


五、第四幕:C 处的融合------"把线索和填空题拼在一起"

这是整个图中最关键的交汇点。

5.1 融合前有什么?

  • 蓝色方块:Encoder 输出的 Latent representation(10% 可见区域的深层理解)
  • 粉色方块:Learnable mask token(45% 被选中的重建位置的占位符)

5.2 灰色方块到底是什么?

不是原始像素 ,也不是零向量。它是一个可学习的嵌入向量(类似 NLP 里的 MASK token),在训练过程中不断更新。

它的作用就像一个空白答题卡上的下划线:"这个位置有个洞,请根据上下文把它填上"。

5.3 C 处的操作:拼接(Concatenate)

把蓝色序列和灰色序列拼成一个长序列:

复制代码
[蓝色1, 蓝色2, ..., 蓝色10%, 灰色1, 灰色2, ..., 灰色45%]

总长度 = 10% + 45% = 55% 的原始 token 数量。

5.4 为什么要拼接?

因为 Decoder 是 Transformer,它依靠自注意力机制工作。

只有把"已知线索"(蓝色)和"待填空位置"(灰色)放在同一个序列里,灰色 token 才能通过注意力层**主动"询问"**蓝色 token:

  • "我这边应该是什么颜色?"
  • "旁边那个可见块在做什么运动?"
  • "整体场景是室内还是室外?"

如果不拼接,Decoder 只看到一堆空白占位符,没有任何上下文,根本无从重建。


六、第五幕:Decoder 内部------"做填空题"

6.1 Decoder 的输入

拼接后的序列(蓝色 + 灰色),加上位置编码。

6.2 Decoder 内部在做什么?

Decoder 通常比 Encoder 小且浅(例如 Encoder 24 层,Decoder 只有 4-8 层)。

核心操作:交叉注意力 + 自注意力

  • 灰色 token 通过自注意力,互相交流:"我左边那个洞应该是什么?"
  • 灰色 token 通过注意力看向蓝色 token:"让我看看 Encoder 对那个可见区域的理解..."
  • 蓝色 token 作为"锚点",提供全局时空上下文

6.3 输出:Reconstructed Pixel(粉色方块)

Decoder 的每个输出对应一个灰色位置的重建结果:

  • 输出维度 = 原始 Cube 的像素维度(如 16×16×2×3 = 1536)
  • 这些输出是归一化后的像素值

图中标注为 "Reconstructed pixel"(粉色)。


七、第六幕:损失函数------只算"被选中的填空题"

7.1 损失计算范围

MSE 损失只计算那 45% 被 Running Cell Masking 选中的位置

复制代码
Loss = MSE( Decoder 输出的粉色, 原始视频对应位置的像素 )

7.2 谁不算损失?

  • 被丢弃的 45%:连题都没出,不算
  • 原本可见的 10%:Encoder 已经看过它们了,不需要重建,不算

7.3 为什么这样设计?

这是 MAE(Masked Autoencoder) 的核心哲学:

  • 不对称设计:Encoder 重、Decoder 轻;Encoder 看得少、Decoder 填得少
  • 把计算预算集中在"理解"上,而不是"复制"上
  • 如果重建全部 90%,Decoder 会变成"像素复制机",而不是"语义理解器"

八、第七幕:训练流程------三阶段"渐进式毕业"

VideoMAE V2 不是"一步到位"的,而是像读博士一样,分阶段进阶:

阶段 1:大规模无监督预训练(Pre-training)

  • 数据 :UnlabeledHybrid(约 135 万 未标注视频,来自 Web、YouTube、Instagram、Movies 等)
  • 任务:Dual Masking 自监督重建
  • 目标:让模型学会"通用的视频时空理解"
  • 模型规模:从 ViT-S 到 ViT-g(十亿参数)
  • 关键:Dual Masking 让 ViT-g 的训练成为可能(节省 1.5~1.8 倍计算)

阶段 2:有监督后预训练(Post-pretraining)

  • 数据:LabeledHybrid(K400 + K600 + K700 混合,有标签)
  • 任务 :用标签数据进行中间监督训练
  • 目标:作为"桥梁",把从无标签数据学到的通用表征,对齐到人类定义的动作语义上
  • 原因:下游数据集(如 Something-Something)通常很小,直接从无标签跳到微调,会有"语义鸿沟"

阶段 3:下游任务微调(Fine-tuning)

  • 数据:具体下游数据集(如 Kinetics-400、Something-Something、AVA 等)
  • 任务:分类、检测、时序动作检测等
  • 操作:加载预训练权重,替换头部(Head),端到端微调

九、第八幕:推理流程------"毕业后的工作"

训练完成后,模型怎么在真实任务中使用?

9.1 丢弃 Decoder,只用 Encoder

在下游任务推理时,Decoder 被完全扔掉 。只保留 Encoder 和任务特定的 Head(分类头、检测头等)。

9.2 为什么能扔掉 Decoder?

因为 Encoder 输出的 Latent representation(蓝色方块) 已经是高质量的语义特征。Decoder 只是训练时用来"监督" Encoder 学习的一个"教练",学完后教练就可以退休了。

9.3 推理时的数据流

复制代码
输入视频 → Cube Embedding → Tube Masking? 

注意 :推理时不需要掩码

推理时,Encoder 会看全部 token(100%),输出全部位置的 Latent representation。然后送入任务 Head:

  • 分类任务:对所有 token 做全局池化(Global Average Pooling),送入分类头
  • 检测/分割任务:保留时空特征图结构,送入检测头

9.4 为什么推理不用掩码?

掩码(Masking)是训练时的"练习题",目的是逼 Encoder 学会从残缺信息中提炼理解。

推理时,我们给 Encoder 看完整视频,它用学到的能力提取特征,自然比训练时更准。


十、大结局:Dual Masking 的完整故事线

让我用一张图串起整个故事:

复制代码
[输入视频]
    ↓
[Cube Embedding] ------ 切成时空小方块(绿色)
    ↓
[Tube Masking] ------ 90% 涂黑,10% 幸存(绿色→Encoder)
    ↓
[Encoder] ------ 看 10%,提炼深层理解(蓝色 Latent)
    ↓
[Running Cell Masking] ------ 在 90% 中再选 45% 重建(粉色)
    ↓
[C 处融合] ------ 蓝色(线索) + 灰色(占位符)拼接
    ↓
[Decoder] ------ 做填空题,输出粉色(重建像素)
    ↓
[Loss] ------ 只算 45% 的 MSE
    ↓
[训练完成]
    ↓
[推理时] ------ 扔掉 Decoder,Encoder 看 100% 视频,输出特征给下游任务

十一、为什么这个设计能训练出十亿参数的模型?

这是 VideoMAE V2 的终极意义

瓶颈 原始 MAE/VideoMAE V1 VideoMAE V2(Dual Masking)
Encoder 计算 只处理 10% 只处理 10%
Decoder 计算 处理 100%(10% 输出 + 90% mask token) 只处理 55%(10% + 45%)
训练速度 提升 1.5~1.8 倍
内存占用 显著降低
可训练模型规模 最大到 ViT-L 首次达到 ViT-g(十亿级)

Dual Masking 的本质 :视频的信息冗余实在太多,没必要全部重建。通过"Encoder 端竖着挖管子 + Decoder 端跳着做填空",用更少的计算,逼出更强的理解


这就是 VideoMAE V2 的完整故事:一个用"故意遮住大部分视频"来训练"十亿参数巨兽"的自监督学习传奇

相关推荐
金色的暴发户1 小时前
一劳永逸解决Codex手机验证
前端·人工智能·开源
YOLO数据集集合1 小时前
无人机松材线虫病树监测:早期与晚期感染阶段目标检测数据集全解析10125期
人工智能·目标检测·无人机
天天进步20151 小时前
InfiniteTalk 源码解析 #12:二次开发路线:做一个可商用的长视频口播生成平台
人工智能
Elastic 中国社区官方博客1 小时前
谁来评判评判者?在 Elasticsearch Workflows 中使用 LLM-as-a-Judge
大数据·运维·人工智能·elasticsearch·搜索引擎·ai·全文检索
yqd6661 小时前
OpenCV
人工智能·opencv·计算机视觉
糖糖的AI心得2 小时前
AI重塑跨境运营效率:产品从精修到上架的全链路实战拆解
图像处理·人工智能·aigc
中微极客2 小时前
Gemini Omni Flash:对话式AI视频编辑新范式
人工智能·音视频·新人首发
mit6.8242 小时前
一些从researcher角度的观察和思考
人工智能
牛企老板俱乐部2 小时前
2026 年合肥专业 GEO 优化服务商深度测评|分行业精准选型指南
大数据·人工智能