class_docstr: A PyTorch Lightning Module for automated kNN callback
  
  At the end of every training epoch we create a feature bank by feeding the
  `dataloader_kNN` passed to the module through the backbone.
  At every validation step we predict features on the validation data.
  After all predictions on validation data (validation_epoch_end) we evaluate
  the predictions on a kNN classifier on the validation data using the
  feature_bank features from the train data.
  
  We can access the highest test accuracy during a kNN prediction
  using the `max_accuracy` attribute.
  
  Attributes:
      backbone:
          The backbone model used for kNN validation. Make sure that you set the
          backbone when inheriting from `BenchmarkModule`.
      max_accuracy:
          Floating point number between 0.0 and 1.0 representing the maximum
          test accuracy the benchmarked model has achieved.
      dataloader_kNN:
          Dataloader to be used after each training epoch to create feature bank.
      num_classes:
          Number of classes. E.g. for cifar10 we have 10 classes. (default: 10)
      knn_k:
          Number of nearest neighbors for kNN
      knn_t:
          Temperature parameter for kNN
  
  Examples:
      >>> class SimSiamModel(BenchmarkingModule):
      >>>     def __init__(dataloader_kNN, num_classes):
      >>>         super().__init__(dataloader_kNN, num_classes)
      >>>         resnet = lightly.models.ResNetGenerator('resnet-18')
      >>>         self.backbone = nn.Sequential(
      >>>             *list(resnet.children())[:-1],
      >>>             nn.AdaptiveAvgPool2d(1),
      >>>         )
      >>>         self.resnet_simsiam =
      >>>             lightly.models.SimSiam(self.backbone, num_ftrs=512)
      >>>         self.criterion = lightly.loss.SymNegCosineSimilarityLoss()
      >>>
      >>>     def forward(self, x):
      >>>         self.resnet_simsiam(x)
      >>>
      >>>     def training_step(self, batch, batch_idx):
      >>>         (x0, x1), _, _ = batch
      >>>         x0, x1 = self.resnet_simsiam(x0, x1)
      >>>         loss = self.criterion(x0, x1)
      >>>         return loss
      >>>     def configure_optimizers(self):
      >>>         optim = torch.optim.SGD(
      >>>             self.resnet_simsiam.parameters(), lr=6e-2, momentum=0.9
      >>>         )
      >>>         return [optim]
      >>>
      >>> model = SimSiamModel(dataloader_train_kNN)
      >>> trainer = pl.Trainer()
      >>> trainer.fit(
      >>>     model,
      >>>     train_dataloader=dataloader_train_ssl,
      >>>     val_dataloaders=dataloader_test
      >>> )
      >>> # you can get the peak accuracy using
      >>> print(model.max_accuracy)
class_docstr_tok: ["A","PyTorch","Lightning","Module","for","automated","kNN","callback","At","the","end","of","every","training","epoch","we","create","a","feature","bank","by","feeding","the","`","dataloader_kNN","`","passed","to","the","module","through","the","backbone",".","At","every","validation","step","we","predict","features","on","the","validation","data",".","After","all","predictions","on","validation","data","(","validation_epoch_end",")","we","evaluate","the","predictions","on","a","kNN","classifier","on","the","validation","data","using","the","feature_bank","features","from","the","train","data",".","We","can","access","the","highest","test","accuracy","during","a","kNN","prediction","using","the","`","max_accuracy","`","attribute",".","Attributes",":","backbone",":","The","backbone","model","used","for","kNN","validation",".","Make","sure","that","you","set","the","backbone","when","inheriting","from","`","BenchmarkModule","`",".","max_accuracy",":","Floating","point","number","between","0.0","and","1.0","representing","the","maximum","test","accuracy","the","benchmarked","model","has","achieved",".","dataloader_kNN",":","Dataloader","to","be","used","after","each","training","epoch","to","create","feature","bank",".","num_classes",":","Number","of","classes",".","E.g",".","for","cifar10","we","have","10","classes",".","(","default",":","10",")","knn_k",":","Number","of","nearest","neighbors","for","kNN","knn_t",":","Temperature","parameter","for","kNN","Examples",":",">",">",">","class","SimSiamModel","(","BenchmarkingModule",")",":",">",">",">","def","__init__","(","dataloader_kNN",",","num_classes",")",":",">",">",">","super","(",")",".__init__","(","dataloader_kNN",",","num_classes",")",">",">",">","resnet","=","lightly.models.ResNetGenerator","(","'resnet-18","'",")",">",">",">","self.backbone","=","nn.Sequential","(",">",">",">","*","list","(","resnet.children","(",")",")","[",":","-1","]",",",">",">",">","nn.AdaptiveAvgPool2d","(","1",")",",",">",">",">",")",">",">",">","self.resnet_simsiam","=",">",">",">","lightly.models.SimSiam","(","self.backbone",",","num_ftrs=512",")",">",">",">","self.criterion","=","lightly.loss.SymNegCosineSimilarityLoss","(",")",">",">",">",">",">",">","def","forward","(","self",",","x",")",":",">",">",">","self.resnet_simsiam","(","x",")",">",">",">",">",">",">","def","training_step","(","self",",","batch",",","batch_idx",")",":",">",">",">","(","x0",",","x1",")",",","_",",","_","=","batch",">",">",">","x0",",","x1","=","self.resnet_simsiam","(","x0",",","x1",")",">",">",">","loss","=","self.criterion","(","x0",",","x1",")",">",">",">","return","loss",">",">",">","def","configure_optimizers","(","self",")",":",">",">",">","optim","=","torch.optim.SGD","(",">",">",">","self.resnet_simsiam.parameters","(",")",",","lr=6e-2",",","momentum=0.9",">",">",">",")",">",">",">","return","[","optim","]",">",">",">",">",">",">","model","=","SimSiamModel","(","dataloader_train_kNN",")",">",">",">","trainer","=","pl.Trainer","(",")",">",">",">","trainer.fit","(",">",">",">","model",",",">",">",">","train_dataloader=dataloader_train_ssl",",",">",">",">","val_dataloaders=dataloader_test",">",">",">",")",">",">",">","#","you","can","get","the","peak","accuracy","using",">",">",">","print","(","model.max_accuracy",")"]
code: def __init__(
      self,
      dataloader_kNN: DataLoader,
      num_classes: int,
      knn_k: int = 200,
      knn_t: float = 0.1,
  ):
      super().__init__()
      self.backbone = nn.Module()
      self.max_accuracy = 0.0
      self.dataloader_kNN = dataloader_kNN
      self.num_classes = num_classes
      self.knn_k = knn_k
      self.knn_t = knn_t
  
      self._train_features: Optional[Tensor] = None
      self._train_targets: Optional[Tensor] = None
      self._val_predicted_labels: List[Tensor] = []
      self._val_targets: List[Tensor] = []
  
file_path: lightly/lightly/utils/benchmarking/benchmark_module.py
imports: from typing import List, Optional
  import torch
  import torch.distributed
  import torch.nn
  import torch.nn.functional
  from pytorch_lightning import LightningModule
  from torch import Tensor
  from torch.utils.data import DataLoader
  from lightly.utils.benchmarking.knn import knn_predict
label_desc: Use image node_id 1 to create a new BenchmarkModule object from inherited base classes: LightningModule with example: obj = BenchmarkModule(dataloader_kNN, num_classes, knn_k, knn_t)