基于对比学习的多模态特征对齐实践
踩坑记录:从0到1的多模态对齐之路
最近在做图像-文本联合训练系统,踩了几个大坑,分享一下。
数据准备阶段
首先,数据预处理必须小心。我最初直接用原图和文本,结果发现特征维度不匹配,报错信息是:RuntimeError: inconsistent shapes in torch.cat。
正确做法应该是:
# 图像预处理
image = transforms.Compose([
transforms.Resize((224, 224)),
transforms.ToTensor(),
transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])
])(image)
# 文本预处理
from transformers import AutoTokenizer
tokenizer = AutoTokenizer.from_pretrained('bert-base-uncased')
text_tokens = tokenizer(text, return_tensors='pt', padding=True, truncation=True)
对齐方案设计
我采用对比学习框架,损失函数设计如下:
import torch.nn.functional as F
class ContrastiveLoss(nn.Module):
def __init__(self, temperature=0.1):
super().__init__()
self.temperature = temperature
def forward(self, image_features, text_features):
# 归一化特征
image_features = F.normalize(image_features, dim=1)
text_features = F.normalize(text_features, dim=1)
# 计算相似度矩阵
similarity = torch.matmul(image_features, text_features.T) / self.temperature
# 对比损失
labels = torch.arange(similarity.shape[0], device=similarity.device)
loss = F.cross_entropy(similarity, labels)
return loss
核心踩坑点
- 温度参数调优:一开始设为1.0,对齐效果很差。后来调整到0.1才有效果
- 特征维度匹配:图像编码器输出维度必须和文本编码器输出维度一致
- 批次大小影响:batch_size太小会导致梯度不稳定
实际训练代码
# 训练循环
for epoch in range(10):
for batch in dataloader:
image, text = batch['image'], batch['text']
image_features = image_encoder(image)
text_features = text_encoder(text)
loss = contrastive_loss(image_features, text_features)
optimizer.zero_grad()
loss.backward()
optimizer.step()
效果验证
训练50个epoch后,图像-文本相似度达到了0.85,比随机对齐高出30%。
最后提醒:多模态对齐不是一蹴而就的,需要大量实验调参。

讨论