class_docstr: This is an implementation of `NearestNeighbors` that uses the Annoy module. At a
  high level, Annoy finds nearest neighbors by constructing binary trees in which
  vectors reside at leaf nodes. Vectors near each other will tend to be in the same
  leaf node. See https://tinyurl.com/2p89sb2h and https://github.com/spotify/annoy
  for more details. Annoy has 1 key parameter: the number of trees to construct.
  Increasing the number of trees leads to more accurate results, but longer time to
  create the trees and memory usage. As mentioned in the `NearestNeighbors`
  documentation, for the use case of computing proponents / opponents, the nearest
  neighbors returned should be those with the largest dot product with the query
  vector. The term "vector" is used here because Annoy stores 1D vectors. However
  in our wrapper around Annoy, we will allow the stored tensors to be of a common
  but arbitrary shape *, and flatten them before storing in the Annoy data structure.
class_docstr_tok: ["This","is","an","implementation","of","`","NearestNeighbors","`","that","uses","the","Annoy","module",".","At","a","high","level",",","Annoy","finds","nearest","neighbors","by","constructing","binary","trees","in","which","vectors","reside","at","leaf","nodes",".","Vectors","near","each","other","will","tend","to","be","in","the","same","leaf","node",".","See","https",":","\/\/tinyurl.com\/2p89sb2h","and","https",":","\/\/github.com\/spotify\/annoy","for","more","details",".","Annoy","has","1","key","parameter",":","the","number","of","trees","to","construct",".","Increasing","the","number","of","trees","leads","to","more","accurate","results",",","but","longer","time","to","create","the","trees","and","memory","usage",".","As","mentioned","in","the","`","NearestNeighbors","`","documentation",",","for","the","use","case","of","computing","proponents","\/","opponents",",","the","nearest","neighbors","returned","should","be","those","with","the","largest","dot","product","with","the","query","vector",".","The","term","``","vector","''","is","used","here","because","Annoy","stores","1D","vectors",".","However","in","our","wrapper","around","Annoy",",","we","will","allow","the","stored","tensors","to","be","of","a","common","but","arbitrary","shape","*",",","and","flatten","them","before","storing","in","the","Annoy","data","structure","."]
docstr: `data` denotes the "stored tensors". These are the tensors within which we
  want to find the nearest neighbors to a query tensor, via a call to the
  `get_nearest_neighbors` method. Before we can call `get_nearest_neighbors`,
  we need to first store the stored tensors, by doing processing that indexes
  the stored tensors in a form that enables nearest-neighbors computation.
  This method does that preprocessing, and is assumed to be called before any
  call to `get_nearest_neighbors`. In particular, it creates the trees used to
  index the stored tensors. This index is built to enable computation of
  vectors that have the largest dot-product with the query tensors. The tensors
  in the "stored tensors" can be of a common, but arbitrary shape, denoted *, so
  that `data` is of shape (N, *), where N is the number of tensors in the stored
  tensors. Therefore, the 0-th dimension indexes the tensors in the stored
  tensors.
  
  Args:
      data (Tensor): A tensor of shape (N, *) representing the stored tensors.
              The 0-th dimension indexes the tensors in the stored tensors,
              so that `data[i]` is the tensor with index `i`. The nearest
              neighbors of a query will be referred to by their index.
docstr_tok: ["`","data","`","denotes","the","``","stored","tensors","''",".","These","are","the","tensors","within","which","we","want","to","find","the","nearest","neighbors","to","a","query","tensor",",","via","a","call","to","the","`","get_nearest_neighbors","`","method",".","Before","we","can","call","`","get_nearest_neighbors","`",",","we","need","to","first","store","the","stored","tensors",",","by","doing","processing","that","indexes","the","stored","tensors","in","a","form","that","enables","nearest-neighbors","computation",".","This","method","does","that","preprocessing",",","and","is","assumed","to","be","called","before","any","call","to","`","get_nearest_neighbors","`",".","In","particular",",","it","creates","the","trees","used","to","index","the","stored","tensors",".","This","index","is","built","to","enable","computation","of","vectors","that","have","the","largest","dot-product","with","the","query","tensors",".","The","tensors","in","the","``","stored","tensors","''","can","be","of","a","common",",","but","arbitrary","shape",",","denoted","*",",","so","that","`","data","`","is","of","shape","(","N",",","*",")",",","where","N","is","the","number","of","tensors","in","the","stored","tensors",".","Therefore",",","the","0-th","dimension","indexes","the","tensors","in","the","stored","tensors",".","Args",":","data","(","Tensor",")",":","A","tensor","of","shape","(","N",",","*",")","representing","the","stored","tensors",".","The","0-th","dimension","indexes","the","tensors","in","the","stored","tensors",",","so","that","`","data","[","i","]","`","is","the","tensor","with","index","`","i","`",".","The","nearest","neighbors","of","a","query","will","be","referred","to","by","their","index","."]
code: def setup(self, data: torch.Tensor) -> None:
      """
      `data` denotes the "stored tensors". These are the tensors within which we
      want to find the nearest neighbors to a query tensor, via a call to the
      `get_nearest_neighbors` method. Before we can call `get_nearest_neighbors`,
      we need to first store the stored tensors, by doing processing that indexes
      the stored tensors in a form that enables nearest-neighbors computation.
      This method does that preprocessing, and is assumed to be called before any
      call to `get_nearest_neighbors`. In particular, it creates the trees used to
      index the stored tensors. This index is built to enable computation of
      vectors that have the largest dot-product with the query tensors. The tensors
      in the "stored tensors" can be of a common, but arbitrary shape, denoted *, so
      that `data` is of shape (N, *), where N is the number of tensors in the stored
      tensors. Therefore, the 0-th dimension indexes the tensors in the stored
      tensors.
  
      Args:
          data (Tensor): A tensor of shape (N, *) representing the stored tensors.
                  The 0-th dimension indexes the tensors in the stored tensors,
                  so that `data[i]` is the tensor with index `i`. The nearest
                  neighbors of a query will be referred to by their index.
      """
      import annoy
  
      data = data.view((len(data), -1))
      projection_dim = data.shape[1]
      self.knn_index = annoy.AnnoyIndex(projection_dim, "dot")
      for i, projection in enumerate(data):
          self.knn_index.add_item(i, projection)
      self.knn_index.build(self.num_trees)
  
file_path: captum/captum/influence/_utils/nearest_neighbors.py
imports: from abc import ABC, abstractmethod
  from typing import Tuple
  import torch
  from torch import Tensor
label_desc: Use image node_id 2 for calling the AnnoyNearestNeighbors obj's underlying member method code with example usage: obj.setup(data) without return types