code: def cv_protoselect_euclidean(
      trainset: Tuple[np.ndarray, np.ndarray],
      protoset: Optional[Tuple[np.ndarray,]] = None,
      valset: Optional[Tuple[np.ndarray, np.ndarray]] = None,
      num_prototypes: int = 1,
      eps_grid: Optional[np.ndarray] = None,
      quantiles: Optional[Tuple[float, float]] = None,
      grid_size: int = 25,
      n_splits: int = 2,
      batch_size: int = int(1e10),
      preprocess_fn: Optional[
          Callable[[np.ndarray], np.ndarray]
      ] = None,
      protoselect_kw: Optional[dict] = None,
      knn_kw: Optional[dict] = None,
      kfold_kw: Optional[dict] = None,
  ) -> dict:
      """
      Cross-validation parameter selection for `ProtoSelect` with Euclidean distance. The method computes
      the best epsilon radius.
  
      Parameters
      ----------
      trainset
          Tuple, `(X_train, y_train)`, consisting of the training data instances with the corresponding labels.
      protoset
          Tuple, `(Z, )`, consisting of the dataset to choose the prototypes from. If `Z` is not provided
          (i.e., ``protoset=None``), the prototypes will be selected from the training dataset `X`. Otherwise, if `Z`
          is provided, the dataset to be summarised is still `X`, but it is summarised by prototypes belonging to
          the dataset `Z`. Note that the argument is passed as a tuple with a single element for consistency reasons.
      valset
          Optional tuple `(X_val, y_val)` consisting of validation data instances with the corresponding
          validation labels. 1-KNN classifier is evaluated on the validation dataset to obtain the best epsilon radius.
          In case ``valset=None``, then `n-splits` cross-validation is performed on the `trainset`.
      num_prototypes
          The number of prototypes to be selected.
      eps_grid
          Optional grid of values to select the epsilon radius from. If not specified, the search grid is
          automatically proposed based on the inter-distances between `X` and `Z`. The distances are filtered
          by considering only values in between the `quantiles` values. The minimum and maximum distance values are
          used to define the range of values to search the epsilon radius. The interval is discretized in `grid_size`
          equidistant bins.
      quantiles
          Quantiles, `(q_min, q_max)`, to be used to filter the range of values of the epsilon radius. The expected
          quantile values are in `[0, 1]` and clipped to `[0, 1]` if outside the range. See `eps_grid` for usage.
          If not specified, no filtering is applied. Only used if ``eps_grid=None``.
      grid_size
          The number of equidistant bins to be used to discretize the `eps_grid` automatically proposed interval.
          Only used if ``eps_grid=None``.
      batch_size
          Batch size to be used for kernel matrix computation.
      preprocess_fn
          Preprocessing function to be applied to the data instance before applying the kernel.
      protoselect_kw
          Keyword arguments passed to :py:meth:`alibi.prototypes.protoselect.ProtoSelect.__init__`.
      knn_kw
          Keyword arguments passed to `sklearn.neighbors.KNeighborsClassifier`. The `n_neighbors` will be
          set automatically to 1 and the `metric` will be set to ``'euclidean``. See parameters description:
          https://scikit-learn.org/stable/modules/generated/sklearn.neighbors.KNeighborsClassifier.html
      kfold_kw
          Keyword arguments passed to `sklearn.model_selection.KFold`. See parameters description:
          https://scikit-learn.org/stable/modules/generated/sklearn.model_selection.KFold.html
  
      Returns
      -------
      Dictionary containing
       - ``'best_eps'``: ``float`` - the best epsilon radius according to the accuracy of a 1-KNN classifier.
       - ``'meta'``: ``dict`` - dictionary containing argument and data gather throughout cross-validation.
      """
      if protoselect_kw is None:
          protoselect_kw = {}
  
      if kfold_kw is None:
          kfold_kw = {}
  
      if knn_kw is None:
          knn_kw = {}
      # ensure that we are training a 1-KNN classifier with Euclidean distance metric
      knn_kw.update({"n_neighbors": 1, "metric": "euclidean"})
  
      X_train, y_train = trainset
      Z = protoset[0] if (protoset is not None) else X_train
      X_val, y_val = valset if (valset is not None) else (None, None)
  
      if preprocess_fn is not None:
          X_train = _batch_preprocessing(
              X=X_train,
              preprocess_fn=preprocess_fn,
              batch_size=batch_size,
          )
          Z = _batch_preprocessing(
              X=Z, preprocess_fn=preprocess_fn, batch_size=batch_size
          )
          if X_val is not None:
              X_val = _batch_preprocessing(
                  X_val,
                  preprocess_fn=preprocess_fn,
                  batch_size=batch_size,
              )
  
      # propose eps_grid if not specified
      if eps_grid is None:
          dist = batch_compute_kernel_matrix(
              x=X_train, y=Z, kernel=EuclideanDistance()
          ).reshape(-1)
          if quantiles is not None:
              if quantiles[0] > quantiles[1]:
                  raise ValueError(
                      "The quantile lower-bound is greater then the quantile upper-bound."
                  )
              quantiles = np.clip(quantiles, a_min=0, a_max=1)  # type: ignore[assignment]
              min_dist, max_dist = np.quantile(
                  a=dist, q=np.array(quantiles)
              )
          else:
              min_dist, max_dist = np.min(dist), np.max(dist)
          # define list of values for eps
          eps_grid = np.linspace(min_dist, max_dist, num=grid_size)
  
      (X_train, y_train), (X_val, y_val), splits = _get_splits(
          trainset=(X_train, y_train),
          valset=(X_val, y_val),
          kfold_kw=kfold_kw,
      )
      scores = np.zeros((len(eps_grid), len(splits)))
  
      for i, (train_index, val_index) in enumerate(splits):
          X_train_i, y_train_i = (
              X_train[train_index],
              y_train[train_index],
          )
          X_val_i, y_val_i = X_val[val_index], y_val[val_index]
  
          # define and fit the summariser here, so we don't repeat the kernel matrix computation in the next for loop
          summariser = ProtoSelect(
              kernel_distance=EuclideanDistance(),
              eps=0,
              **protoselect_kw,
          )
          summariser = summariser.fit(X=X_train_i, y=y_train_i, Z=Z)
  
          for j in range(len(eps_grid)):
              knn = _helper_protoselect_euclidean_1knn(
                  summariser=summariser,
                  num_prototypes=num_prototypes,
                  eps=eps_grid[j],
                  knn_kw=knn_kw,
              )
              if knn is None:
                  continue
              scores[j][i] = knn.score(X_val_i, y_val_i)
  
      return {
          "best_eps": eps_grid[np.argmax(np.mean(scores, axis=-1))],
          "meta": {
              "num_prototypes": num_prototypes,
              "eps_grid": eps_grid,
              "quantiles": quantiles,
              "grid_size": grid_size,
              "n_splits": n_splits,
              "batch_size": batch_size,
              "scores": scores,
          },
      }
  
imports: import logging
  from copy import deepcopy
  from typing import Callable, Dict, List, Optional, Tuple, Union
  import matplotlib.pyplot
  import numpy
  from matplotlib.offsetbox import AnnotationBbox, OffsetImage
  from skimage.transform import resize
  from sklearn.model_selection import KFold
  from sklearn.neighbors import KNeighborsClassifier
  from tqdm import tqdm
  from alibi.api.defaults import DEFAULT_DATA_PROTOSELECT, DEFAULT_META_PROTOSELECT
  from alibi.api.interfaces import Explanation, FitMixin, Summariser
  from alibi.utils.distance import batch_compute_kernel_matrix
  from alibi.utils.kernel import EuclideanDistance
label_desc: Use image node_id 3 for calling a global function with example usage: cv_protoselect_euclidean(trainset, protoset, valset, num_prototypes, eps_grid, quantiles, grid_size, n_splits, batch_size, preprocess_fn, protoselect_kw, knn_kw, kfold_kw) and returns: dict