Ejemplo n.º 1
0
    def infer_shape_conv_pool_shape(self, op):
        input_shape = self._output_shape_cache[op.input[0]]
        output_shape = np.zeros_like(input_shape)
        if op.type == MaceOp.Pooling:
            filter_shape = list(
                ConverterUtil.get_arg(op, MaceKeyword.mace_kernel_str).ints)
            if ConverterUtil.data_format(op) == DataFormat.NCHW:
                filter_shape = [input_shape[1], input_shape[1]] + filter_shape
                if ConverterUtil.get_arg(op,
                                         MaceKeyword.mace_global_pooling_str) \
                        is not None:
                    filter_shape[2] = input_shape[2]
                    filter_shape[3] = input_shape[3]
            else:  # NHWC
                filter_shape = filter_shape + [input_shape[1], input_shape[1]]
                if ConverterUtil.get_arg(op,
                                         MaceKeyword.mace_global_pooling_str) \
                        is not None:
                    filter_shape[0] = input_shape[1]
                    filter_shape[1] = input_shape[2]
        else:
            filter_shape = self._output_shape_cache[op.input[1]]

        paddings = ConverterUtil.get_arg(
            op, MaceKeyword.mace_padding_values_str).ints  # noqa
        strides = ConverterUtil.get_arg(op, MaceKeyword.mace_strides_str).ints
        dilations_arg = ConverterUtil.get_arg(op,
                                              MaceKeyword.mace_dilations_str)
        if dilations_arg is not None:
            dilations = dilations_arg.ints
        else:
            dilations = [1, 1]
        if op.type == MaceOp.Pooling:
            round_func = math.ceil
        else:
            round_func = math.floor

        output_shape[0] = input_shape[0]
        if ConverterUtil.data_format(op) == DataFormat.NCHW \
                and ConverterUtil.filter_format(self._net) == DataFormat.OIHW:  # noqa
            # filter format: OIHW
            if op.type == MaceOp.DepthwiseConv2d.name:
                output_shape[1] = filter_shape[0] * filter_shape[1]
            else:
                output_shape[1] = filter_shape[0]
            output_shape[2] = int(
                round_func((input_shape[2] + paddings[0] - filter_shape[2] -
                            (filter_shape[2] - 1) *
                            (dilations[0] - 1)) / float(strides[0]))) + 1
            output_shape[3] = int(
                round_func((input_shape[3] + paddings[1] - filter_shape[3] -
                            (filter_shape[3] - 1) *
                            (dilations[1] - 1)) / float(strides[1]))) + 1
        else:
            mace_check(
                False, "Mace can only infer shape for"
                " NCHW input and OIHW filter")

        self.add_output_shape(op, [output_shape])
Ejemplo n.º 2
0
 def infer_shape_fully_connected(self, op):
     input_shape = self._output_shape_cache[op.input[0]]
     weight_shape = self._output_shape_cache[op.input[1]]
     if ConverterUtil.data_format(op) == DataFormat.NCHW:
         output_shape = [input_shape[0], weight_shape[0], 1, 1]
     else:
         mace_check(
             False,
             "format %s is not supported" % ConverterUtil.data_format(op))
     self.add_output_shape(op, [output_shape])
Ejemplo n.º 3
0
 def infer_shape_resize_bilinear(self, op):
     input_shape = self._output_shape_cache[op.input[0]]
     size = ConverterUtil.get_arg(op, MaceKeyword.mace_resize_size_str).ints
     if ConverterUtil.data_format(op) == DataFormat.NCHW:
         output_shape = [input_shape[0], input_shape[1], size[0], size[1]]
     elif ConverterUtil.data_format(op) == DataFormat.NHWC:
         output_shape = [input_shape[0], size[0], size[1], input_shape[3]]
     else:
         output_shape = []
         mace_check(
             False,
             "format %s is not supported" % ConverterUtil.data_format(op))
     self.add_output_shape(op, [output_shape])
Ejemplo n.º 4
0
 def infer_shape_fully_connected(self, op):
     input_shape = self._output_shape_cache[op.input[0]]
     weight_shape = self._output_shape_cache[op.input[1]]
     data_format = ConverterUtil.data_format(op)
     mace_check(data_format == DataFormat.NCHW,
                "format {} is not supported".format(data_format))
     output_shape = [input_shape[0], weight_shape[0], 1, 1]
     self.add_output_shape(op, [output_shape])
