特征表示基础:单模态特征提取
多模态对齐,说白了就是让不同模态的数据在同一个语义空间里「对话」。但对话之前,你得先让每种模态把自己的话说清楚——这就是单模态特征提取要做的事。
我刚开始做多模态项目时,踩过一个坑:直接用预训练模型抽特征,没仔细看输出维度,结果图像特征 2048 维,文本特征 768 维,对齐的时候怎么调都不对。后来才明白,特征维度和语义空间的设计,从一开始就得想清楚。
图像特征提取:从 CNN 到 ViT
图像特征提取,目前主流就两派:CNN 和 ViT。我个人的习惯是,任务需要局部细节就用 CNN,需要全局关系就用 ViT。
CNN 特征提取
CNN 的核心思路是「局部感受野 + 层级抽象」。一张图进去,经过卷积、池化、激活,逐渐从边缘、纹理升到物体部件。
常用的 CNN 主干网络:
| 模型 | 参数量 | 输出特征维度 | 特点 |
|---|---|---|---|
| ResNet-50 | 25.6M | 2048 | 残差连接,训练稳定 |
| ResNet-101 | 44.5M | 2048 | 更深,适合细粒度 |
| EfficientNet-B0 | 5.3M | 1280 | 计算效率高 |
| MobileNetV3 | 5.4M | 960 | 移动端友好 |
ViT 特征提取
ViT 把图像切成 patch,每个 patch 线性投影成 ,然后用 Transformer 做全局自注意力。说白了,就是把 NLP 那套搬到了图像上。
ViT 的典型流程:
- 图像切 patch(如 16×16)
- 每个 patch 展平 + 线性投影
- 加上位置编码
- 送入 Transformer Encoder
- 取 [CLS] 或所有 平均作为特征
常用的 ViT 变体:
| 模型 | patch 大小 | 输出维度 | 预训练数据 |
|---|---|---|---|
| ViT-B/16 | 16×16 | 768 | ImageNet-21K |
| ViT-L/14 | 14×14 | 1024 | ImageNet-21K |
| DeiT-S | 16×16 | 384 | ImageNet-1K + 蒸馏 |
| Swin-T | 4×4 | 768 | ImageNet-1K |
文本特征提取:BERT 与 RoBERTa
文本这边,BERT 和 RoBERTa 是绕不开的基石。我做过一个图文检索项目,试过用 Word2Vec 抽特征,效果惨不忍睹——语义太浅,跟图像特征根本对不上。换成 BERT 之后,召回率直接涨了 12 个点。
BERT 特征提取
BERT 的核心是「双向 Transformer + 掩码语言模型」。它不像 那样只能看左边,而是左右上下文都看,所以语义理解更准。
BERT 的输入处理:
- Embedding: 每个词转成向量
- Segment Embedding: 区分句子 A/B
- Position Embedding: 位置编码
输出特征通常取 [CLS] 的向量作为句子表示,或者取所有 的平均池化。
常用 BERT 系列:
| 模型 | 层数 | 隐藏维度 | 参数量 |
|---|---|---|---|
| BERT-Base | 12 | 768 | 110M |
| BERT-Large | 24 | 1024 | 340M |
| RoBERTa-Base | 12 | 768 | 125M |
| RoBERTa-Large | 24 | 1024 | 355M |
RoBERTa 的改进
RoBERTa 说白了就是 BERT 的「优化版」。它去掉了 BERT 的下一句预测任务,用了更大的 batch、更多的数据、更长的训练时间。
我个人的经验是:如果数据量够大,RoBERTa 通常比 BERT 好 2-3 个点。但如果数据量小,BERT 反而更稳,因为 RoBERTa 的动态掩码策略在小数据上容易过拟合。
特征维度与语义空间
特征维度不是越大越好。你想想看,图像特征 2048 维,文本特征 768 维,直接做点积相似度,维度高的模态天然占便宜——因为它的向量范数更大。
常见的处理方式:
- 投影到公共空间: 用线性层把不同模态映射到相同维度(如 512 或 768)
- L2 归一化: 让所有特征向量落在单位超球面上,消除维度差异
- 温度缩放: 在对比学习里调整 logits 的 sharpness
语义空间的设计,我建议遵循三个原则:
- 维度适中: 256-1024 之间,太低欠拟合,太高过拟合
- 各向同性: 特征空间不要有「死胡同」,每个方向都有意义
- 对齐友好: 不同模态的特征分布尽量接近(均值、方差)
本章知识结构
下面这张图总结了单模态特征提取的核心流程和维度关系: