通过不变和扩散的实例特征实现无监督嵌入学习.

本文作者指出,相同的图像经过简单的数据增强后,特征具有不变性(Invariant),即分布在相似的特征空间中;对于不同的图像,其特征具有扩散性(Spreading),特征应尽可能地分开。

本文采用个体判别任务,对于一批样本进行数据增强,把样本$x$的增强样本\(\hat{x}\)视为正样本,其余所有样本视为负样本;对于正样本增加数据增强的特征不变性,对于负样本减小被当作其他样本的概率:

\[\mathcal{L}_{\text{InvaSpread}} = -\sum_i \log \frac{\exp(f_i^T\hat{f}_i/\tau)}{\sum_{k=1}^N\exp(f_k^T\hat{f}_i/\tau)}-\sum_i \sum_{j\neq i} \log(1- \frac{\exp(f_i^Tf_j/\tau)}{\sum_{k=1}^N\exp(f_k^Tf_j/\tau)})\]

class BatchCriterion(nn.Module):
    ''' Compute the loss within each batch  
    '''
    def __init__(self, T):
        super(BatchCriterion, self).__init__()
        self.T = T
        
    def forward(self, x, x_hat)
        batchSize = x.size(0)
        
        #get positive innerproduct
        pos = (x*x_hat).sum(1).div_(self.T).exp_() # [B, 1]

        #get all innerproduct
        all_prob = torch.mm(x,x_hat.t()).div_(self.T).exp_() # [B, B]
        all_div = all_prob.sum(0).view(-1, 1) # [B, 1]

        #positive probability
        lnPmt = torch.div(pos, all_div) # [B, 1]

        #positive loss        
        lnPmt.log_()
        lnPmtsum = lnPmt.sum(0)

        #get negative innerproduct
        intra_prob = torch.mm(x,x.t()).div_(self.T).exp_() # [B, B]

        #negative probability
        Pon_div = intra_prob.sum(0).view(-1, 1) # [B, 1]
        lnPon = torch.div(intra_prob, Pon_div) # [B, B]
        lnPon = -lnPon.add(-1)
        
        #remove the pos term
        lnPon.log_()
        mask = torch.ones_like(lnPon)-torch.eye(batchSize)
        lnPon = lnPon * mask

        #negative loss
        lnPonsum = lnPon.sum()

        loss = - (lnPmtsum + lnPonsum)/batchSize
        return loss