docstr: Evaluate a model on a given dataset
  
  :param x: Input data. It could be:
      - a TFDataset object
      - A Numpy array (or array-like), or a list of arrays
         (in case the model has multiple inputs).
      - A dict mapping input names to the corresponding array/tensors,
      if the model has named inputs.
  :param y: Target data. Like the input data `x`,
    It should be consistent with `x` (you cannot have Numpy inputs and
    tensor targets, or inversely). If `x` is a TFDataset, `y` should
    not be specified (since targets will be obtained from `x`).
  :param batch_per_thread:
    The default value is 1.
    When distributed is True,the total batch size is batch_per_thread * rdd.getNumPartitions.
    When distributed is False the total batch size is batch_per_thread * numOfCores.
  :param distributed: Boolean. Whether to do prediction in distributed mode or local mode.
               Default is True. In local mode, x must be a Numpy array.
docstr_tok: ["Evaluate","a","model","on","a","given","dataset",":","param","x",":","Input","data",".","It","could","be",":","-","a","TFDataset","object","-","A","Numpy","array","(","or","array-like",")",",","or","a","list","of","arrays","(","in","case","the","model","has","multiple","inputs",")",".","-","A","dict","mapping","input","names","to","the","corresponding","array\/tensors",",","if","the","model","has","named","inputs",".",":","param","y",":","Target","data",".","Like","the","input","data","`","x","`",",","It","should","be","consistent","with","`","x","`","(","you","can","not","have","Numpy","inputs","and","tensor","targets",",","or","inversely",")",".","If","`","x","`","is","a","TFDataset",",","`","y","`","should","not","be","specified","(","since","targets","will","be","obtained","from","`","x","`",")",".",":","param","batch_per_thread",":","The","default","value","is","1",".","When","distributed","is","True",",","the","total","batch","size","is","batch_per_thread","*","rdd.getNumPartitions",".","When","distributed","is","False","the","total","batch","size","is","batch_per_thread","*","numOfCores",".",":","param","distributed",":","Boolean",".","Whether","to","do","prediction","in","distributed","mode","or","local","mode",".","Default","is","True",".","In","local","mode",",","x","must","be","a","Numpy","array","."]
code: def evaluate(
      self, x=None, y=None, batch_per_thread=None, distributed=False
  ):
      """
      Evaluate a model on a given dataset
  
      :param x: Input data. It could be:
          - a TFDataset object
          - A Numpy array (or array-like), or a list of arrays
             (in case the model has multiple inputs).
          - A dict mapping input names to the corresponding array/tensors,
          if the model has named inputs.
      :param y: Target data. Like the input data `x`,
        It should be consistent with `x` (you cannot have Numpy inputs and
        tensor targets, or inversely). If `x` is a TFDataset, `y` should
        not be specified (since targets will be obtained from `x`).
      :param batch_per_thread:
        The default value is 1.
        When distributed is True,the total batch size is batch_per_thread * rdd.getNumPartitions.
        When distributed is False the total batch size is batch_per_thread * numOfCores.
      :param distributed: Boolean. Whether to do prediction in distributed mode or local mode.
                   Default is True. In local mode, x must be a Numpy array.
      """
      if isinstance(x, TFDataset):
          if not x.has_batch:
              raise ValueError(
                  "The batch_per_thread of TFDataset must be "
                  + "specified when used in KerasModel evaluate."
              )
          if isinstance(x, TFNdarrayDataset):
              x = _standarize_feature_label_dataset(x, self.model)
          # todo check arguments
          check_data_compatible(x, self.model, mode="evaluate")
  
          return self._evaluate_distributed(x)
      else:
          if distributed:
              dataset = TFDataset.from_ndarrays(
                  (x, y),
                  batch_per_thread=-1
                  if batch_per_thread is None
                  else batch_per_thread,
              )
              dataset = _standarize_feature_label_dataset(
                  dataset, self.model
              )
              return self._evaluate_distributed(dataset)
          else:
              results = self.model.evaluate(
                  x=x, y=y, batch_size=batch_per_thread
              )
              results = dict(zip(self.metrics_names, results))
              return results
  
imports: import numpy
  from bigdl.optim.optimizer import MaxEpoch
  from zoo.tfpark.utils import evaluate_string_metrics
  from zoo.common import enable_multi_fs_save, enable_multi_fs_load
  from zoo.common.nncontext import getOrCreateSparkContext
  from zoo.tfpark.tf_dataset import TFNdarrayDataset, TFDataset, _standarize_feature_label_dataset, check_data_compatible
  from zoo.tfpark.tf_optimizer import TFOptimizer
  from zoo.tfpark.tf_predictor import TFPredictor
label_desc: Use image node_id 12 for calling the KerasModel obj's underlying member method code with example usage: obj.evaluate(x, y, batch_per_thread, distributed) and returns: self, self, results