code: def validation_step(self, batch, batch_idx) -> None:
      if (
          self._train_features_tensor is None
          or self._train_targets_tensor is None
      ):
          return
  
      images, targets = batch[0], batch[1]
      features = self.model.forward(images).flatten(start_dim=1)
      if self.normalize:
          features = F.normalize(features, dim=1)
      features = features.to(self.feature_dtype)
      predicted_classes = knn_predict(
          feature=features,
          feature_bank=self._train_features_tensor,
          feature_labels=self._train_targets_tensor,
          num_classes=self.num_classes,
          knn_k=self.knn_k,
          knn_t=self.knn_t,
      )
      topk = mean_topk_accuracy(
          predicted_classes=predicted_classes,
          targets=targets,
          k=self.topk,
      )
      log_dict = {f"val_top{k}": acc for k, acc in topk.items()}
      self.log_dict(
          log_dict,
          prog_bar=True,
          sync_dist=True,
          batch_size=len(targets),
      )
  
file_path: lightly/lightly/utils/benchmarking/knn_classifier.py
imports: from typing import Tuple, Union
  import torch
  import torch.nn.functional
  from pytorch_lightning import LightningModule
  from torch import Tensor
  from torch.nn import Module
  from lightly.utils.benchmarking import knn_predict
  from lightly.utils.benchmarking.topk import mean_topk_accuracy
label_desc: Use image node_id 3 for calling the KNNClassifier obj's underlying member method code with example usage: obj.validation_step(batch, batch_idx) without return types