Example #1
0
def parse_caffe_net(caffe_net):
    """
    Create and populate a Topology object, based on a given Caffe protobuf network object
    Todo: fix Input assignment
    """
    graph = Topology()

    modifiers = {}

    # Input BLOBs
    for i in range(len(caffe_net.input)):
        if len(caffe_net.input_shape) > 0:
            graph.add_blob("b_"+caffe_net.input[i], caffe_net.input_shape[i].dim, None)
        elif len(caffe_net.input_dim) > 0:
            # graph.add_blob(caffe_net.input[i], caffe_net.input_dim[i], None)
            graph.add_blob("b_"+caffe_net.input[i], caffe_net.input_dim, None)

    if len(caffe_net.layer) < 1:
        exit("Something went wrong - the parser can't find any layers in the network")

    for layer in caffe_net.layer:
        log().debug('evaluating layer: ' + layer.name)
        #print('evaluating layer: ' + layer.name)

        # filter away layers used only in training phase
        phase = 1  # caffe_pb2.Phase.TEST
        if phase is not None:
            included = False
            if len(layer.include) == 0:
                included = True
            if len(layer.include) > 0 and len(layer.exclude) > 0:
                raise ValueError('layer ' + layer.name + ' has both include '
                                                         'and exclude specified.')
            for layer_phase in layer.include:
                included = included or layer_phase.phase == phase
            for layer_phase in layer.exclude:
                included = included and not layer_phase.phase == phase
            if not included:
                continue

        if layer.type == "Input":
            graph.add_blob("b_"+layer.name, layer.input_param.shape[0].dim, producer=None)
            continue
        else:
            new_node = graph.add_op(layer.name, layer.type, layer)

        if (len(layer.bottom) == 1 and
            len(layer.top) == 1 and
            layer.bottom[0] == layer.top[0]):
            # We have an in-place neuron layer.
            if layer.bottom[0] not in modifiers:
                modifiers[layer.bottom[0]] = []
            modifiers[layer.bottom[0]].append(new_node)
            continue

        # Iterate over BLOBs consumed by this layer and create edges to them
        for caffe_bottom_blob in layer.bottom:
            # Because the Caffe Tensors and Layers have the same name, I add a b_ prefix to
            # BLOB names, to make them distinguishable
            blob = graph.find_blob_by_name("b_"+caffe_bottom_blob)
            if blob == None:
                raise ValueError(layer.name + ' - could not find BLOB:' + caffe_bottom_blob)
            edge = graph.add_edge(src=blob, dst=new_node)

        # Add the BLOBs produced by this layer to the topology
        for caffe_top_blob in layer.top:
            if new_node==None: #.type == "Input":
                new_blob = graph.add_blob("b_"+caffe_top_blob, layer.input_param.shape[0].dim, producer=None)#producer=new_node)
            else:
                new_blob = graph.add_blob("b_"+caffe_top_blob, None, producer=new_node)

            # Add producer edges
            edge = graph.add_edge(src=new_node, dst=new_blob)

    ''' Below is some ugly code to handle Caffe's modifier layers (e.g. ReLU, Dropout).
    This code "normailizes" these nodes by "flattening" them.
    '''
    for modified_node in modifiers:
        src = graph.find_op_by_name(modified_node)

        # now inject the modifier
        for modifier in modifiers[modified_node]:
            outgoing_edges = graph.find_outgoing_edges(src)
            assert len(outgoing_edges) == 1
            assert type(outgoing_edges[0].dst)==BLOB
            replicated_blob = copy.deepcopy(outgoing_edges[0].dst)
            replicated_blob.name += '_copy'
            graph.add_blob2(replicated_blob)
            graph.add_edge(src=src, dst=replicated_blob)
            graph.add_edge(src=replicated_blob, dst=modifier)
            graph.add_edge(src=modifier, dst=outgoing_edges[0].dst)
            graph.del_edge(outgoing_edges[0])

    return graph
Example #2
0
def parse_caffe_net(caffe_net):
    """
    Create and populate a Topology object, based on a given Caffe protobuf network object
    Todo: fix Input assignment
    """
    graph = Topology()

    # Input BLOBs
    for i in range(len(caffe_net.input)):
        if len(caffe_net.input_shape) > 0:
            graph.add_blob(caffe_net.input[i], caffe_net.input_shape[i].dim,
                           None)
        elif len(caffe_net.input_dim) > 0:
            # graph.add_blob(caffe_net.input[i], caffe_net.input_dim[i], None)
            graph.add_blob(caffe_net.input[i], caffe_net.input_dim, None)

    if len(caffe_net.layer) < 1:
        exit(
            "Something went wrong - the parser can't find any layers in the network"
        )

    for layer in caffe_net.layer:
        debug('evaluating layer: ' + layer.name)

        # filter away layers used only in training phase
        phase = 1  # caffe_pb2.Phase.TEST
        if phase is not None:
            included = False
            if len(layer.include) == 0:
                included = True
            if len(layer.include) > 0 and len(layer.exclude) > 0:
                raise ValueError('layer ' + layer.name + ' has both include '
                                 'and exclude specified.')
            for layer_phase in layer.include:
                included = included or layer_phase.phase == phase
            for layer_phase in layer.exclude:
                included = included and not layer_phase.phase == phase
            if not included:
                continue

        node_role = 'Producer'
        if (len(layer.bottom) == 1 and len(layer.top) == 1
                and layer.bottom[0] == layer.top[0]):
            # We have an in-place neuron layer.
            node_role = 'Modifier'

        new_node = graph.add_node(layer.name, layer.type, layer, node_role)

        # Iterate over BLOBs consumed by this layer and create edges to them
        for caffe_bottom_blob in layer.bottom:
            blob = graph.find_blob_by_name(caffe_bottom_blob)
            if blob == None:
                raise ValueError(layer.name + ' - could not find BLOB:' +
                                 caffe_bottom_blob)

            edge = graph.add_edge(src=blob.producer, dst=new_node, blob=blob)

        # Add the BLOBs produced by this layer to the topology
        for caffe_top_blob in layer.top:
            if new_node.type == "Input":
                graph.add_blob(caffe_top_blob,
                               layer.input_param.shape[0].dim,
                               producer=new_node)
            else:
                graph.add_blob(caffe_top_blob, None, producer=new_node)

    # Add fake output edges
    output_blobs = graph.find_output_blobs()
    for blob_name in output_blobs:
        blob = graph.find_blob_by_name(blob_name)
        graph.add_edge(src=blob.producer, dst=None, blob=blob)

    return graph