(nodes,
                    num_images,
                    get_leaves_fn,
                    get_spanning_leaves_fn,
                    graph_name=None,
                    min_way=5,
                    max_way=50)
Compute and display statistics about the graph defined by nodes.

  In particular, the statistics that are computed are:
  the number of nodes, the numbers of roots and leaves, the min/max/mean number
  of images living in the leaves, the min/max/mean number of children of
  internal nodes, the min/max/mean depth of leaves.

  Args:
    nodes: A set of Synsets representing a graph.
    num_images: A dict mapping each node's WordNet id to the number of images
      living in the leaves spanned by that node.
    get_leaves_fn: A function that returns the set of leaves of a graph defined
      by a given set of nodes, e.g. get_leaves in imagenet_specification.py
    get_spanning_leaves_fn: A function that returns a dict mapping each node of
      a given set of nodes to the set of leaf Synsets spanned by that node, e.g.
      get_spanning_leaves in imagenet_specification.py.
    graph_name: A name for the graph (for the printed logs).
    min_way: The smallest allowable way of an episode.
    max_way: The largest allowable way of an episode.
Compute and display statistics about the graph defined by nodes.
Compute and display statistics about the graph defined by nodes .
def log_graph_stats(nodes,
                    num_images,
                    get_leaves_fn,
                    get_spanning_leaves_fn,
                    graph_name=None,
                    min_way=5,
                    max_way=50):
  """Compute and display statistics about the graph defined by nodes.

  In particular, the statistics that are computed are:
  the number of nodes, the numbers of roots and leaves, the min/max/mean number
  of images living in the leaves, the min/max/mean number of children of
  internal nodes, the min/max/mean depth of leaves.

  Args:
    nodes: A set of Synsets representing a graph.
    num_images: A dict mapping each node's WordNet id to the number of images
      living in the leaves spanned by that node.
    get_leaves_fn: A function that returns the set of leaves of a graph defined
      by a given set of nodes, e.g. get_leaves in imagenet_specification.py
    get_spanning_leaves_fn: A function that returns a dict mapping each node of
      a given set of nodes to the set of leaf Synsets spanned by that node, e.g.
      get_spanning_leaves in imagenet_specification.py.
    graph_name: A name for the graph (for the printed logs).
    min_way: The smallest allowable way of an episode.
    max_way: The largest allowable way of an episode.
  """
  logging.info(
      'Graph statistics%s:',
      ' of graph {}'.format(graph_name) if graph_name is not None else '')
  logging.info('Number of nodes: %d', len(nodes))
  if not nodes:
    # Empty set
    return

  # Compute the dict mapping internal nodes to their spanning leaves. Note that
  # this is different for the different splits since even for nodes that may be
  # shared across splits, their connectivity will be different.
  spanning_leaves = get_spanning_leaves_fn(nodes)

  # Compute the number of roots and leaves
  num_roots = 0
  for n in nodes:
    if not n.parents:
      num_roots += 1
      logging.info('Root: %s', n.words)
  logging.info('Number of roots: %d', num_roots)
  leaves = get_leaves_fn(nodes)
  logging.info('Number of leaves: %d', len(leaves))

  # Compute the number of images in the leaves
  num_leaf_images = []
  for n in nodes:
    if n.children:
      continue
    num_leaf_images.append(num_images[n])
  logging.info('Number of leaf images: min %d, max %d, median %f',
               min(num_leaf_images), max(num_leaf_images),
               np.median(num_leaf_images))

  # Compute the average number of children of internal nodes
  num_children = []
  for n in nodes:
    if not n.children:
      continue
    num_children.append(len(n.children))
  logging.info(
      'Number of children of internal nodes: min %d, max %d, mean %f median %f',
      min(num_children), max(num_children), np.mean(num_children),
      np.median(num_children))

  # Compute the average number of leaves spanned by internal nodes.
  num_span_leaves = []
  for n in nodes:
    if not n.children:
      continue
    num_span_leaves.append(len(spanning_leaves[n]))
  logging.info(
      'Number of spanning leaves of internal nodes: min %d, max %d, mean %f '
      'median %f', min(num_span_leaves), max(num_span_leaves),
      np.mean(num_span_leaves), np.median(num_span_leaves))

  # Log the effects of restricting the allowable 'way' of episodes.
  all_reachable_leaves = set()  # leaves reachable under the restriction.
  possible_ways_in_range = []
  for v in spanning_leaves.values():
    way = len(v)
    if way >= min_way and way <= max_way:
      possible_ways_in_range.append(way)
      all_reachable_leaves |= set(v)
  logging.info(
      'When restricting the allowable way to be between %d and %d, '
      'the achievable ways are: %s', min_way, max_way, possible_ways_in_range)
  logging.info(
      'So there is a total of %d available internal nodes and a '
      'total of %d different ways.', len(possible_ways_in_range),
      len(set(possible_ways_in_range)))
  # Are all leaves reachable when using the restricted way?
  logging.info(' %d / %d are reachable.', len(all_reachable_leaves),
               len(leaves))
