目录
上一课中,CLIP 让一张图片在一批描述中选择正确答案。现在换一种提问:不先看全部候选,而是单独拿出一对图片和文字,问“这一对是否匹配”?
SigLIP 仍然使用图像与文字编码器,但把训练目标改为逐对的 sigmoid 损失,不再需要用整批相似度做 softmax 归一化。[1]
1、一个是选择题,一个是逐项判断
面对一张猫图和“猫”“狗”“自行车”三段描述,CLIP 的一行 softmax 分配一份总和为 1 的概率;SigLIP 则对每一对分别给出匹配分数,各项不必加起来等于 1。
图中使用人为指定的同一组 logits,只为说明归一化方式,不代表两种真实模型的输出。实际模型的尺度、偏置和训练结果不同,不能拿它们的原始分数直接比较。
CLIP 问“这些候选里选哪个”,SigLIP 的训练损失问“这一对应当匹配还是不匹配”。
2、sigmoid 怎样把一个分数变成判断?
2.1 先计算图文分数
两路编码器各自产生特征,经过投影与归一化得到 $v_i$ 和 $t_j$,再计算:
\[s_{ij}=\alpha v_i^Tt_j+b,\qquad \alpha=\exp(a)>0\]$a$ 是可学习的对数尺度,$b$ 是可学习偏置。尺度改变分数差异的大小,偏置整体移动分数,两者作用不同。
2.2 每个分数单独经过 sigmoid
\[p_{ij}=\sigma(s_{ij})=\frac{1}{1+\exp(-s_{ij})}\]分数为 0 时结果是 0.5,为 2 时约为 0.881,为 −1 时约为 0.269。它可以作为配对匹配分数,但不应未经校准就理解成真实场景中“有多少概率判断正确”。
固定这一对的 logit 时,增加其他候选不会改变它的 sigmoid 结果;softmax 则会因为分母增加而改变原有候选的概率。
3、怎样设置正确答案与损失?
3.1 配对标签仍然来自数据
一批有 $B$ 对图文,按正确配对顺序排列,令对角线标签 $y_{ii}=1$,其他格子 $y_{ij}=0$。对于三对数据,就有 3 个正例和 6 个负例;虽然逐对打分,标准训练仍可使用批内的交叉组合。
这些负例是训练构造的标签,不保证语义上绝对错误:两张猫图或重复描述仍可能形成假负例。换成 sigmoid 并没有自动解决数据噪声。
3.2 匹配项希望高,不匹配项希望低
\[\ell_{ij}=-y_{ij}\log\sigma(s_{ij})-(1-y_{ij})\log(1-\sigma(s_{ij}))\]如果标签是 1、logit 是 2,单对损失约为 0.127;如果标签仍是 1,logit 却是 −1,损失约为 1.313,说明模型把正确配对打低了。
原论文常用 $z_{ij}=2y_{ij}-1$ 把标签写成正负 1,等价地得到:
\[L=\frac1B\sum_{i=1}^{B}\sum_{j=1}^{B}\operatorname{softplus}(-z_{ij}s_{ij}),\qquad \operatorname{softplus}(x)=\log(1+\exp(x))\]这里除以 $B$,不是 $B^2$。如果代码对全部格子取平均,会多出一个 $1/B$ 的缩放;比较损失或训练设置时,要确认归约方式。实际计算应使用稳定的 logits 损失函数,避免先算概率再取对数。
4、最小代码:同一张分数表,换一种损失
下面直接给出一张示意 logit 表,演示配对标签与数值稳定的二元交叉熵;它不是完整训练,也没有加载真实编码器。
import torch
import torch.nn.functional as F
logits = torch.tensor([
[2.0, -1.0, -2.0],
[-1.0, 2.0, -2.0],
[-2.0, -1.0, 2.0],
], requires_grad=True)
batch = logits.shape[0]
labels = torch.eye(batch)
loss = F.binary_cross_entropy_with_logits(
logits, labels, reduction="sum"
) / batch
loss.backward()
print(round(loss.item(), 4)) # 0.5671
print(logits.detach().sigmoid().round(decimals=3))
# 对角线约 0.881;其他位置约 0.269 或 0.119
binary_cross_entropy_with_logits 已经包含 sigmoid 相关计算,传入原始 logits 即可。可以把对角线的一项改成 −2,再看损失变大;也可以增加负例,观察总损失与归约方式之间的关系。
5、不做整批归一化,是否就不用大批数据?
不需要全局 softmax 分母,让损失更容易按配对分块计算或组织分布式实现;但如果枚举所有批内组合,仍然有 $B^2$ 对图文,计算和通信不会凭空消失。
| 需要区分的事 | 怎样理解 |
|---|---|
| 单对损失是否依赖其他候选分数 | sigmoid 单对损失不依赖 softmax 分母 |
| 总训练是否使用其他样本 | 仍可使用批内负例与跨设备配对 |
| 全部配对是否仍是平方数量 | 枚举所有组合时仍是 $B^2$ |
| 换损失是否保证模型更好 | 还取决于数据、规模、采样与训练设置 |
随着批大小增加,负例数量相对正例也会增加,偏置、负例采样和损失尺度因此值得一起考虑。不能把“逐对判断”理解成“每次只训练一个配对”,也不能仅靠一个示例就判断它优于 CLIP。
6、使用时有什么变化?
6.1 检索与分类仍然比较图文表示
给图片与候选描述打分后,依然可以按分数排序。对固定模型,正尺度、公共偏置与 sigmoid 都不改变候选排名,但会改变分数数值,所以旧模型的阈值不应直接搬过来。
6.2 单独打分不等于自动获得多标签能力
多个描述可以同时得到高分,不过标准配对训练仍会把同批非对角线视为负例。若要判断图片中是否同时存在多个对象,还需要相应的数据、阈值验证与任务评估。
同样,模型可以比较“角色在掩体后”等描述,却不能仅凭高匹配分数证明局部关系或视频时序正确。图文表示是多模态系统的基础,接入语言模型还需要连接器和后续训练。
7、记住这条区别
CLIP 通过整批候选间的竞争学习匹配,SigLIP 通过逐对的二元判断学习匹配;改变的是训练损失的组织方式,图文编码与共同表示仍然是主线。
试着回答:为什么新增候选会改变 softmax 概率,却不改变固定 logit 的 sigmoid 结果?逐对损失为什么仍可能涉及 $B^2$ 个配对?把概率阈值设为 0.5,为什么不能保证实际判断可靠?
下一课进入视觉与语言的接口:Projector 怎样把视觉特征接入 LLM,为什么维度相同还不够?
8、参考文献(References)
- Zhai, X., Mustafa, B., Kolesnikov, A., and Beyer, L. “Sigmoid Loss for Language Image Pre-Training.” ICCV, 2023. arXiv:2303.15343.↩