code: def _unbatch(batch):
      """Splits a dictionary of batched tensors into a list of dictionaries."""
      unbatched = []
      for key, val in batch.items():
          if isinstance(val, (tf.Tensor, np.ndarray)):
              if not unbatched:
                  unbatched = [{} for _ in range(val.shape[0])]
              assert val.shape[0] == len(
                  unbatched
              ), f"batch size mismatch: {val.shape[0]} vs {len(unbatched)}"
              for i in range(val.shape[0]):
                  unbatched[i][key] = val[i]
          elif isinstance(val, dict):
              sub_batch = _unbatch(val)
              if not unbatched:
                  unbatched = [{} for _ in sub_batch]
              for i in range(len(sub_batch)):
                  unbatched[i][key] = sub_batch[i]
          elif val is None:
              continue
          else:
              raise Exception(
                  f"unsupported value at {key}:{val} of type {type(val)}"
              )
      return unbatched
  
file_path: ddsp/ddsp/training/heuristics.py
imports: import ddsp
  import gin
  import note_seq
  import numpy
  import tensorflow.compat.v2
label_desc: Use image node_id 2 for calling a global function with example usage: _unbatch(batch) and returns: unbatched