# Buggy code
def _remove_internal_identity_nodes(nnssa):
    """
    remove identity nodes that are not connected to the model outputs
    """
    delete_count = 0
    for fn_key in list(nnssa.functions.keys()):
        f = nnssa.functions[fn_key]
        keys = list(f.graph.keys())
        for k in keys:
            if k not in f.graph:
                continue
            node = f.graph[k]
            if len(node.inputs) != 1 or len(node.outputs) != 1:
                continue
            inp_node = f.graph[node.inputs[0]]
            if node.op == "Identity" and inp_node.op != "get_tuple":
                delete_count += 1
                parent_name = f.graph[k].inputs[0]
                disconnect_edge(f.graph, parent_name, k)
                for control_input in f.graph[k].control_inputs:
                    replace_control_dest(f.graph, control_input, k, parent_name)

                replace_node(f.graph, k, parent_name)  # join parent to children
                delete_node(f.graph, k)

    return delete_count


# Traceback (ValueError)
Converting pb model to .mlmodel......
0 assert nodes deleted
872 nodes deleted
36 nodes deleted
0 nodes deleted
[Op Fusion] fuse_bias_add() deleted 24 nodes.
77 identity nodes deleted
Traceback (most recent call last):
File "tf2coreml.py", line 198, in <module>
convertModel(model=_TRAIN_MODEL, ml_model=_ML_MODEL, pb_model=_PB_MODEL)
File "tf2coreml.py", line 174, in convertModel
minimum_ios_deployment_target='12'
File "/home/ubuntu/anaconda3/envs/tensorflow_p36/lib/python3.6/site-packages/coremltools/converters/tensorflow/_tf_converter.py", line 193, in convert
optional_inputs=optional_inputs)
File "/home/ubuntu/anaconda3/envs/tensorflow_p36/lib/python3.6/site-packages/coremltools/converters/nnssa/coreml/ssa_converter.py", line 130, in ssa_convert
p(ssa)
File "/home/ubuntu/anaconda3/envs/tensorflow_p36/lib/python3.6/site-packages/coremltools/converters/nnssa/coreml/graph_pass/op_removals.py", line 20, in
remove_no_ops_and_shift_control_dependencies
f.graph[each_control_input].control_outputs.remove(node.name)
ValueError: list.remove(x): x not in list

# Fixed code
def _remove_internal_identity_nodes(nnssa):
    """
    remove identity nodes that are not connected to the model outputs
    """
    delete_count = 0
    for fn_key in list(nnssa.functions.keys()):
        f = nnssa.functions[fn_key]
        for name in list(f.graph.keys()):
            if name not in f.graph:
                continue
            node = f.graph[name]

            # Check if the node is in graph outputs
            if len(node.inputs) != 1:
                continue
            if len(node.outputs) == 0 and len(node.control_outputs) == 0:
                continue

            # Remove identity node
            inp_node = f.graph[node.inputs[0]]
            if node.op == "Identity" and inp_node.op != "get_tuple":
                delete_count += 1
                parent_name = f.graph[name].inputs[0]
                disconnect_edge(f.graph, parent_name, name)
                for control_input in f.graph[name].control_inputs:
                    replace_control_dest(f.graph, control_input, name, parent_name)

                replace_node(f.graph, name, parent_name)  # join parent to children
                delete_node(f.graph, name)

    return delete_count