code: def val(args, model, test_dataloader, class_name, idx):
      print(
          datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
          + "\t"
          + "Starting eval model..."
      )
      total_roc_auc = []
      total_pixel_roc_auc = []
  
      gt_list = []
      gt_mask_list = []
      test_imgs = []
  
      test_outputs = OrderedDict(
          [("layer1", []), ("layer2", []), ("layer3", [])]
      )
      # extract test set features
      for x, y, mask in tqdm(
          test_dataloader,
          "| feature extraction | test | %s |" % class_name,
      ):
          test_imgs.extend(x.cpu().detach().numpy())
          gt_list.extend(y.cpu().detach().numpy())
          gt_mask_list.extend(mask.cpu().detach().numpy())
          # model prediction
          with paddle.no_grad():
              outputs = model(x)
          # get intermediate layer outputs
          for k, v in zip(test_outputs.keys(), outputs):
              test_outputs[k].append(v.cpu().detach())
      print(
          datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
          + "\t"
          + "Eval model..."
      )
      for k, v in test_outputs.items():
          test_outputs[k] = paddle.concat(v, 0)
  
      # Embedding concat
      embedding_vectors = test_outputs["layer1"]
      for layer_name in ["layer2", "layer3"]:
          layer_embedding = test_outputs[layer_name]
          layer_embedding = F.interpolate(
              layer_embedding,
              size=embedding_vectors.shape[-2:],
              mode="nearest",
          )
          embedding_vectors = paddle.concat(
              (embedding_vectors, layer_embedding), 1
          )
  
      # randomly select d dimension
      embedding_vectors = paddle.index_select(embedding_vectors, idx, 1)
  
      # calculate distance matrix
      if paddle.device.is_compiled_with_cuda():
  
          def mahalanobis_pd(sample, mean, conv_inv):
              return paddle.sqrt(
                  paddle.matmul(
                      paddle.matmul((sample - mean).t(), conv_inv),
                      (sample - mean),
                  )
              )[0]
  
          B, C, H, W = embedding_vectors.shape
          embedding_vectors = embedding_vectors.reshape(
              (B, C, H * W)
          ).cuda()
          model.distribution[0] = paddle.to_tensor(
              model.distribution[0]
          ).cuda()
          model.distribution[1] = paddle.to_tensor(
              model.distribution[1]
          ).cuda()
          dist_list = []
          for i in range(H * W):
              mean = model.distribution[0][:, i]
              conv_inv = paddle.linalg.inv(
                  model.distribution[1][:, :, i]
              )
              dist = [
                  mahalanobis_pd(sample[:, i], mean, conv_inv).numpy()[
                      0
                  ]
                  for sample in embedding_vectors
              ]
              dist_list.append(dist)
      else:
          # calculate distance matrix
          B, C, H, W = embedding_vectors.shape
          embedding_vectors = embedding_vectors.reshape(
              (B, C, H * W)
          ).numpy()
          dist_list = []
          for i in range(H * W):
              mean = model.distribution[0][:, i]
              conv_inv = np.linalg.inv(model.distribution[1][:, :, i])
              dist = [
                  mahalanobis(sample[:, i], mean, conv_inv)
                  for sample in embedding_vectors
              ]
              dist_list.append(dist)
  
      dist_list = np.array(dist_list).transpose(1, 0).reshape(B, H, W)
  
      # upsample
      dist_list = paddle.to_tensor(dist_list)
      score_map = (
          F.interpolate(
              dist_list.unsqueeze(1),
              size=x.shape[2:],
              mode="bilinear",
              align_corners=False,
          )
          .squeeze()
          .numpy()
      )
  
      # apply gaussian smoothing on the score map
      for i in range(score_map.shape[0]):
          score_map[i] = gaussian_filter(score_map[i], sigma=4)
  
      # Normalization
      max_score = score_map.max()
      min_score = score_map.min()
      scores = (score_map - min_score) / (max_score - min_score)
  
      # calculate image-level ROC AUC score
      img_scores = scores.reshape(scores.shape[0], -1).max(axis=1)
      gt_list = np.asarray(gt_list)
      fpr, tpr, _ = roc_curve(gt_list, img_scores)
      img_roc_auc = roc_auc_score(gt_list, img_scores)
      total_roc_auc.append(img_roc_auc)
  
      # get optimal threshold
      gt_mask = np.asarray(gt_mask_list, dtype=np.int64)
      precision, recall, thresholds = precision_recall_curve(
          gt_mask.flatten(), scores.flatten()
      )
      a = 2 * precision * recall
      b = precision + recall
      f1 = np.divide(a, b, out=np.zeros_like(a), where=b != 0)
      threshold = thresholds[np.argmax(f1)]
  
      # calculate per-pixel level ROCAUC
      fpr, tpr, _ = roc_curve(gt_mask.flatten(), scores.flatten())
      per_pixel_rocauc = roc_auc_score(
          gt_mask.flatten(), scores.flatten()
      )
      total_pixel_roc_auc.append(per_pixel_rocauc)
  
      if args.save_pic:
          save_name = os.path.join(
              args.save_path, args.backbone, args.category
          )
          dir_name = os.path.dirname(save_name)
          if dir_name and not os.path.exists(dir_name):
              os.makedirs(dir_name)
          plot_fig(
              test_imgs,
              scores,
              gt_mask_list,
              threshold,
              save_name,
              class_name,
          )
      return np.mean(total_roc_auc), np.mean(total_pixel_roc_auc)
  
imports: import os
  import sys
  import random
  import argparse
  import datetime
  from random import sample
  from collections import OrderedDict
  import numpy
  import pandas
  import matplotlib
  import matplotlib.pyplot
  from tqdm import tqdm
  from sklearn.metrics import roc_auc_score
  from sklearn.metrics import roc_curve
  from sklearn.metrics import precision_recall_curve
  from scipy.spatial.distance import mahalanobis
  from scipy.ndimage import gaussian_filter
  from skimage import morphology
  from skimage.segmentation import mark_boundaries
  import paddle
  import paddle.nn.functional
  from paddle.io import DataLoader
  import qinspector.uad.datasets.mvtec
  from qinspector.uad.models.padim import ResNet_PaDiM
  from qinspector.cvlib.uad_configs import *
label_desc: Use image node_id 3 for calling a global function with example usage: val(args, model, test_dataloader, class_name, idx) and returns: np,  np, paddle