code: def check_should_stop(
      performance_history,
      mode="mean",
      min_delta=0.03,
      kernel_size=5,
      k_splits=5,
  ):
      """
      This function takes in a mode, performance_history and patience and
      returns True if the application should stop early.
      :param mode: {'mean', 'robust_mean', 'median', 'generalisation_loss',
       'median_smoothing', 'validation_up'} the default mode is 'mean'
      mean:
          If your last loss is less than the average across the entire
          performance history stop training
      robust_mean:
          Same as 'mean' but only loss values within 5th and 95th
          percentile are considered
      median:
          As in mode='mean' but using the median
      generalisation_loss:
          Computes generalisation loss over the performance
          history, and stops if it reaches an arbitrary threshold of 0.2.
      validation_up:
          This method check for performance increases in k sub-arrays of
          length s, where k x s = patience. Because we cannot guarantee
          patience to be divisible by both k and s, we define that k is
          either 4 or 5, depending on which has the smallest remainder when
          dividing.
      :param performance_history: a list of size patience with the performance
      history
      :param min_delta: threshold for smoothness
      :param kernel_size: hyperparameter for median smoothing
      :param k_splits: number of splits if using 'validation_up'
      :return:
      """
      if mode == "mean":
          performance_to_consider = performance_history[:-1]
          thresh = np.mean(performance_to_consider)
          tf.logging.info("====Mean====")
          tf.logging.info(thresh)
          tf.logging.info(performance_history[-1])
          should_stop = performance_history[-1] > thresh
  
      elif mode == "robust_mean":
          performance_to_consider = performance_history[:-1]
          perc = np.percentile(performance_to_consider, q=[5, 95])
          temp = []
          for perf_val in performance_to_consider:
              if perc[0] < perf_val < perc[1]:
                  temp.append(perf_val)
          should_stop = performance_history[-1] > np.mean(temp)
  
      elif mode == "median":
          performance_to_consider = performance_history[:-1]
          should_stop = performance_history[-1] > np.median(
              performance_to_consider
          )
  
      elif mode == "generalisation_loss":
          value = compute_generalisation_loss(performance_history)
          should_stop = value > 0.2
  
      elif mode == "median_smoothing":
          smoothed = median_filter(
              performance_history[:-1], size=kernel_size
          )
          gradient = np.gradient(smoothed)
          thresholded = np.where(gradient < min_delta, 1, 0)
          value = np.sum(thresholded) * 1.0 / len(gradient)
          should_stop = value < 0.5
      elif mode == "validation_up":
          remainder = len(performance_history) % k_splits
          performance_to_consider = performance_history[remainder:]
          strips = np.split(np.array(performance_to_consider), k_splits)
          gl_increase = []
          for strip in strips:
              generalisation_loss = compute_generalisation_loss(strip)
              gl_increase.append(generalisation_loss >= min_delta)
          tf.logging.info("====Validation_up====")
          tf.logging.info(gl_increase)
          should_stop = False not in gl_increase
      else:
          raise Exception(
              "Mode: {} provided is not supported".format(mode)
          )
      return should_stop
  
file_path: NiftyNet/niftynet/engine/handler_early_stopping.py
imports: import numpy
  import tensorflow
  from scipy.ndimage import median_filter
  from niftynet.engine.signal import ITER_FINISHED
label_desc: Use image node_id 2 for calling a global function with example usage: check_should_stop(performance_history, mode, min_delta, kernel_size, k_splits) and returns: should_stop