def log_graph_stats ( nodes , num_images , get_leaves_fn , get_spanning_leaves_fn , graph_name = None , min_way = 5 , max_way = 50 ) : logging . info ( 'Graph statistics%s:' , ' of graph {}' . format ( graph_name ) if graph_name is not None else '' ) logging . info ( 'Number of nodes: %d' , len ( nodes ) ) if not nodes : # Empty set return # Compute the dict mapping internal nodes to their spanning leaves. Note that # this is different for the different splits since even for nodes that may be # shared across splits, their connectivity will be different. spanning_leaves = get_spanning_leaves_fn ( nodes ) # Compute the number of roots and leaves num_roots = 0 for n in nodes : if not n . parents : num_roots += 1 logging . info ( 'Root: %s' , n . words ) logging . info ( 'Number of roots: %d' , num_roots ) leaves = get_leaves_fn ( nodes ) logging . info ( 'Number of leaves: %d' , len ( leaves ) ) # Compute the number of images in the leaves num_leaf_images = [ ] for n in nodes : if n . children : continue num_leaf_images . append ( num_images [ n ] ) logging . info ( 'Number of leaf images: min %d, max %d, median %f' , min ( num_leaf_images ) , max ( num_leaf_images ) , np . median ( num_leaf_images ) ) # Compute the average number of children of internal nodes num_children = [ ] for n in nodes : if not n . children : continue num_children . append ( len ( n . children ) ) logging . info ( 'Number of children of internal nodes: min %d, max %d, mean %f median %f' , min ( num_children ) , max ( num_children ) , np . mean ( num_children ) , np . median ( num_children ) ) # Compute the average number of leaves spanned by internal nodes. num_span_leaves = [ ] for n in nodes : if not n . children : continue num_span_leaves . append ( len ( spanning_leaves [ n ] ) ) logging . info ( 'Number of spanning leaves of internal nodes: min %d, max %d, mean %f ' 'median %f' , min ( num_span_leaves ) , max ( num_span_leaves ) , np . mean ( num_span_leaves ) , np . median ( num_span_leaves ) ) # Log the effects of restricting the allowable 'way' of episodes. all_reachable_leaves = set ( ) # leaves reachable under the restriction. possible_ways_in_range = [ ] for v in spanning_leaves . values ( ) : way = len ( v ) if way >= min_way and way <= max_way : possible_ways_in_range . append ( way ) all_reachable_leaves |= set ( v ) logging . info ( 'When restricting the allowable way to be between %d and %d, ' 'the achievable ways are: %s' , min_way , max_way , possible_ways_in_range ) logging . info ( 'So there is a total of %d available internal nodes and a ' 'total of %d different ways.' , len ( possible_ways_in_range ) , len ( set ( possible_ways_in_range ) ) ) # Are all leaves reachable when using the restricted way? logging . info ( ' %d / %d are reachable.' , len ( all_reachable_leaves ) , len ( leaves ) )