class_docstr: Callback to compute specific metric and logs during train and eval
class_docstr_tok: ["Callback","to","compute","specific","metric","and","logs","during","train","and","eval"]
docstr: computing token error
docstr_tok: ["computing","token","error"]
code: def on_epoch_end(self, epoch, logs={}):
      """computing token error"""
  
      cur_session = tf.keras.backend.get_session()
      target_seq_list, predict_seq_list = [], []
  
      is_py_sequence = True
      if isinstance(
          self.eval_ds, (dataset_ops.DatasetV2, dataset_ops.DatasetV1)
      ):
          eval_gen = self.eval_ds.make_one_shot_iterator()
          self.next_batch_gen = eval_gen.get_next()[0]
          is_py_sequence = False
      elif isinstance(
          self.eval_ds, (iterator_ops.IteratorV2, iterator_ops.Iterator)
      ):
          self.next_batch_gen = self.ds.get_next()[0]
          is_py_sequence = False
  
      for index in range(len(self.eval_task)):
          batch_data = None
          if is_py_sequence:
              batch_data = self.eval_ds[index][0]
          else:
              batch_data = cur_session.run(self.next_batch_gen)
          batch_input = batch_data["inputs"]
          batch_target = batch_data["targets"].tolist()
          batch_predict = self.func(batch_input)[0]
  
          if self.decoder_type == "argmax":
              predict_seq_list += py_ctc.ctc_greedy_decode(
                  batch_predict, 0, unique=True
              )
          else:
              sequence_lens = [
                  len(pre_sequence) for pre_sequence in batch_predict
              ]
              batch_decoder, _ = tf_ctc.ctc_beam_search_decode(
                  tf.constant(batch_predict),
                  tf.constant(sequence_lens),
                  beam_width=3,
                  top_paths=3,
              )
              predict_seq_list += cur_session.run(batch_decoder)[
                  0
              ].tolist()
          target_seq_list += batch_target
  
      val_token_errors = metrics_lib.token_error(
          predict_seq_list=predict_seq_list,
          target_seq_list=target_seq_list,
          eos_id=0,
      )
      logs["val_token_err"] = val_token_errors
  
      if "val_loss" in logs:
          logging.info(
              "Epoch {}: on eval, val_loss is {}.".format(
                  epoch + 1, logs["val_loss"]
              )
          )
      logging.info(
          "Epoch {}: on eval, token_err is {}.".format(
              epoch + 1, val_token_errors
          )
      )
      logging.info(
          "Epoch {}: loss on train is {}".format(
              epoch + 1, logs["loss"]
          )
      )
  
imports: from absl import logging
  import delta.compat
  import numpy
  from tensorflow.keras.callbacks import Callback
  from tensorflow.keras.callbacks import ModelCheckpoint
  from tensorflow.keras import backend
  from sklearn import metrics
  from tensorflow.python.data.ops import iterator_ops
  from tensorflow.python.data.ops import dataset_ops
  from delta.utils.decode import py_ctc
  from delta.utils.decode import tf_ctc
  from delta.utils import metrics
label_desc: Use image node_id 2 for calling the TokenErrMetricCallBack obj's underlying member method code with example usage: obj.on_epoch_end(epoch, logs) without return types