code: def nested_shape(array_or_tuple):
      
      if hasattr(array_or_tuple, 'size'):
          # pytorch tensors use V.size() to get size of tensor
          return list(array_or_tuple.size())
      elif hasattr(array_or_tuple, 'get_shape'):
          # tensorflow uses V.get_shape() to get size of tensor
          return array_or_tuple.get_shape().as_list()
      elif hasattr(array_or_tuple, 'shape'):
          return array_or_tuple.shape
  
      try:
          # treat object as iterable
          return [nested_shape(item) for item in list(array_or_tuple)]
      except TypeError:
          # object is not actually iterable
          # LB: Maybe we should throw an error?
          return []
docs: Figures out the shape of tensors possibly embedded in tuples
       i.e 
       [0,0] returns (2)
       ([0,0], [0,0]) returns (2,2)
       (([0,0], [0,0]),[0,0]) returns ((2,2),2)