Ejemplo n.º 1
0
    def convert_quantize_layer(self, keras_op):
        op = self._mace_net_def.op.add()
        op.name = keras_op.name
        op.type = MaceOp.Identity.name
        op.input.append(get_input(keras_op).name)
        op.output.append(get_output(keras_op).name)
        output_shape = op.output_shape.add()
        output_shape.dims.extend(keras_shape2list(get_output(keras_op).shape))

        ConverterUtil.add_data_type_arg(op, mace_pb2.DT_FLOAT)
        ConverterUtil.add_data_format_arg(op, DataFormat.NHWC)

        output_min = keras_op.weights[0].numpy()
        output_max = keras_op.weights[1].numpy()

        self.add_quantize_info(op, output_min, output_max)

        return op
Ejemplo n.º 2
0
def convert(model_file, output_dir, layers):
    mace_check(os.path.isdir(output_dir),
               "Output directory '" + output_dir + "' does not exist!")
    multi_net_def = init_multi_net_def(model_file)
    multi_net_info = MultiNetDefInfo(multi_net_def, layers)

    output_configs = {ModelKeys.subgraphs: []}
    while multi_net_info.index_valid():
        # omit BatchToSpaceND and op before that due to changed graph
        cur_op = multi_net_info.get_current_op()
        next_op = multi_net_info.get_next_op()
        if cur_op.type == MaceOp.BatchToSpaceND.name or \
                cur_op.type == HexagonOp.BatchToSpaceND_8.name or \
                (cur_op.type == MaceOp.Quantize.name or
                 cur_op.type == HexagonOp.QuantizeINPUT_f_to_8.name or
                 cur_op.type == HexagonOp.INPUT.name) or \
                (cur_op.type == HexagonOp.DequantizeOUTPUT_8tof.name or
                 cur_op.type == HexagonOp.OUTPUT.name) or \
                (next_op is not None and
                 (next_op.type == MaceOp.BatchToSpaceND.name or
                  next_op.type == HexagonOp.BatchToSpaceND_8.name)) or \
                cur_op.name.startswith(MaceKeyword.mace_output_node_name):
            multi_net_info.StartIndexIncrement()
            continue
        multi_net = copy.deepcopy(multi_net_def)
        net_defs = multi_net.net_def

        # remove unused net_def
        net = None
        cur_net_idx = multi_net_info.get_current_net_idx()
        for net_def in net_defs[:]:
            if net_def.infer_order == cur_net_idx:
                net = net_def
            elif net_def.infer_order > cur_net_idx:
                net_defs.remove(net_def)
        del multi_net.output_tensor[:]
        data_format = net.output_info[0].data_format

        # remove unsued op
        cur_op_idx = multi_net_info.get_current_op_idx()
        is_hexagon = multi_net_info.is_hexagon(cur_net_idx)
        if is_hexagon:
            # reuse dequantize op and it's min/max tensor's node_id
            del net.op[(cur_op_idx + 1):-1]
        else:
            del net.op[(cur_op_idx + 1):]
        del net.output_info[:]
        op = net.op[cur_op_idx]
        multi_net_info.StartIndexIncrement()

        output_tensors = []
        output_shapes = []
        op_name = op.name
        if str(op.name).startswith(MaceKeyword.mace_output_node_name):
            continue
        is_quantize = multi_net_info.is_quantize(cur_net_idx)
        if is_quantize:
            op.name = MaceKeyword.mace_output_node_name + '_' + op.name
        if is_hexagon:
            if len(op.output) != 1:
                print("Skip %s(%s)" % (op.name, op.type))
                continue
        for i in range(len(op.output)):
            output_tensors.append(str(op.output[i]))
            output_shapes.append(",".join(
                [str(dim) for dim in op.output_shape[i].dims]))
            # modify output info
            multi_net.output_tensor.append(op.output[i])
            output_info = net.output_info.add()
            output_info.name = op.output[i]
            output_info.data_format = data_format
            output_info.dims.extend(op.output_shape[i].dims)
            output_info.data_type = mace_pb2.DT_FLOAT
            if is_quantize:
                output_info.scale = op.quantize_info[0].scale
                output_info.zero_point = op.quantize_info[0].zero_point
            # modify output op
            if is_quantize:
                output_name = op.output[i]
                new_output_name = \
                    MaceKeyword.mace_output_node_name + '_' + op.output[i]
                op.output[i] = new_output_name
                if not is_hexagon:
                    dequantize_op = net.op.add()
                    dequantize_op.name = normalize_op_name(output_name)
                    dequantize_op.type = MaceOp.Dequantize.name
                    dequantize_op.input.append(new_output_name)
                    dequantize_op.output.append(output_name)
                    output_shape = dequantize_op.output_shape.add()
                    output_shape.dims.extend(op.output_shape[i].dims)
                    dequantize_op.output_type.append(mace_pb2.DT_FLOAT)
                    ConverterUtil.add_data_type_arg(dequantize_op,
                                                    mace_pb2.DT_UINT8)
                else:
                    dequantize_op = net.op[-1]
                    dequantize_op.name = normalize_op_name(output_name)
                    del dequantize_op.input[:]
                    del dequantize_op.output[:]
                    dequantize_op.input.append(new_output_name)
                    dequantize_op.node_input[0].node_id = op.node_id
                    dequantize_op.output.append(output_name)
                    if dequantize_op.type == \
                            HexagonOp.DequantizeOUTPUT_8tof.name:
                        input_min = new_output_name[:-1] + '1'
                        input_max = new_output_name[:-1] + '2'
                        dequantize_op.input.extend([input_min, input_max])
                        dequantize_op.node_input[1].node_id = op.node_id
                        dequantize_op.node_input[2].node_id = op.node_id
                        del dequantize_op.node_input[3:]
                    else:
                        del dequantize_op.node_input[1:]

        model_path = save_model_to_proto(multi_net, normalize_op_name(op_name),
                                         output_dir)
        output_config = {
            ModelKeys.model_file_path: str(model_path),
            ModelKeys.output_tensors: output_tensors,
            ModelKeys.output_shapes: output_shapes,
            "output_data_formats": [DataFormat.NHWC.name] * len(output_shapes)
        }
        output_configs[ModelKeys.subgraphs].append(output_config)

    output_configs_path = output_dir + "outputs.yml"
    with open(output_configs_path, "w") as f:
        yaml.dump(output_configs, f, default_flow_style=False)
