区分真实样本

前面的两种是为了去估计配分函数,接下来要介绍的 InfoNCE 虽然带个 NCE,但这个的目的不是要预估配分函数,他是直接像上篇应用 NCE 的方法一样,直接采用自归一化,即:

$$ p(\boldsymbol{w}|\boldsymbol{c}) = \frac{u_{\boldsymbol{\theta}}(\boldsymbol{w}, \boldsymbol{c})}{1} $$

首先对于每个训练样本来说,我们再从噪声分布$q(x)$中采样$k-1$个样本,我们的目的即是区分出真实样本:

$$ \begin{align} L(\boldsymbol{\theta}) & = -\mathbb{E}_{\boldsymbol{w}, \boldsymbol{c} \sim \mathcal{D}; \boldsymbol{w}_{j} \sim q} \log \frac{p(\boldsymbol{w}|\boldsymbol{c})}{p(\boldsymbol{w}|\boldsymbol{c})+\sum_{j=1}^{k-1}q(\boldsymbol{w}_{j})}\\ & = -\mathbb{E}_{\boldsymbol{w}, \boldsymbol{c} \sim \mathcal{D};\boldsymbol{w}_{j} \sim q} \log \frac{u_{\boldsymbol{\theta}}(\boldsymbol{w}, \boldsymbol{c})}{u_{\boldsymbol{\theta}}(\boldsymbol{w}, \boldsymbol{c}) + \sum_{j=1}^{k-1} q(\boldsymbol{w}_{j})} \end{align} $$

最小化上述 loss 到底有什么好处呢?

互信息来访

对于训练样本$i$来说,它是真实样本的概率为:

$$ \begin{align} p(d=i) & = \frac{p(\boldsymbol{w}_{i}|\boldsymbol{c})\prod_{j=1, i\neq j}^{k}q(\boldsymbol{w}_{j})}{\sum_{j=1}^{k}p(\boldsymbol{w}_{j}|\boldsymbol{c})\prod_{l=1,l\neq j}^{k}q(\boldsymbol{w}_{l})} \\ &= \frac{\frac{p(\boldsymbol{w}_{i}|\boldsymbol{c})}{q(\boldsymbol{w}_{i})}}{\sum_{j=1}^{k} \frac{p(\boldsymbol{w}_{j}|\boldsymbol{c})}{q(\boldsymbol{w}_{j})}} \end{align} $$

转换的方法即是上下同除以$\prod_{i=1}^{k} q(\boldsymbol{w}_{i})$

InfoNCE 的目的即为正确区分出真实样本,而真实样本都来自训练集(与噪声集区分),也就是说对于 loss 而言,最优解即为$u_{\boldsymbol{\theta}}(\boldsymbol{w}, \boldsymbol{c})$正比于 density ratio:

$$ u_{\boldsymbol{\theta}}(\boldsymbol{w}_{i}, \boldsymbol{c}) \propto \frac{p(\boldsymbol{w}_{i}|\boldsymbol{c})}{q(\boldsymbol{w}_{i})} $$

我们知道,互信息的计算如下:

$$ I(\boldsymbol{w}, \boldsymbol{c}) = \text{KL}(p(\boldsymbol{w}, \boldsymbol{c})\|p(\boldsymbol{w})p(\boldsymbol{c})) = \mathbb{E}_{\boldsymbol{w}, \boldsymbol{c} \sim \mathcal{D}} \log \frac{p(\boldsymbol{w}, \boldsymbol{c})}{p(\boldsymbol{w})p(\boldsymbol{c})} $$

为了和上述 loss 有关,很自然做出以下变化:

$$ I(\boldsymbol{w}, \boldsymbol{c}) = \mathbb{E}_{\boldsymbol{w}, \boldsymbol{c} \sim \mathcal{D}} \log \frac{p(\boldsymbol{w}|\boldsymbol{c})p(\boldsymbol{c})}{p(\boldsymbol{w})p(\boldsymbol{c})} = \mathbb{E}_{\boldsymbol{w}, \boldsymbol{c} \sim \mathcal{D}} \log {\color{blue}\frac{p(\boldsymbol{w}|\boldsymbol{c})}{p(\boldsymbol{w})}} $$

也就是说如果我们要$u_{\boldsymbol{\theta}}(\boldsymbol{w}, \boldsymbol{c})$来表示互信息,还得$q(x) = p(x)$,也就是噪声分布即为模型分布(unconditioned)

那么:

