4. 数据准备与预处理:数据集构建、清洗与增强策略
跨模态对齐与检索,说白了就是让模型学会“看图说话”和“听音识字”。但模型能不能学好,很大程度上取决于你喂给它的数据长什么样。我见过太多团队把精力全砸在模型结构上,结果数据质量一塌糊涂,最后性能死活上不去。
这一章,我们就来聊聊数据准备这件事。我个人习惯把数据准备分成三步:数据集构建 → 数据清洗 → 数据增强。每一步都有坑,我们一个一个说。
4.1 数据集构建:选对“教材”
跨模态检索领域有两个最经典的“教材”:MSCOCO 和 Flickr30k。它们俩就像英语学习里的新概念和经济学人,各有各的脾气。
| 特性 | MSCOCO | Flickr30k |
|---|---|---|
| 图像数量 | ~123,000(训练集) | ~31,000(训练集) |
| 每张图标注数 | 5 句人工描述 | 5 句人工描述 |
| 场景多样性 | 高(日常场景、物体检测) | 中(Flickr 用户上传照片) |
| 标注质量 | 高(经过严格质检) | 中(部分描述较随意) |
| 常见用途 | 预训练、大规模评测 | 快速验证、小规模实验 |
我个人建议:如果你在做学术研究或需要发,MSCOCO 是首选。它的数据量大、场景丰富,模型在上面训练出来的泛化能力会更好。但如果你只是想快速验证一个想法,或者计算资源有限,Flickr30k 更合适——训练速度快,迭代周期短。
4.2 数据清洗:别让垃圾数据毁了模型
数据清洗这件事,听起来很枯燥,但做不好会直接让模型“学坏”。我刚开始做跨模态检索时,就吃过这个亏。
常见的脏数据有这几类:
- 图文不匹配:描述和图片内容对不上。比如图片里是一只猫,描述却写“一只狗在跑步”。
- 描述质量差:句子太短、语法错误、或者全是“a photo of something”这种模板句。
- 图片质量低:模糊、过暗、过曝、或者分辨率太低。
- 重复数据:同一张图片或同一段描述出现多次。
我曾经在一个项目里,模型训练了三天,结果检索准确率只有 30%。排查了半天,发现训练集里有将近 20% 的图片是“图文不匹配”的——标注人员偷懒,随便复制粘贴了描述。从那以后,我养成了一个习惯:数据清洗的优先级,永远高于模型调参。
4.3 数据增强:让模型“见多识广”
数据增强,说白了就是“无中生有”。但这里的“无中生有”不是瞎编,而是基于现有数据,生成一些合理的新样本。
跨模态检索的数据增强,可以从两个维度入手:图像增强 和 文本增强。
4.3.1 图像增强
图像增强的方法很多,但要注意:不能破坏图像和文本的语义对应关系。比如,你把一张“猫在沙发上”的图片水平翻转了,描述还是“猫在沙发上”,这没问题。但如果你把图片旋转了 90 度,猫变成倒立的了,描述还是“猫在沙发上”,这就出问题了。
常用的图像增强方法:
- 随机裁剪:保留主体,去掉背景干扰。
- 颜色抖动:调整亮度、对比度、饱和度。
- 高斯模糊:模拟低质量图片。
- 随机遮挡:随机遮掉一部分,强迫模型关注全局特征。
4.3.2 文本增强
文本增强相对容易被忽视,但它同样重要。常用的方法:
- 同义词替换:把“猫”换成“猫咪”,把“跑”换成“奔跑”。
- 回译:把英文描述翻译成中文,再翻译回英文。这样能生成一些语法结构不同的句子。
- 随机插入/删除:在句子中随机插入或删除一个词,模拟口语化表达。
你想想看,如果模型只见过“a cat sitting on a sofa”这种标准句式,那它遇到“there’s a cat on the sofa”可能就懵了。文本增强的目的,就是让模型学会“同义不同形”。
4.4 数据准备流程总览
下面这张图,是我在实际项目中总结出来的数据准备流程。你可以把它当作一个 checklist,每次做数据准备时对照着走一遍。
流程很简单:原始数据 → 数据集构建 → 数据清洗 → 数据增强 → 训练集。但这里有一个容易被忽略的点:清洗和增强的顺序不能颠倒。如果你先做了增强,再清洗,那增强出来的“脏数据”可能会被保留下来,反而污染了数据集。
4.5 代码示例:一个简单的数据增强 Pipeline
下面是一个用 PyTorch 实现的简单数据增强 Pipeline。它同时处理图像和文本,适合快速实验。
import torch
from torchvision import transforms
from PIL import Image
import random
# 图像增强
image_transform = transforms.Compose([
transforms.RandomResizedCrop(224, scale=(0.8, 1.0)),
transforms.RandomHorizontalFlip(p=0.5),
transforms.ColorJitter(brightness=0.2, contrast=0.2, saturation=0.2),
transforms.ToTensor(),
transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])
])
# 文本增强:同义词替换
def synonym_replacement(text, synonym_dict):
words = text.split()
if len(words) < 3:
return text
idx = random.randint(0, len(words) - 1)
if words[idx] in synonym_dict:
words[idx] = random.choice(synonym_dict[words[idx]])
return ' '.join(words)
# 使用示例
image = Image.open('cat.jpg')
augmented_image = image_transform(image)
caption = "a cat sitting on a sofa"
synonym_dict = {"cat": ["kitten", "feline"], "sofa": ["couch", "settee"]}
augmented_caption = synonym_replacement(caption, synonym_dict)
print(f"原描述: {caption}")
print(f"增强后: {augmented_caption}")
4.6 总结
数据准备这件事,说难不难,说简单也不简单。它的核心就三个字:干净、多样、匹配。
- 干净:数据清洗不能偷懒,脏数据会直接拉低模型上限。
- 多样:数据增强要适度,既要让模型见多识广,又不能引入不合理样本。
- 匹配:图像和文本的语义对应关系,是跨模态检索的生命线。
我个人觉得,数据准备花的时间,至少应该占整个项目周期的 30%。别急着调模型,先把数据搞明白。数据好了,模型自然就上去了。