def suggest_save_args()

in lucid/modelzoo/vision_base.py [0:0]


  def suggest_save_args(graph_def=None):
    if graph_def is None:
      graph_def = tf.get_default_graph().as_graph_def()
    gdhelper = model_util.GraphDefHelper(graph_def)
    inferred_info = dict.fromkeys(("input_name", "image_shape", "output_names", "image_value_range"))
    node_shape = lambda n: [dim.size for dim in n.attr['shape'].shape.dim]
    potential_input_nodes = gdhelper.by_op["Placeholder"]
    output_nodes = [node.name for node in gdhelper.by_op["Softmax"]]

    if len(potential_input_nodes) == 1:
      input_node = potential_input_nodes[0]
      input_dtype = tf.dtypes.as_dtype(input_node.attr['dtype'].type)
      if input_dtype.is_floating:
        input_name = input_node.name
        print("Inferred: input_name = {} (because it was the only Placeholder in the graph_def)".format(input_name))
        inferred_info["input_name"] = input_name
      else:
        print("Warning: found a single Placeholder, but its dtype is {}. Lucid's parameterizations can only replace float dtypes. We're now scanning to see if you maybe divide this placeholder by 255 to get a float later in the graph...".format(str(input_node.attr['dtype']).strip()))
        neighborhood = gdhelper.neighborhood(input_node, degree=5)
        divs = [n for n in neighborhood if n.op == "RealDiv"]
        consts = [n for n in neighborhood if n.op == "Const"]
        magic_number_present = any(255 in c.attr['value'].tensor.int_val for c in consts)
        if divs and magic_number_present:
          if len(divs) == 1:
            input_name = divs[0].name
            print("Guessed: input_name = {} (because it's the only division by 255 near the only placeholder)".format(input_name))
            inferred_info["input_name"] = input_name
            image_value_range = (0,1)
            print("Guessed: image_value_range = {} (because you're dividing by 255 near the only placeholder)".format(image_value_range))
            inferred_info["image_value_range"] = (0,1)
          else:
            warnings.warn("Could not infer input_name because there were multiple division ops near your the only placeholder. Candidates include: {}".format([n.name for n in divs]))
    else:
      warnings.warn("Could not infer input_name because there were multiple or no Placeholders.")

    if inferred_info["input_name"] is not None:
      input_node = gdhelper.by_name[inferred_info["input_name"]]
      shape = node_shape(input_node)
      if len(shape) in (3,4):
        if len(shape) == 4:
          shape = shape[1:]
        if -1 not in shape:
          print("Inferred: image_shape = {}".format(shape))
          inferred_info["image_shape"] = shape
      if inferred_info["image_shape"] is None:
        warnings.warn("Could not infer image_shape.")

    if output_nodes:
      print("Inferred: output_names = {}  (because those are all the Softmax ops)".format(output_nodes))
      inferred_info["output_names"] = output_nodes
    else:
      warnings.warn("Could not infer output_names.")

    report = []
    report.append("# Please sanity check all inferred values before using this code.")
    report.append("# Incorrect `image_value_range` is the most common cause of feature visualization bugs! Most methods will fail silently with incorrect visualizations!")
    report.append("Model.save(")

    suggestions = {
        "input_name" : 'input',
        "image_shape" : [224, 224, 3],
        "output_names": ['logits'],
        "image_value_range": "[-1, 1], [0, 1], [0, 255], or [-117, 138]"
    }
    for key, value in inferred_info.items():
      if value is not None:
        report.append("    {}={!r},".format(key, value))
      else:
        report.append("    {}=_,                   # TODO (eg. {!r})".format(key, suggestions[key]))
    report.append("  )")

    print("\n".join(report))
    return inferred_info