$$ u_{\boldsymbol{\theta}}(\boldsymbol{w}_{i}, \boldsymbol{c}) \propto \frac{p(\boldsymbol{w}_{i}|\boldsymbol{c})}{{\color{blue}p(\boldsymbol{w}_{i})}} $$

此时完整的 loss 即为:

$$ L(\boldsymbol{\theta }) = -\mathbb{E}_{\boldsymbol{w}, \boldsymbol{c} \sim \mathcal{D}; \boldsymbol{w}_{j} \sim q} \log \frac{u_{\boldsymbol{\theta}}(\boldsymbol{w}, \boldsymbol{c})}{\sum_{j=1}^{k} u_{\boldsymbol{\theta}}(\boldsymbol{w}_{j}, \boldsymbol{c})} $$

当我们要使得训练样本$\boldsymbol{w}$是真实样本的概率变得最大,即一定程度最大化$u_{\boldsymbol{\theta}}(\boldsymbol{w}, \boldsymbol{c})$,然后最小化$u_{\boldsymbol{\theta}}(\boldsymbol{w}_{j}, \boldsymbol{c})$,即最大化$\boldsymbol{w}, \boldsymbol{c}$之间的互信息,最小化负样本与$\boldsymbol{c}$之间的互信息

注意:现在用的时候并非像一开始通过真实样本的概念,而是可以将$\boldsymbol{w}, \boldsymbol{c}$看成是一对正样本,噪声样本看作负样本

Hardness-Aware

同时 InfoNCE 会着重关照那些跟真实样本$\boldsymbol{c}$更相似的负样本,这类也叫做「Hard-Negative」,而相应地会轻视一些与$\boldsymbol{c}$本来就没有那么相似的负样本,即「Hardness-Aware」

$$ \begin{align} L(\boldsymbol{\theta }) & = - \mathbb{E}_{\boldsymbol{w}, \boldsymbol{c} \sim \mathcal{D};\boldsymbol{w}_{j}\sim q} \log \frac{u_{\boldsymbol{\theta }}(\boldsymbol{w}, \boldsymbol{c})}{u_{\boldsymbol{\theta }}(\boldsymbol{w}, \boldsymbol{c})+\sum_{j=1}^{k-1} u_{\boldsymbol{\theta }}(\boldsymbol{w}_{j}, \boldsymbol{c})} \\ &= -\mathbb{E}_{\boldsymbol{w}, \boldsymbol{c} \sim \mathcal{D};\boldsymbol{w}_{j}\sim q} \log \frac{\exp(s_{\boldsymbol{w}, \boldsymbol{c}} )}{\exp(s_{\boldsymbol{w}, \boldsymbol{c}})+\sum_{j=1}^{k-1}\exp(s_{\boldsymbol{w}_{j}, \boldsymbol{c}})} \\ &= -\mathbb{E}_{\boldsymbol{w}, \boldsymbol{c} \sim \mathcal{D};\boldsymbol{w}_{j} \sim q} \left[s_{\boldsymbol{w}, \boldsymbol{c}} - \log\left( \exp(s_{\boldsymbol{w}, \boldsymbol{c}})+\sum_{j=1}^{k-1}\exp(s_{\boldsymbol{w}_{j},\boldsymbol{c}}) \right)\right] \end{align} $$

对于$\boldsymbol{w}_{j}$而言,与$\boldsymbol{c}$的相似性越大,则在损失函数中占比越大,可以看成是惩罚越大,然而仅凭这个没办法做到上述性质,比如下面的 loss 也可以:

$$ L_{\text{simple}}(\boldsymbol{\theta }) = \mathbb{E}_{\boldsymbol{w}, \boldsymbol{c} \sim \mathcal{D}; \boldsymbol{w}_{j} \sim q} \left[-s_{\boldsymbol{w}, \boldsymbol{c}} + \sum_{j=1}^{k-1} s_{\boldsymbol{w}_{j}, \boldsymbol{c}}\right] $$

然而实验证明,这个 loss 效果并不是很好

接着,我们来求下损失函数相对于$s_{\boldsymbol{w}_{j}, \boldsymbol{c}}$的偏导:

不妨就对单个样本$\boldsymbol{w}, \boldsymbol{c}$来看:

$$ \frac{ \partial L_{\text{simple}} }{ \partial s_{\boldsymbol{w}_{j}, \boldsymbol{c}} } = 1 $$

也就是说 loss 对于所有$s_{\boldsymbol{w}_{j}, \boldsymbol{c}}$的变化一样敏感,即「一视同仁」,没有给损失函数的优化注入其他信息

