code: def eval(self, feed_dict=None):
          
          # first, check that the length of all feed_dict keys match our own length
          for tensor_ensemble in feed_dict:
              if len(tensor_ensemble.tensors) != len(self.tensors):
                  raise EnsembleMismatchException("incompatible lengths of tensors: %d, %d" \
                                                  % (len(self.tensors), len(tensor_ensemble.tensors)))
  
          # create a joined uuid
          _uuid = uuid4()
  
          # prepare feed_dicts
          feed_dicts = [{} for _ in range(len(self.tensors))]
          for tensor_ensemble, value in feed_dict.items():
              for i, tensor in enumerate(tensor_ensemble.tensors):
                  if tensor is not None:
                      feed_dicts[i][tensor] = value[i] if isinstance(value, (list, tuple)) else value
  
          # eval all tensors
          values = [t.eval(feed_dict=d, _uuid=_uuid) for t, d in zip(self.tensors, feed_dicts)]
  
          # return the computed ensemble value
          return self.func(values)
docs: Evaluates all contained tensors using a *feed_dict* and returns the ensemble value. The keys
          of *feed_dict* must be tensor ensembles. Its values can be batches, i.e., numpy arrays, or
          lists or tuples of batches. In the latter case, these lists or tuples must have the same
          length as the list of stored tensors as they will be mapped.