code: def eval_metrics_one_dataset(
      model, test_dataloader, device, k_vals, opt
  ):
      """
      Compute evaluation metrics on test-dataset, e.g. NMI, F1 and Recall @ k.
  
      Args:
          model:              PyTorch network, network to compute evaluation metrics for.
          test_dataloader:    PyTorch Dataloader, dataloader for test dataset, should have no shuffling and correct processing.
          device:             torch.device, Device to run inference on.
          k_vals:             list of int, Recall values to compute
          opt:                argparse.Namespace, contains all training-specific parameters.
      Returns:
          F1 score (float), NMI score (float), recall_at_k (list of float), data embedding (np.ndarray)
      """
      torch.cuda.empty_cache()
  
      _ = model.eval()
      n_classes = len(test_dataloader.dataset.avail_classes)
      with torch.no_grad():
          ### For all test images, extract features
          target_labels, feature_coll = [], []
          final_iter = tqdm(
              test_dataloader, desc="Computing Evaluation Metrics..."
          )
          image_paths = [
              x[0] for x in test_dataloader.dataset.image_list
          ]
          for idx, inp in enumerate(final_iter):
              input_img, target = inp[-1], inp[0]
              target_labels.extend(target.numpy().tolist())
              out = model(input_img.to(device), feature=True)
              feature_coll.extend(out.cpu().detach().numpy().tolist())
          # pdb.set_trace()
          target_labels = np.hstack(target_labels).reshape(-1, 1)
          feature_coll = np.vstack(feature_coll).astype("float32")
  
          torch.cuda.empty_cache()
  
          ### Set Faiss CPU Cluster index
          cpu_cluster_index = faiss.IndexFlatL2(feature_coll.shape[-1])
          kmeans = faiss.Clustering(feature_coll.shape[-1], n_classes)
          kmeans.niter = 20
          kmeans.min_points_per_centroid = 1
          kmeans.max_points_per_centroid = 1000000000
  
          ### Train Kmeans
          kmeans.train(feature_coll, cpu_cluster_index)
          computed_centroids = faiss.vector_float_to_array(
              kmeans.centroids
          ).reshape(n_classes, feature_coll.shape[-1])
  
          ### Assign feature points to clusters
          faiss_search_index = faiss.IndexFlatL2(
              computed_centroids.shape[-1]
          )
          faiss_search_index.add(computed_centroids)
          _, model_generated_cluster_labels = faiss_search_index.search(
              feature_coll, 1
          )
  
          ### Compute NMI
          NMI = metrics.cluster.normalized_mutual_info_score(
              model_generated_cluster_labels.reshape(-1),
              target_labels.reshape(-1),
          )
  
          ### Recover max(k_vals) nehbours to use for recall computation
          faiss_search_index = faiss.IndexFlatL2(feature_coll.shape[-1])
          faiss_search_index.add(feature_coll)
          _, k_closest_points = faiss_search_index.search(
              feature_coll, int(np.max(k_vals) + 1)
          )
          k_closest_classes = target_labels.reshape(-1)[
              k_closest_points[:, 1:]
          ]
          print("computing recalls")
          ### Compute Recall
          recall_all_k = []
          for k in k_vals:
              recall_at_k = np.sum(
                  [
                      1
                      for target, recalled_predictions in zip(
                          target_labels, k_closest_classes
                      )
                      if target in recalled_predictions[:k]
                  ]
              ) / len(target_labels)
              recall_all_k.append(recall_at_k)
          print("finished recalls")
          print("computing F1")
          ### Compute F1 Score
          F1 = 0
          # F1 = f1_score(model_generated_cluster_labels, target_labels, feature_coll, computed_centroids)
          print("finished computing f1")
  
      return F1, NMI, recall_all_k, feature_coll
  
imports: import warnings
  import csv
  import datetime
  import os
  import pickle
  import faiss
  import matplotlib.pyplot
  import numpy
  import torch
  from PIL import Image
  from sklearn import metrics
  from torch import nn
  from tqdm import tqdm
  import pdb
label_desc: Use image node_id 5 for calling a global function with example usage: eval_metrics_one_dataset(model, test_dataloader, device, k_vals, opt) and returns: F1,  NMI,  recall_all_k,  feature_coll