Ejemplo n.º 3
0
def convert(model_file, output_dir, layers):
    mace_check(os.path.isfile(model_file),
               "Input graph file '" + model_file + "' does not exist!")
    mace_check(os.path.isdir(output_dir),
               "Output directory '" + output_dir + "' does not exist!")
    net_def = mace_pb2.NetDef()
    with open(model_file, "rb") as f:
        net_def.ParseFromString(f.read())

    is_quantize = ConverterUtil.get_arg(net_def,
                                        MaceKeyword.mace_quantize_flag_arg_str)
    is_quantize = False if is_quantize is None else is_quantize.i == 1
    is_hexagon = False
    index = 0
    end_index = len(net_def.op)
    if is_quantize:
        while index < end_index:
            # omit op quantize
            if net_def.op[index].type == MaceOp.Quantize.name or \
                    net_def.op[index].type == \
                    HexagonOp.QuantizeINPUT_f_to_8.name or \
                    net_def.op[index].type == HexagonOp.INPUT.name:
                index += 1
            # omit op dequantize
            elif net_def.op[end_index - 1].type == MaceOp.Dequantize.name or \
                    net_def.op[end_index - 1].type == \
                    HexagonOp.DequantizeOUTPUT_8tof.name or \
                    net_def.op[end_index - 1].type == HexagonOp.OUTPUT.name:

                end_index -= 1
            else:
                break
        mace_check(
            0 < index < end_index < len(net_def.op),
            "Wrong number of op quantize(%d) or dequantize(%d)." %
            (index, len(net_def.op) - end_index))
        if net_def.op[-1].type == HexagonOp.DequantizeOUTPUT_8tof.name or \
                net_def.op[-1].type == HexagonOp.OUTPUT.name:
            is_hexagon = True

    index, end_index = handle_index(index, end_index, layers)

    data_format = net_def.output_info[0].data_format
    output_configs = {"subgraphs": []}
    while index < end_index:
        # omit BatchToSpaceND and op before that due to changed graph
        if net_def.op[index].type == MaceOp.BatchToSpaceND.name or \
                net_def.op[index].type == HexagonOp.BatchToSpaceND_8.name or \
                (index + 1 < end_index and
                 (net_def.op[index + 1].type == MaceOp.BatchToSpaceND.name or
                  net_def.op[index + 1].type == HexagonOp.BatchToSpaceND_8.name)):  # noqa
            index += 1
            continue
        net = copy.deepcopy(net_def)
        if is_hexagon:
            # reuse dequantize op and it's min/max tensor's node_id
            del net.op[index + 1:-1]
        else:
            del net.op[index + 1:]
        del net.output_info[:]
        op = net.op[index]
        index += 1

        output_tensors = []
        output_shapes = []
        op_name = op.name
        if str(op.name).startswith(MaceKeyword.mace_output_node_name):
            continue
        if is_quantize:
            op.name = MaceKeyword.mace_output_node_name + '_' + op.name
        if is_hexagon:
            if len(op.output) != 1:
                print("Skip %s(%s)" % (op.name, op.type))
                continue
        for i in range(len(op.output)):
            output_tensors.append(str(op.output[i]))
            output_shapes.append(",".join(
                [str(dim) for dim in op.output_shape[i].dims]))
            # modify output info
            output_info = net.output_info.add()
            output_info.name = op.output[i]
            output_info.data_format = data_format
            output_info.dims.extend(op.output_shape[i].dims)
            output_info.data_type = mace_pb2.DT_FLOAT
            if is_quantize:
                output_info.scale = op.quantize_info[0].scale
                output_info.zero_point = op.quantize_info[0].zero_point
            # modify output op
            if is_quantize:
                output_name = op.output[i]
                new_output_name = \
                    MaceKeyword.mace_output_node_name + '_' + op.output[i]
                op.output[i] = new_output_name
                if not is_hexagon:
                    dequantize_op = net.op.add()
                    dequantize_op.name = normalize_op_name(output_name)
                    dequantize_op.type = MaceOp.Dequantize.name
                    dequantize_op.input.append(new_output_name)
                    dequantize_op.output.append(output_name)
                    output_shape = dequantize_op.output_shape.add()
                    output_shape.dims.extend(op.output_shape[i].dims)
                    dequantize_op.output_type.append(mace_pb2.DT_FLOAT)
                    ConverterUtil.add_data_type_arg(dequantize_op,
                                                    mace_pb2.DT_UINT8)
                else:
                    dequantize_op = net.op[-1]
                    dequantize_op.name = normalize_op_name(output_name)
                    del dequantize_op.input[:]
                    del dequantize_op.output[:]
                    dequantize_op.input.append(new_output_name)
                    dequantize_op.node_input[0].node_id = op.node_id
                    dequantize_op.output.append(output_name)
                    if dequantize_op.type == \
                            HexagonOp.DequantizeOUTPUT_8tof.name:
                        input_min = new_output_name[:-1] + '1'
                        input_max = new_output_name[:-1] + '2'
                        dequantize_op.input.extend([input_min, input_max])
                        dequantize_op.node_input[1].node_id = op.node_id
                        dequantize_op.node_input[2].node_id = op.node_id
                        del dequantize_op.node_input[3:]
                    else:
                        del dequantize_op.node_input[1:]

        model_path = save_model_to_proto(net, normalize_op_name(op_name),
                                         output_dir)
        output_config = {
            "model_file_path": str(model_path),
            "output_tensors": output_tensors,
            "output_shapes": output_shapes,
            "output_data_formats": [DataFormat.NHWC.name]
        }
        output_configs["subgraphs"].append(output_config)

    output_configs_path = output_dir + "outputs.yml"
    with open(output_configs_path, "w") as f:
        yaml.dump(output_configs, f, default_flow_style=False)