$$ \frac{ \partial L }{ \partial s_{\boldsymbol{w}_{j},\boldsymbol{c}} } = \frac{\exp(s_{\boldsymbol{w}_{j}, \boldsymbol{c}})}{\exp(s_{\boldsymbol{w},\boldsymbol{c}} )+ \sum_{j=1}^{k-1}\exp(s_{\boldsymbol{w}_{j}, c})} $$

而对于 InfoNCE 而言,对于所有负样本而言,分母是固定的,而「分子越大」,即$s_{\boldsymbol{w}_{j}, \boldsymbol{c}}$越大,则此时 loss 对于$s_{\boldsymbol{w}_{j}, \boldsymbol{c}}$的变化则越敏感

总结说就是,InfoNCE 这种 loss 在优化时会注入一种偏好,更偏向于把与真实样本相似的噪声样本给区分开来

温度系数

一般现在用的时候,还会加入一个调节因子:$\tau$

$$ L(\boldsymbol{\theta})= -\mathbb{E}_{\boldsymbol{w}, \boldsymbol{c} \sim \mathcal{D}; \boldsymbol{w}_{j} \sim q} \log \frac{\exp(s_{\boldsymbol{w}, \boldsymbol{c}}/\tau )}{\exp(s_{\boldsymbol{w}, \boldsymbol{c}}/\tau)+\sum_{j=1}^{k-1}\exp(s_{\boldsymbol{w}_{j}, \boldsymbol{c}}/\tau)} $$

那么:

$$ \frac{ \partial L }{ \partial s_{\boldsymbol{w}_{j},\boldsymbol{c}} } = \frac{1}{\tau}\frac{\exp(s_{\boldsymbol{w}_{j}, \boldsymbol{c}}/\tau)}{\exp(s_{\boldsymbol{w},\boldsymbol{c}}/\tau )+ \sum_{j=1}^{k-1}\exp(s_{\boldsymbol{w}_{j}, c}/\tau)} $$

推论 1:当$\tau$很小时,比如$0.02$那么由上式可得 loss 会格外关注于将与真实样本相似的噪声样本给区分开。换句话说,$\tau$越小,对 hard-negative 的惩罚越大

下面我们引入一个 kernel 来衡量一个分布的均匀性(uniform),$f(\boldsymbol{x})$代表模型输出的表示

$$ L_{\text{uniformity}}(f;t) = \log \, \mathbb{E}_{\boldsymbol{x}, \boldsymbol{y} \sim \mathcal{D}} \left[e^{-t\|f(\boldsymbol{x}) - f(\boldsymbol{y})\|_{2}^{2}}\right](t \in \mathbb{R}_{+}) $$

Wang et., al中,作者采用不同的$\tau$来对比模型产生表示的均匀性

$\tau$比较小时,模型产生的表征空间更加均匀,随着$\tau$的增大,均匀性被破坏

而对于一个好的对比学习的表征空间应该满足「locally clustered,globally uniform」,比如下图,当表征均匀分布在球面上时,此时用一个超平面(线性分类器)便可分开

推论 2:当$\tau$较小时,用 infoNCE loss 训出的模型表征空间比较均匀,当$\tau$增大时,表征空间的均匀性被逐步破坏

上代码

当下的算力已经足够支撑直接用概率而非自归一化了,其实会发现 InfoNCE loss 跟多分类交叉熵损失一样:

import torch.nn.functional as F

def infoNCE(q_vectors, c_vectors, labels, tau=1):
    """Compute the InfoNCE Loss in
    http://arxiv.org/abs/1807.03748.

    Params:
        - q_vectors: Tensor. Shape: (bs, d_model). Vector presentation of query.
        - c_vectors: Tensor. Shape: (num_pos_neg_contexts, d_model). Vector presentation of context.
        - labels: Tensor. Shape: (bs, ). Indices for the positive contexts.
        - tau: Scalar. The parameter to control penalty on hard negatives (smaller => harder).
               A good initialization value can be 0.02 or 0.05.

    Examples:
        >>> q_vectors = torch.randn((2, 4))
        >>> c_vectors = torch.randn((4, 4)) # each query has 4 contexts
        >>> labels = torch.tensor([1, 3])
        >>> print(infoNCE(q_vectors, c_vectors, labels))
    """
    scores = (q_vectors @ c_vectors.T) / tau
    return F.cross_entropy(scores, labels)