(self, z_i, z_j)
return loss
We do not sample negative examples explicitly.
        Instead, given a positive pair, similar to (Chen et al., 2017), we treat the other 2(N − 1) augmented examples within a minibatch as negative examples.
We do not sample negative examples explicitly.
        Instead, given a positive pair, similar to (Chen et al., 2017), we treat the other 2(N − 1) augmented examples within a minibatch as negative examples.
We do not sample negative examples explicitly . Instead given a positive pair similar to ( Chen et al . 2017 ) we treat the other 2 ( N − 1 ) augmented examples within a minibatch as negative examples .
def forward(self, z_i, z_j):
        """
        We do not sample negative examples explicitly.
        Instead, given a positive pair, similar to (Chen et al., 2017), we treat the other 2(N − 1) augmented examples within a minibatch as negative examples.
        """
        N = 2 * self.batch_size * self.world_size

        z = torch.cat((z_i, z_j), dim=0)
        if self.world_size > 1:
            z = torch.cat(GatherLayer.apply(z), dim=0)

        sim = self.similarity_f(z.unsqueeze(1), z.unsqueeze(0)) / self.temperature

        sim_i_j = torch.diag(sim, self.batch_size * self.world_size)
        sim_j_i = torch.diag(sim, -self.batch_size * self.world_size)

        # We have 2N samples, but with Distributed training every GPU gets N examples too, resulting in: 2xNxN
        positive_samples = torch.cat((sim_i_j, sim_j_i), dim=0).reshape(N, 1)
        negative_samples = sim[self.mask].reshape(N, -1)

        labels = torch.zeros(N).to(positive_samples.device).long()
        logits = torch.cat((positive_samples, negative_samples), dim=1)
        loss = self.criterion(logits, labels)
        loss /= N
        return loss
def forward ( self , z_i , z_j ) : N = 2 * self . batch_size * self . world_size z = torch . cat ( ( z_i , z_j ) , dim = 0 ) if self . world_size > 1 : z = torch . cat ( GatherLayer . apply ( z ) , dim = 0 ) sim = self . similarity_f ( z . unsqueeze ( 1 ) , z . unsqueeze ( 0 ) ) / self . temperature sim_i_j = torch . diag ( sim , self . batch_size * self . world_size ) sim_j_i = torch . diag ( sim , - self . batch_size * self . world_size ) # We have 2N samples, but with Distributed training every GPU gets N examples too, resulting in: 2xNxN positive_samples = torch . cat ( ( sim_i_j , sim_j_i ) , dim = 0 ) . reshape ( N , 1 ) negative_samples = sim [ self . mask ] . reshape ( N , - 1 ) labels = torch . zeros ( N ) . to ( positive_samples . device ) . long ( ) logits = torch . cat ( ( positive_samples , negative_samples ) , dim = 1 ) loss = self . criterion ( logits , labels ) loss /= N return loss