class_docstr: Pseudo-Prototypical Proxy loss (PPP-loss).
  This is a contrastive loss using prototypes and representations of the
  samples in the batch to optimize the embedding space.
class_docstr_tok: ["Pseudo-Prototypical","Proxy","loss","(","PPP-loss",")",".","This","is","a","contrastive","loss","using","prototypes","and","representations","of","the","samples","in","the","batch","to","optimize","the","embedding","space","."]
docstr: Get the attractor loss terms for all instances in xc.
  :param pc: Prototype of the same class c.
  :param pk: Prototoypes of the other classes.
  :param Bc: Batch of instances of the same class c.
  :return: Sum_{i, the part of same class c} log P(c|x_i^c)
docstr_tok: ["Get","the","attractor","loss","terms","for","all","instances","in","xc",".",":","param","pc",":","Prototype","of","the","same","class","c.",":","param","pk",":","Prototoypes","of","the","other","classes",".",":","param","Bc",":","Batch","of","instances","of","the","same","class","c.",":","return",":","Sum_","{","i",",","the","part","of","same","class","c","}","log","P","(","c|x_i^c",")"]
code: def attractor(self, pc, pk, Bc):
      """
      Get the attractor loss terms for all instances in xc.
      :param pc: Prototype of the same class c.
      :param pk: Prototoypes of the other classes.
      :param Bc: Batch of instances of the same class c.
      :return: Sum_{i, the part of same class c} log P(c|x_i^c)
      """
      m = torch.cat(
          [Bc.clone(), pc, pk]
      ).detach()  # Incl other-class proto
      pk_idx = m.shape[0] - pk.shape[0]  # from when starts p_k
  
      # Resulting distance columns are per-instance loss terms
      D = (
          torch.mm(m, Bc.t()).div_(self.T).exp_()
      )  # Distance matrix exp terms
      mask = (
          torch.eye(*D.shape).bool().to(Bc.device)
      )  # Exclude self-product
      Dm = D.masked_fill(mask, 0)  # Masked out products with self
  
      Lc_n, Lk_d = Dm[:pk_idx], Dm[pk_idx:].sum(
          dim=0
      )  # Num/denominator
      Pci = Lc_n / (Lc_n + Lk_d)  # Get probabilities per instance
      E_Pc = (
          Pci.sum(0) / Bc.shape[0]
      )  # Expectation over pseudo-prototypes
      return E_Pc.log_().sum()
  
imports: from typing import Dict
  import torch
  from torch import Tensor
  from torch.nn.functional import normalize
  from torch.nn.modules import Module
  from avalanche.training.utils import get_last_fc_layer, swap_last_fc_layer
  from avalanche.training.plugins.strategy_plugin import SupervisedPlugin
  from avalanche.training.storage_policy import ClassBalancedBuffer
  from avalanche.benchmarks.utils.data_loader import ReplayDataLoader
label_desc: Use image node_id 3 for calling the PPPloss obj's underlying member method code with example usage: obj.attractor(pc, pk, Bc) and returns: E_Pc