class_docstr: Iterative Nullspace Projection. It mitigates bias by repeatedly building
  a linear classifier that separates concept groups and linearly
  projecting all words along the classifier normal.
  
  !!! Note
      For a detailed walkthrough and visual descriptions of the steps, please
      refer to Figure 5 in [VERB: Visualizing and Interpreting Bias Mitigation Techniques
      for Word Representations](https://api.semanticscholar.org/CorpusID:233168618).
  
  Based on: Ravfogel, S., Elazar, Y., Gonen, H., Twiton, M., & Goldberg, Y. (2020).
  [Null It Out: Guarding Protected Attributes by Iterative Nullspace Projection]
  (https://api.semanticscholar.org/CorpusID:215786522). ArXiv, abs/2004.07667.
  
  Implementation and terminology based on Rathore, A., Dev, S., Phillips, J.M., Srikumar,
  V., Zheng, Y., Yeh, C.M., Wang, J., Zhang, W., & Wang, B. (2021).
  [VERB: Visualizing and Interpreting Bias Mitigation Techniques for
  Word Representations](https://api.semanticscholar.org/CorpusID:233168618).
  ArXiv, abs/2104.02797.
docstr: # Parameters
  
  !!! Note
      In the examples below, we treat gender identity as binary, which does not accurately
      characterize gender in real life.
  
  evaluation_embeddings : `torch.Tensor`
      A tensor of size (evaluation_batch_size, ..., dim) of embeddings for which to mitigate bias.
  seed_embeddings1 : `torch.Tensor`
      A tensor of size (embeddings1_batch_size, ..., dim) containing seed word
      embeddings related to a specific concept group. For example, if the concept is gender,
      seed_embeddings1 could contain embeddings for linguistically masculine words, e.g.
      "man", "king", "brother", etc.
  seed_embeddings2: `torch.Tensor`
      A tensor of size (embeddings2_batch_size, ..., dim) containing seed word
      embeddings related to a different group for the same concept. For example,
      seed_embeddings2 could contain embeddings for linguistically feminine words, , e.g.
      "woman", "queen", "sister", etc.
  num_iters: `torch.Tensor`
      Number of times to build classifier and project embeddings along normal.
  
  !!! Note
      seed_embeddings1 and seed_embeddings2 need NOT be the same size. Furthermore,
      the embeddings at the same positions in each of seed_embeddings1 and seed_embeddings2
      are NOT expected to form seed word pairs.
  
  !!! Note
      All tensors are expected to be on the same device.
  
  !!! Note
      This bias mitigator is not differentiable.
  
  # Returns
  
  bias_mitigated_embeddings : `torch.Tensor`
      A tensor of the same size as evaluation_embeddings.
docstr_tok: ["#","Parameters","!","!","!","Note","In","the","examples","below",",","we","treat","gender","identity","as","binary",",","which","does","not","accurately","characterize","gender","in","real","life",".","evaluation_embeddings",":","`","torch.Tensor","`","A","tensor","of","size","(","evaluation_batch_size",",","...",",","dim",")","of","embeddings","for","which","to","mitigate","bias",".","seed_embeddings1",":","`","torch.Tensor","`","A","tensor","of","size","(","embeddings1_batch_size",",","...",",","dim",")","containing","seed","word","embeddings","related","to","a","specific","concept","group",".","For","example",",","if","the","concept","is","gender",",","seed_embeddings1","could","contain","embeddings","for","linguistically","masculine","words",",","e.g",".","``","man","''",",","``","king","''",",","``","brother","''",",","etc",".","seed_embeddings2",":","`","torch.Tensor","`","A","tensor","of","size","(","embeddings2_batch_size",",","...",",","dim",")","containing","seed","word","embeddings","related","to","a","different","group","for","the","same","concept",".","For","example",",","seed_embeddings2","could","contain","embeddings","for","linguistically","feminine","words",",",",","e.g",".","``","woman","''",",","``","queen","''",",","``","sister","''",",","etc",".","num_iters",":","`","torch.Tensor","`","Number","of","times","to","build","classifier","and","project","embeddings","along","normal",".","!","!","!","Note","seed_embeddings1","and","seed_embeddings2","need","NOT","be","the","same","size",".","Furthermore",",","the","embeddings","at","the","same","positions","in","each","of","seed_embeddings1","and","seed_embeddings2","are","NOT","expected","to","form","seed","word","pairs",".","!","!","!","Note","All","tensors","are","expected","to","be","on","the","same","device",".","!","!","!","Note","This","bias","mitigator","is","not","differentiable",".","#","Returns","bias_mitigated_embeddings",":","`","torch.Tensor","`","A","tensor","of","the","same","size","as","evaluation_embeddings","."]
code: def __call__(
      self,
      evaluation_embeddings: torch.Tensor,
      seed_embeddings1: torch.Tensor,
      seed_embeddings2: torch.Tensor,
      num_iters: int = 35,
  ):
      """
  
      # Parameters
  
      !!! Note
          In the examples below, we treat gender identity as binary, which does not accurately
          characterize gender in real life.
  
      evaluation_embeddings : `torch.Tensor`
          A tensor of size (evaluation_batch_size, ..., dim) of embeddings for which to mitigate bias.
      seed_embeddings1 : `torch.Tensor`
          A tensor of size (embeddings1_batch_size, ..., dim) containing seed word
          embeddings related to a specific concept group. For example, if the concept is gender,
          seed_embeddings1 could contain embeddings for linguistically masculine words, e.g.
          "man", "king", "brother", etc.
      seed_embeddings2: `torch.Tensor`
          A tensor of size (embeddings2_batch_size, ..., dim) containing seed word
          embeddings related to a different group for the same concept. For example,
          seed_embeddings2 could contain embeddings for linguistically feminine words, , e.g.
          "woman", "queen", "sister", etc.
      num_iters: `torch.Tensor`
          Number of times to build classifier and project embeddings along normal.
  
      !!! Note
          seed_embeddings1 and seed_embeddings2 need NOT be the same size. Furthermore,
          the embeddings at the same positions in each of seed_embeddings1 and seed_embeddings2
          are NOT expected to form seed word pairs.
  
      !!! Note
          All tensors are expected to be on the same device.
  
      !!! Note
          This bias mitigator is not differentiable.
  
      # Returns
  
      bias_mitigated_embeddings : `torch.Tensor`
          A tensor of the same size as evaluation_embeddings.
      """
      # Some sanity checks
      if seed_embeddings1.ndim < 2 or seed_embeddings2.ndim < 2:
          raise ConfigurationError(
              "seed_embeddings1 and seed_embeddings2 must have at least two dimensions."
          )
      if seed_embeddings1.size(-1) != seed_embeddings2.size(-1):
          raise ConfigurationError(
              "All seed embeddings must have same dimensionality."
          )
      if evaluation_embeddings.ndim < 2:
          raise ConfigurationError(
              "evaluation_embeddings must have at least two dimensions."
          )
      if evaluation_embeddings.size(-1) != seed_embeddings1.size(
          -1
      ) or evaluation_embeddings.size(-1) != seed_embeddings2.size(-1):
          raise ConfigurationError(
              "evaluation_embeddings, seed_embeddings1, and seed_embeddings2 must have the same dimensionality."
          )
  
      device = seed_embeddings1.device
      seed_embeddings1 = (
          seed_embeddings1.flatten(end_dim=-2).detach().cpu().numpy()
      )
      seed_embeddings2 = (
          seed_embeddings2.flatten(end_dim=-2).detach().cpu().numpy()
      )
      X = np.vstack([seed_embeddings1, seed_embeddings2])
      Y = np.concatenate(
          [
              [0] * seed_embeddings1.shape[0],
              [1] * seed_embeddings2.shape[0],
          ]
      )
  
      rowspace_projs = []
      for iter_idx in range(num_iters):
          classifier = sklearn.svm.SVC(kernel="linear").fit(X, Y)
          weights = np.expand_dims(classifier.coef_[0], 0)
  
          if (
              np.linalg.norm(weights) < 1e-10
              or classifier.score(X, Y) < 0.55
          ) and iter_idx > 1:
              break
  
          rowspace_projs.append(self._get_rowspace_proj(weights))
          # Project embeddings to intersection of nullspaces
          nullspace_proj = np.eye(
              seed_embeddings1.shape[1]
          ) - self._get_rowspace_proj(np.sum(rowspace_projs, axis=0))
          evaluation_embeddings = torch.matmul(
              evaluation_embeddings,
              torch.from_numpy(nullspace_proj).float().t().to(device),
          )
          X = nullspace_proj.dot(X.T).T
  
      return evaluation_embeddings
  
imports: import torch
  import numpy
  import scipy
  import sklearn
  from allennlp.common.checks import ConfigurationError
label_desc: Use image node_id 2 for calling the INLPBiasMitigator obj's underlying member method code with example usage: obj.__call__(evaluation_embeddings, seed_embeddings1, seed_embeddings2, num_iters) and returns: evaluation_embeddings