Ejemplo n.º 5
0
 def common_check(self):
     for op in self._model.op:
         mace_check(
             len(op.input) >= 1,
             op.name + ': apu does not support op with 0 input')
         mace_check(
             len(op.output) == 1,
             op.name + ': apu only support single output op')
         mace_check(
             len(op.output) == len(op.output_shape),
             op.name + ': length of output and output_shape not'
             ' match')
         mace_check(
             len(op.output_shape[0].dims) <= 4,
             op.name + ': apu only support 1D~4D tensor')
         if op.output_type[0] == mace_pb2.DT_UINT8 \
                 or op.output_type[0] == mace_pb2.DT_INT16:
             mace_check(
                 len(op.output) == len(op.quantize_info),
                 op.name + ': length of output and quantize_info not'
                 ' match')
         data_format = ConverterUtil.data_format(op)
         if data_format is not None and len(op.output_shape[0].dims) == 4:
             mace_check((data_format == DataFormat.NHWC)
                        or (data_format == DataFormat.AUTO),
                        op.name + ': apu only support 4D tensor with NHWC'
                        ' or AUTO format but find ' + str(data_format))
         act_mode_arg = ConverterUtil.get_arg(
             op, MaceKeyword.mace_activation_type_str)
         if act_mode_arg is not None:
             mace_check(
                 act_mode_arg.s == b'PRELU' or act_mode_arg.s == b'RELU'
                 or act_mode_arg.s == b'RELUX' or act_mode_arg.s == b'TANH'
                 or act_mode_arg.s == b'SIGMOID',
                 op.name + ': apu only support activation RELU,'
                 ' RELUX, TANH and SIGMOID')
     for tensor in self._model.tensors:
         mace_check(
             len(tensor.dims) <= 4,
             tensor.name + ': apu only support 1D~4D tensor')
     for input_info in self._model.input_info:
         mace_check(
             len(input_info.dims) <= 4,
             input_info.name + ': apu only support 1D~4D tensor')
         mace_check(
             input_info.data_type == mace_pb2.DT_FLOAT
             or input_info.data_type == mace_pb2.DT_INT16
             or input_info.data_type == mace_pb2.DT_UINT8,
             input_info.name + ': apu only support '
             'float/uint8/int16 input')
         if len(input_info.dims) == 4:
             mace_check(
                 input_info.data_format == DataFormat.NHWC.value,
                 input_info.name + ': apu only support 4D tensor'
                 ' with NHWC format')
Ejemplo n.º 6
0
 def infer_shape_nearest_neighbor(self, op):
     input_shape = self._output_shape_cache[op.input[0]]
     height_scale = \
         ConverterUtil.get_arg(op, MaceKeyword.mace_height_scale_str).f
     width_scale = \
         ConverterUtil.get_arg(op, MaceKeyword.mace_width_scale_str).f
     if ConverterUtil.data_format(op) == DataFormat.NCHW:
         output_shape = [
             input_shape[0], input_shape[1],
             int(input_shape[2] * height_scale),
             int(input_shape[3] * width_scale)
         ]
     elif ConverterUtil.data_format(op) == DataFormat.NHWC:
         output_shape = [
             input_shape[0],
             int(input_shape[2] * height_scale),
             int(input_shape[3] * width_scale), input_shape[3]
         ]
     else:
         output_shape = []
         mace_check(
             False,
             "format %s is not supported" % ConverterUtil.data_format(op))
     self.add_output_shape(op, [output_shape])
