class_docstr: Torch implementation of the CFA Model.
  
  Args:
      input_size: (tuple[int, int]): Input size of the image tensor.
      backbone (str): Backbone CNN network.
      gamma_c (int): gamma_c parameter from the paper.
      gamma_d (int): gamma_d parameter from the paper.
      num_nearest_neighbors (int): Number of nearest neighbors.
      num_hard_negative_features (int): Number of hard negative features.
      radius (float): Radius of the hypersphere to search the soft boundary.
class_docstr_tok: ["Torch","implementation","of","the","CFA","Model",".","Args",":","input_size",":","(","tuple","[","int",",","int","]",")",":","Input","size","of","the","image","tensor",".","backbone","(","str",")",":","Backbone","CNN","network",".","gamma_c","(","int",")",":","gamma_c","parameter","from","the","paper",".","gamma_d","(","int",")",":","gamma_d","parameter","from","the","paper",".","num_nearest_neighbors","(","int",")",":","Number","of","nearest","neighbors",".","num_hard_negative_features","(","int",")",":","Number","of","hard","negative","features",".","radius","(","float",")",":","Radius","of","the","hypersphere","to","search","the","soft","boundary","."]
docstr: Forward pass.
  
  Args:
      input_tensor (Tensor): Input tensor.
  
  Raises:
      ValueError: When the memory bank is not initialized.
  
  Returns:
      Tensor: Loss or anomaly map depending on the train/eval mode.
docstr_tok: ["Forward","pass",".","Args",":","input_tensor","(","Tensor",")",":","Input","tensor",".","Raises",":","ValueError",":","When","the","memory","bank","is","not","initialized",".","Returns",":","Tensor",":","Loss","or","anomaly","map","depending","on","the","train\/eval","mode","."]
code: def forward(self, input_tensor: Tensor) -> Tensor:
      """Forward pass.
  
      Args:
          input_tensor (Tensor): Input tensor.
  
      Raises:
          ValueError: When the memory bank is not initialized.
  
      Returns:
          Tensor: Loss or anomaly map depending on the train/eval mode.
      """
      if self.memory_bank.ndim == 0:
          raise ValueError(
              "Memory bank is not initialized. Run `initialize_centroid` method first."
          )
  
      self.feature_extractor.eval()
      with torch.no_grad():
          features = self.feature_extractor(input_tensor)
          features = list(features.values())
  
      target_features = self.descriptor(features)
      distance = self.compute_distance(target_features)
  
      if self.training:
          output = distance
      else:
          output = self.anomaly_map_generator(
              distance=distance, scale=self.scale
          )
  
      return output
  
imports: from __future__ import annotations
  import torch
  import torch.nn.functional
  import torchvision
  from einops import rearrange
  from sklearn.cluster import KMeans
  from torch import Tensor, nn
  from torch.fx.graph_module import GraphModule
  from torch.nn.common_types import _size_2_t
  from torch.utils.data import DataLoader
  from torchvision.models.feature_extraction import create_feature_extractor
  from tqdm import tqdm
  from anomalib.models.cfa.anomaly_map import AnomalyMapGenerator
  from anomalib.models.components import DynamicBufferModule
  from anomalib.models.components.feature_extractors import dryrun_find_featuremap_dims
label_desc: Use image node_id 4 for calling the CfaModel obj's underlying member method code with example usage: obj.forward(input_tensor) and returns: output