Ejemplo n.º 7
0
    def infer_shape_deconv(self, op):
        input_shape = self._output_shape_cache[op.input[0]]
        output_shape = np.zeros_like(input_shape)
        filter_shape = self._output_shape_cache[op.input[1]]

        paddings = ConverterUtil.get_arg(
            op, MaceKeyword.mace_padding_values_str).ints  # noqa
        strides = ConverterUtil.get_arg(op, MaceKeyword.mace_strides_str).ints
        dilations_arg = ConverterUtil.get_arg(op,
                                              MaceKeyword.mace_dilations_str)
        if dilations_arg is not None:
            dilations = dilations_arg.ints
        else:
            dilations = [1, 1]
        round_func = math.floor

        group_arg = ConverterUtil.get_arg(op, MaceKeyword.mace_group_str)
        output_shape[0] = input_shape[0]
        if ConverterUtil.data_format(op) == DataFormat.NCHW \
                and ConverterUtil.filter_format(self._net) == DataFormat.OIHW:  # noqa
            # filter format: IOHW
            output_shape[1] = filter_shape[1]
            if group_arg is not None and group_arg.i > 1:
                output_shape[1] = group_arg.i * filter_shape[1]
            output_shape[2] = int(
                round_func((input_shape[2] - 1) * strides[0] +
                           (filter_shape[2] - 1) * (dilations[0] - 1) +
                           filter_shape[2] - paddings[0]))
            output_shape[3] = int(
                round_func((input_shape[3] - 1) * strides[1] +
                           (filter_shape[3] - 1) * (dilations[1] - 1) +
                           filter_shape[3] - paddings[1]))
        else:
            mace_check(
                False, "Mace can only infer shape for"
                " NCHW input and OIHW filter")
        print("deconv layer %s (%s) input:%s filter:%s output:%s" %
              (op.name, op.type, input_shape, filter_shape, output_shape))

        self.add_output_shape(op, [output_shape])
Ejemplo n.º 8
0
    def infer_shape_conv2d_pool(self, op):
        input_shape = self._output_shape_cache[op.input[0]]
        output_shape = np.zeros_like(input_shape)
        if not op.type == MaceOp.Pooling:
            filter_shape = self._output_shape_cache[op.input[1]]
        paddings = ConverterUtil.get_arg(
            op, MaceKeyword.mace_padding_values_str).ints  # noqa
        strides = ConverterUtil.get_arg(op, MaceKeyword.mace_strides_str).ints
        dilations_arg = ConverterUtil.get_arg(op,
                                              MaceKeyword.mace_dilations_str)
        if dilations_arg is not None:
            dilations = dilations_arg.ints
        else:
            dilations = [1, 1]  # MACE pooling has no dilation
        if op.type == MaceOp.Pooling.name:
            kernels = ConverterUtil.get_arg(op,
                                            MaceKeyword.mace_kernel_str).ints
            if ConverterUtil.get_arg(
                    op, MaceKeyword.mace_global_pooling_str) is not None:
                kernels[0] = input_shape[2]
                kernels[1] = input_shape[3]

        round_func = math.floor
        round_mode_arg = ConverterUtil.get_arg(op,
                                               MaceKeyword.mace_round_mode_str)
        if round_mode_arg is not None and \
                round_mode_arg.i == RoundMode.CEIL.value:
            round_func = math.ceil

        # N_o = N_i
        output_shape[0] = input_shape[0]
        mace_check(
            ConverterUtil.data_format(op) == DataFormat.NCHW and
            ConverterUtil.filter_format(self._mace_net_def) == DataFormat.OIHW,
            "MACE can only infer shape for NCHW input and OIHW filter")  # noqa
        # get C_{out}
        if op.type == MaceOp.DepthwiseConv2d.name:
            # 1CHW for depthwise, here C=C_{out}
            output_shape[1] = filter_shape[1]
        elif op.type == MaceOp.Conv2D.name:
            # filter format: OIHW
            output_shape[1] = filter_shape[0]
        else:
            output_shape[1] = input_shape[1]
        # H_{out}
        p, d, s = paddings[0], dilations[0], strides[0]
        k = kernels[0] if op.type == MaceOp.Pooling.name \
            else filter_shape[2]
        # https://pytorch.org/docs/stable/generated/torch.nn.Conv2d.html
        output_shape[2] = int(
            round_func(
                float(input_shape[2] + p - d * (k - 1) - 1) / float(s) + 1))
        # W_{out}
        p, d, s = paddings[1], dilations[1], strides[1]
        k = kernels[1] if op.type == MaceOp.Pooling.name \
            else filter_shape[3]
        output_shape[3] = int(
            round_func(
                float(input_shape[3] + p - d * (k - 1) - 1) / float(s) + 1))

        self.add_output_shape(op, [output_shape])