def multi_box_head(inputs, image, base_size, num_classes, aspect_ratios, min_ratio=None, max_ratio=None, min_sizes=None, max_sizes=None, steps=None, step_w=None, step_h=None, offset=0.5, variance=[0.1, 0.1, 0.2, 0.2], flip=True, clip=False, kernel_size=1, pad=0, stride=1, name=None, min_max_aspect_ratios_order=False):
    "\n\t:api_attr: Static Graph\n\n    Base on SSD ((Single Shot MultiBox Detector) algorithm, generate prior boxes,\n    regression location and classification confidence on multiple input feature\n    maps, then output the concatenate results. The details of this algorithm,\n    please refer the section 2.2 of SSD paper `SSD: Single Shot MultiBox Detector\n    <https://arxiv.org/abs/1512.02325>`_ .\n\n    Args:\n       inputs (list(Variable)|tuple(Variable)): The list of input variables,\n           the format of all Variables are 4-D Tensor, layout is NCHW.\n           Data type should be float32 or float64.\n       image (Variable): The input image, layout is NCHW. Data type should be\n           the same as inputs.\n       base_size(int): the base_size is input image size. When len(inputs) > 2\n           and `min_size` and `max_size` are None, the `min_size` and `max_size`\n           are calculated by `baze_size`, 'min_ratio' and `max_ratio`. The\n           formula is as follows:\n\n              ..  code-block:: text\n\n                  min_sizes = []\n                  max_sizes = []\n                  step = int(math.floor(((max_ratio - min_ratio)) / (num_layer - 2)))\n                  for ratio in six.moves.range(min_ratio, max_ratio + 1, step):\n                      min_sizes.append(base_size * ratio / 100.)\n                      max_sizes.append(base_size * (ratio + step) / 100.)\n                      min_sizes = [base_size * .10] + min_sizes\n                      max_sizes = [base_size * .20] + max_sizes\n\n       num_classes(int): The number of classes.\n       aspect_ratios(list(float) | tuple(float)): the aspect ratios of generated\n           prior boxes. The length of input and aspect_ratios must be equal.\n       min_ratio(int): the min ratio of generated prior boxes.\n       max_ratio(int): the max ratio of generated prior boxes.\n       min_sizes(list|tuple|None): If `len(inputs) <=2`,\n            min_sizes must be set up, and the length of min_sizes\n            should equal to the length of inputs. Default: None.\n       max_sizes(list|tuple|None): If `len(inputs) <=2`,\n            max_sizes must be set up, and the length of min_sizes\n            should equal to the length of inputs. Default: None.\n       steps(list|tuple): If step_w and step_h are the same,\n            step_w and step_h can be replaced by steps.\n       step_w(list|tuple): Prior boxes step\n            across width. If step_w[i] == 0.0, the prior boxes step\n            across width of the inputs[i] will be automatically\n            calculated. Default: None.\n       step_h(list|tuple): Prior boxes step across height, If\n            step_h[i] == 0.0, the prior boxes step across height of\n            the inputs[i] will be automatically calculated. Default: None.\n       offset(float): Prior boxes center offset. Default: 0.5\n       variance(list|tuple): the variances to be encoded in prior boxes.\n            Default:[0.1, 0.1, 0.2, 0.2].\n       flip(bool): Whether to flip aspect ratios. Default:False.\n       clip(bool): Whether to clip out-of-boundary boxes. Default: False.\n       kernel_size(int): The kernel size of conv2d. Default: 1.\n       pad(int|list|tuple): The padding of conv2d. Default:0.\n       stride(int|list|tuple): The stride of conv2d. Default:1,\n       name(str): The default value is None.  Normally there is no need\n           for user to set this property.  For more information, please\n           refer to :ref:`api_guide_Name`.\n       min_max_aspect_ratios_order(bool): If set True, the output prior box is\n            in order of [min, max, aspect_ratios], which is consistent with\n            Caffe. Please note, this order affects the weights order of\n            convolution layer followed by and does not affect the final\n            detection results. Default: False.\n\n    Returns:\n        tuple: A tuple with four Variables. (mbox_loc, mbox_conf, boxes, variances)\n\n        mbox_loc (Variable): The predicted boxes' location of the inputs. The\n        layout is [N, num_priors, 4], where N is batch size, ``num_priors``\n        is the number of prior boxes. Data type is the same as input.\n\n        mbox_conf (Variable): The predicted boxes' confidence of the inputs.\n        The layout is [N, num_priors, C], where ``N`` and ``num_priors`` \n        has the same meaning as above. C is the number of Classes.\n        Data type is the same as input.\n\n        boxes (Variable): the output prior boxes. The layout is [num_priors, 4].\n        The meaning of num_priors is the same as above.\n        Data type is the same as input.\n\n        variances (Variable): the expanded variances for prior boxes.\n        The layout is [num_priors, 4]. Data type is the same as input.\n\n    Examples 1: set min_ratio and max_ratio:\n        .. code-block:: python\n\n          import paddle.fluid as fluid\n\n          images = fluid.data(name='data', shape=[None, 3, 300, 300], dtype='float32')\n          conv1 = fluid.data(name='conv1', shape=[None, 512, 19, 19], dtype='float32')\n          conv2 = fluid.data(name='conv2', shape=[None, 1024, 10, 10], dtype='float32')\n          conv3 = fluid.data(name='conv3', shape=[None, 512, 5, 5], dtype='float32')\n          conv4 = fluid.data(name='conv4', shape=[None, 256, 3, 3], dtype='float32')\n          conv5 = fluid.data(name='conv5', shape=[None, 256, 2, 2], dtype='float32')\n          conv6 = fluid.data(name='conv6', shape=[None, 128, 1, 1], dtype='float32')\n\n          mbox_locs, mbox_confs, box, var = fluid.layers.multi_box_head(\n            inputs=[conv1, conv2, conv3, conv4, conv5, conv6],\n            image=images,\n            num_classes=21,\n            min_ratio=20,\n            max_ratio=90,\n            aspect_ratios=[[2.], [2., 3.], [2., 3.], [2., 3.], [2.], [2.]],\n            base_size=300,\n            offset=0.5,\n            flip=True,\n            clip=True)\n\n    Examples 2: set min_sizes and max_sizes:\n        .. code-block:: python\n\n          import paddle.fluid as fluid\n\n          images = fluid.data(name='data', shape=[None, 3, 300, 300], dtype='float32')\n          conv1 = fluid.data(name='conv1', shape=[None, 512, 19, 19], dtype='float32')\n          conv2 = fluid.data(name='conv2', shape=[None, 1024, 10, 10], dtype='float32')\n          conv3 = fluid.data(name='conv3', shape=[None, 512, 5, 5], dtype='float32')\n          conv4 = fluid.data(name='conv4', shape=[None, 256, 3, 3], dtype='float32')\n          conv5 = fluid.data(name='conv5', shape=[None, 256, 2, 2], dtype='float32')\n          conv6 = fluid.data(name='conv6', shape=[None, 128, 1, 1], dtype='float32')\n\n          mbox_locs, mbox_confs, box, var = fluid.layers.multi_box_head(\n            inputs=[conv1, conv2, conv3, conv4, conv5, conv6],\n            image=images,\n            num_classes=21,\n            min_sizes=[60.0, 105.0, 150.0, 195.0, 240.0, 285.0],\n            max_sizes=[[], 150.0, 195.0, 240.0, 285.0, 300.0],\n            aspect_ratios=[[2.], [2., 3.], [2., 3.], [2., 3.], [2.], [2.]],\n            base_size=300,\n            offset=0.5,\n            flip=True,\n            clip=True)\n\n    "

    def _reshape_with_axis_(input, axis=1):
        out = nn.flatten(x=input, axis=axis)
        return out

    def _is_list_or_tuple_(data):
        return (isinstance(data, list) or isinstance(data, tuple))

    def _is_list_or_tuple_and_equal(data, length, err_info):
        if (not (_is_list_or_tuple_(data) and (len(data) == length))):
            raise ValueError(err_info)
    if (not _is_list_or_tuple_(inputs)):
        raise ValueError('inputs should be a list or tuple.')
    num_layer = len(inputs)
    if (num_layer <= 2):
        assert ((min_sizes is not None) and (max_sizes is not None))
        assert ((len(min_sizes) == num_layer) and (len(max_sizes) == num_layer))
    elif ((min_sizes is None) and (max_sizes is None)):
        min_sizes = []
        max_sizes = []
        step = int(math.floor(((max_ratio - min_ratio) / (num_layer - 2))))
        for ratio in six.moves.range(min_ratio, (max_ratio + 1), step):
            min_sizes.append(((base_size * ratio) / 100.0))
            max_sizes.append(((base_size * (ratio + step)) / 100.0))
        min_sizes = ([(base_size * 0.1)] + min_sizes)
        max_sizes = ([(base_size * 0.2)] + max_sizes)
    if aspect_ratios:
        _is_list_or_tuple_and_equal(aspect_ratios, num_layer, 'aspect_ratios should be list or tuple, and the length of inputs and aspect_ratios should be the same.')
    if (step_h is not None):
        _is_list_or_tuple_and_equal(step_h, num_layer, 'step_h should be list or tuple, and the length of inputs and step_h should be the same.')
    if (step_w is not None):
        _is_list_or_tuple_and_equal(step_w, num_layer, 'step_w should be list or tuple, and the length of inputs and step_w should be the same.')
    if (steps is not None):
        _is_list_or_tuple_and_equal(steps, num_layer, 'steps should be list or tuple, and the length of inputs and step_w should be the same.')
        step_w = steps
        step_h = steps
    mbox_locs = []
    mbox_confs = []
    box_results = []
    var_results = []
    for (i, input) in enumerate(inputs):
        min_size = min_sizes[i]
        max_size = max_sizes[i]
        if (not _is_list_or_tuple_(min_size)):
            min_size = [min_size]
        if (not _is_list_or_tuple_(max_size)):
            max_size = [max_size]
        aspect_ratio = []
        if (aspect_ratios is not None):
            aspect_ratio = aspect_ratios[i]
            if (not _is_list_or_tuple_(aspect_ratio)):
                aspect_ratio = [aspect_ratio]
        step = [(step_w[i] if step_w else 0.0), (step_h[i] if step_w else 0.0)]
        (box, var) = prior_box(input, image, min_size, max_size, aspect_ratio, variance, flip, clip, step, offset, None, min_max_aspect_ratios_order)
        box_results.append(box)
        var_results.append(var)
        num_boxes = box.shape[2]
        num_loc_output = (num_boxes * 4)
        mbox_loc = nn.conv2d(input=input, num_filters=num_loc_output, filter_size=kernel_size, padding=pad, stride=stride)
        mbox_loc = nn.transpose(mbox_loc, perm=[0, 2, 3, 1])
        mbox_loc_flatten = nn.flatten(mbox_loc, axis=1)
        mbox_locs.append(mbox_loc_flatten)
        num_conf_output = (num_boxes * num_classes)
        conf_loc = nn.conv2d(input=input, num_filters=num_conf_output, filter_size=kernel_size, padding=pad, stride=stride)
        conf_loc = nn.transpose(conf_loc, perm=[0, 2, 3, 1])
        conf_loc_flatten = nn.flatten(conf_loc, axis=1)
        mbox_confs.append(conf_loc_flatten)
    if (len(box_results) == 1):
        box = box_results[0]
        var = var_results[0]
        mbox_locs_concat = mbox_locs[0]
        mbox_confs_concat = mbox_confs[0]
    else:
        reshaped_boxes = []
        reshaped_vars = []
        for i in range(len(box_results)):
            reshaped_boxes.append(_reshape_with_axis_(box_results[i], axis=3))
            reshaped_vars.append(_reshape_with_axis_(var_results[i], axis=3))
        box = tensor.concat(reshaped_boxes)
        var = tensor.concat(reshaped_vars)
        mbox_locs_concat = tensor.concat(mbox_locs, axis=1)
        mbox_locs_concat = nn.reshape(mbox_locs_concat, shape=[0, (- 1), 4])
        mbox_confs_concat = tensor.concat(mbox_confs, axis=1)
        mbox_confs_concat = nn.reshape(mbox_confs_concat, shape=[0, (- 1), num_classes])
    box.stop_gradient = True
    var.stop_gradient = True
    return (mbox_locs_concat, mbox_confs_concat, box, var)
:api_attr: Static Graph

Base on SSD ((Single Shot MultiBox Detector) algorithm, generate prior boxes,
regression location and classification confidence on multiple input feature
maps, then output the concatenate results. The details of this algorithm,
please refer the section 2.2 of SSD paper `SSD: Single Shot MultiBox Detector
<https://arxiv.org/abs/1512.02325>`_ .

Args:
   inputs (list(Variable)|tuple(Variable)): The list of input variables,
       the format of all Variables are 4-D Tensor, layout is NCHW.
       Data type should be float32 or float64.
   image (Variable): The input image, layout is NCHW. Data type should be
       the same as inputs.
   base_size(int): the base_size is input image size. When len(inputs) > 2
       and `min_size` and `max_size` are None, the `min_size` and `max_size`
       are calculated by `baze_size`, 'min_ratio' and `max_ratio`. The
       formula is as follows:

          ..  code-block:: text

              min_sizes = []
              max_sizes = []
              step = int(math.floor(((max_ratio - min_ratio)) / (num_layer - 2)))
              for ratio in six.moves.range(min_ratio, max_ratio + 1, step):
                  min_sizes.append(base_size * ratio / 100.)
                  max_sizes.append(base_size * (ratio + step) / 100.)
                  min_sizes = [base_size * .10] + min_sizes
                  max_sizes = [base_size * .20] + max_sizes

   num_classes(int): The number of classes.
   aspect_ratios(list(float) | tuple(float)): the aspect ratios of generated
       prior boxes. The length of input and aspect_ratios must be equal.
   min_ratio(int): the min ratio of generated prior boxes.
   max_ratio(int): the max ratio of generated prior boxes.
   min_sizes(list|tuple|None): If `len(inputs) <=2`,
        min_sizes must be set up, and the length of min_sizes
        should equal to the length of inputs. Default: None.
   max_sizes(list|tuple|None): If `len(inputs) <=2`,
        max_sizes must be set up, and the length of min_sizes
        should equal to the length of inputs. Default: None.
   steps(list|tuple): If step_w and step_h are the same,
        step_w and step_h can be replaced by steps.
   step_w(list|tuple): Prior boxes step
        across width. If step_w[i] == 0.0, the prior boxes step
        across width of the inputs[i] will be automatically
        calculated. Default: None.
   step_h(list|tuple): Prior boxes step across height, If
        step_h[i] == 0.0, the prior boxes step across height of
        the inputs[i] will be automatically calculated. Default: None.
   offset(float): Prior boxes center offset. Default: 0.5
   variance(list|tuple): the variances to be encoded in prior boxes.
        Default:[0.1, 0.1, 0.2, 0.2].
   flip(bool): Whether to flip aspect ratios. Default:False.
   clip(bool): Whether to clip out-of-boundary boxes. Default: False.
   kernel_size(int): The kernel size of conv2d. Default: 1.
   pad(int|list|tuple): The padding of conv2d. Default:0.
   stride(int|list|tuple): The stride of conv2d. Default:1,
   name(str): The default value is None.  Normally there is no need
       for user to set this property.  For more information, please
       refer to :ref:`api_guide_Name`.
   min_max_aspect_ratios_order(bool): If set True, the output prior box is
        in order of [min, max, aspect_ratios], which is consistent with
        Caffe. Please note, this order affects the weights order of
        convolution layer followed by and does not affect the final
        detection results. Default: False.

Returns:
    tuple: A tuple with four Variables. (mbox_loc, mbox_conf, boxes, variances)

    mbox_loc (Variable): The predicted boxes' location of the inputs. The
    layout is [N, num_priors, 4], where N is batch size, ``num_priors``
    is the number of prior boxes. Data type is the same as input.

    mbox_conf (Variable): The predicted boxes' confidence of the inputs.
    The layout is [N, num_priors, C], where ``N`` and ``num_priors`` 
    has the same meaning as above. C is the number of Classes.
    Data type is the same as input.

    boxes (Variable): the output prior boxes. The layout is [num_priors, 4].
    The meaning of num_priors is the same as above.
    Data type is the same as input.

    variances (Variable): the expanded variances for prior boxes.
    The layout is [num_priors, 4]. Data type is the same as input.

Examples 1: set min_ratio and max_ratio:
    .. code-block:: python

      import paddle.fluid as fluid

      images = fluid.data(name='data', shape=[None, 3, 300, 300], dtype='float32')
      conv1 = fluid.data(name='conv1', shape=[None, 512, 19, 19], dtype='float32')
      conv2 = fluid.data(name='conv2', shape=[None, 1024, 10, 10], dtype='float32')
      conv3 = fluid.data(name='conv3', shape=[None, 512, 5, 5], dtype='float32')
      conv4 = fluid.data(name='conv4', shape=[None, 256, 3, 3], dtype='float32')
      conv5 = fluid.data(name='conv5', shape=[None, 256, 2, 2], dtype='float32')
      conv6 = fluid.data(name='conv6', shape=[None, 128, 1, 1], dtype='float32')

      mbox_locs, mbox_confs, box, var = fluid.layers.multi_box_head(
        inputs=[conv1, conv2, conv3, conv4, conv5, conv6],
        image=images,
        num_classes=21,
        min_ratio=20,
        max_ratio=90,
        aspect_ratios=[[2.], [2., 3.], [2., 3.], [2., 3.], [2.], [2.]],
        base_size=300,
        offset=0.5,
        flip=True,
        clip=True)

Examples 2: set min_sizes and max_sizes:
    .. code-block:: python

      import paddle.fluid as fluid

      images = fluid.data(name='data', shape=[None, 3, 300, 300], dtype='float32')
      conv1 = fluid.data(name='conv1', shape=[None, 512, 19, 19], dtype='float32')
      conv2 = fluid.data(name='conv2', shape=[None, 1024, 10, 10], dtype='float32')
      conv3 = fluid.data(name='conv3', shape=[None, 512, 5, 5], dtype='float32')
      conv4 = fluid.data(name='conv4', shape=[None, 256, 3, 3], dtype='float32')
      conv5 = fluid.data(name='conv5', shape=[None, 256, 2, 2], dtype='float32')
      conv6 = fluid.data(name='conv6', shape=[None, 128, 1, 1], dtype='float32')

      mbox_locs, mbox_confs, box, var = fluid.layers.multi_box_head(
        inputs=[conv1, conv2, conv3, conv4, conv5, conv6],
        image=images,
        num_classes=21,
        min_sizes=[60.0, 105.0, 150.0, 195.0, 240.0, 285.0],
        max_sizes=[[], 150.0, 195.0, 240.0, 285.0, 300.0],
        aspect_ratios=[[2.], [2., 3.], [2., 3.], [2., 3.], [2.], [2.]],
        base_size=300,
        offset=0.5,
        flip=True,
        clip=True)
def multi_box_head(inputs, image, base_size, num_classes, aspect_ratios, min_ratio=None, max_ratio=None, min_sizes=None, max_sizes=None, steps=None, step_w=None, step_h=None, offset=0.5, variance=[0.1, 0.1, 0.2, 0.2], flip=True, clip=False, kernel_size=1, pad=0, stride=1, name=None, min_max_aspect_ratios_order=False):
    "\n\t:api_attr: Static Graph\n\n    Base on SSD ((Single Shot MultiBox Detector) algorithm, generate prior boxes,\n    regression location and classification confidence on multiple input feature\n    maps, then output the concatenate results. The details of this algorithm,\n    please refer the section 2.2 of SSD paper `SSD: Single Shot MultiBox Detector\n    <https://arxiv.org/abs/1512.02325>`_ .\n\n    Args:\n       inputs (list(Variable)|tuple(Variable)): The list of input variables,\n           the format of all Variables are 4-D Tensor, layout is NCHW.\n           Data type should be float32 or float64.\n       image (Variable): The input image, layout is NCHW. Data type should be\n           the same as inputs.\n       base_size(int): the base_size is input image size. When len(inputs) > 2\n           and `min_size` and `max_size` are None, the `min_size` and `max_size`\n           are calculated by `baze_size`, 'min_ratio' and `max_ratio`. The\n           formula is as follows:\n\n              ..  code-block:: text\n\n                  min_sizes = []\n                  max_sizes = []\n                  step = int(math.floor(((max_ratio - min_ratio)) / (num_layer - 2)))\n                  for ratio in six.moves.range(min_ratio, max_ratio + 1, step):\n                      min_sizes.append(base_size * ratio / 100.)\n                      max_sizes.append(base_size * (ratio + step) / 100.)\n                      min_sizes = [base_size * .10] + min_sizes\n                      max_sizes = [base_size * .20] + max_sizes\n\n       num_classes(int): The number of classes.\n       aspect_ratios(list(float) | tuple(float)): the aspect ratios of generated\n           prior boxes. The length of input and aspect_ratios must be equal.\n       min_ratio(int): the min ratio of generated prior boxes.\n       max_ratio(int): the max ratio of generated prior boxes.\n       min_sizes(list|tuple|None): If `len(inputs) <=2`,\n            min_sizes must be set up, and the length of min_sizes\n            should equal to the length of inputs. Default: None.\n       max_sizes(list|tuple|None): If `len(inputs) <=2`,\n            max_sizes must be set up, and the length of min_sizes\n            should equal to the length of inputs. Default: None.\n       steps(list|tuple): If step_w and step_h are the same,\n            step_w and step_h can be replaced by steps.\n       step_w(list|tuple): Prior boxes step\n            across width. If step_w[i] == 0.0, the prior boxes step\n            across width of the inputs[i] will be automatically\n            calculated. Default: None.\n       step_h(list|tuple): Prior boxes step across height, If\n            step_h[i] == 0.0, the prior boxes step across height of\n            the inputs[i] will be automatically calculated. Default: None.\n       offset(float): Prior boxes center offset. Default: 0.5\n       variance(list|tuple): the variances to be encoded in prior boxes.\n            Default:[0.1, 0.1, 0.2, 0.2].\n       flip(bool): Whether to flip aspect ratios. Default:False.\n       clip(bool): Whether to clip out-of-boundary boxes. Default: False.\n       kernel_size(int): The kernel size of conv2d. Default: 1.\n       pad(int|list|tuple): The padding of conv2d. Default:0.\n       stride(int|list|tuple): The stride of conv2d. Default:1,\n       name(str): The default value is None.  Normally there is no need\n           for user to set this property.  For more information, please\n           refer to :ref:`api_guide_Name`.\n       min_max_aspect_ratios_order(bool): If set True, the output prior box is\n            in order of [min, max, aspect_ratios], which is consistent with\n            Caffe. Please note, this order affects the weights order of\n            convolution layer followed by and does not affect the final\n            detection results. Default: False.\n\n    Returns:\n        tuple: A tuple with four Variables. (mbox_loc, mbox_conf, boxes, variances)\n\n        mbox_loc (Variable): The predicted boxes' location of the inputs. The\n        layout is [N, num_priors, 4], where N is batch size, ``num_priors``\n        is the number of prior boxes. Data type is the same as input.\n\n        mbox_conf (Variable): The predicted boxes' confidence of the inputs.\n        The layout is [N, num_priors, C], where ``N`` and ``num_priors`` \n        has the same meaning as above. C is the number of Classes.\n        Data type is the same as input.\n\n        boxes (Variable): the output prior boxes. The layout is [num_priors, 4].\n        The meaning of num_priors is the same as above.\n        Data type is the same as input.\n\n        variances (Variable): the expanded variances for prior boxes.\n        The layout is [num_priors, 4]. Data type is the same as input.\n\n    Examples 1: set min_ratio and max_ratio:\n        .. code-block:: python\n\n          import paddle.fluid as fluid\n\n          images = fluid.data(name='data', shape=[None, 3, 300, 300], dtype='float32')\n          conv1 = fluid.data(name='conv1', shape=[None, 512, 19, 19], dtype='float32')\n          conv2 = fluid.data(name='conv2', shape=[None, 1024, 10, 10], dtype='float32')\n          conv3 = fluid.data(name='conv3', shape=[None, 512, 5, 5], dtype='float32')\n          conv4 = fluid.data(name='conv4', shape=[None, 256, 3, 3], dtype='float32')\n          conv5 = fluid.data(name='conv5', shape=[None, 256, 2, 2], dtype='float32')\n          conv6 = fluid.data(name='conv6', shape=[None, 128, 1, 1], dtype='float32')\n\n          mbox_locs, mbox_confs, box, var = fluid.layers.multi_box_head(\n            inputs=[conv1, conv2, conv3, conv4, conv5, conv6],\n            image=images,\n            num_classes=21,\n            min_ratio=20,\n            max_ratio=90,\n            aspect_ratios=[[2.], [2., 3.], [2., 3.], [2., 3.], [2.], [2.]],\n            base_size=300,\n            offset=0.5,\n            flip=True,\n            clip=True)\n\n    Examples 2: set min_sizes and max_sizes:\n        .. code-block:: python\n\n          import paddle.fluid as fluid\n\n          images = fluid.data(name='data', shape=[None, 3, 300, 300], dtype='float32')\n          conv1 = fluid.data(name='conv1', shape=[None, 512, 19, 19], dtype='float32')\n          conv2 = fluid.data(name='conv2', shape=[None, 1024, 10, 10], dtype='float32')\n          conv3 = fluid.data(name='conv3', shape=[None, 512, 5, 5], dtype='float32')\n          conv4 = fluid.data(name='conv4', shape=[None, 256, 3, 3], dtype='float32')\n          conv5 = fluid.data(name='conv5', shape=[None, 256, 2, 2], dtype='float32')\n          conv6 = fluid.data(name='conv6', shape=[None, 128, 1, 1], dtype='float32')\n\n          mbox_locs, mbox_confs, box, var = fluid.layers.multi_box_head(\n            inputs=[conv1, conv2, conv3, conv4, conv5, conv6],\n            image=images,\n            num_classes=21,\n            min_sizes=[60.0, 105.0, 150.0, 195.0, 240.0, 285.0],\n            max_sizes=[[], 150.0, 195.0, 240.0, 285.0, 300.0],\n            aspect_ratios=[[2.], [2., 3.], [2., 3.], [2., 3.], [2.], [2.]],\n            base_size=300,\n            offset=0.5,\n            flip=True,\n            clip=True)\n\n    "

    def _reshape_with_axis_(input, axis=1):
        out = nn.flatten(x=input, axis=axis)
        return out

    def _is_list_or_tuple_(data):
        return (isinstance(data, list) or isinstance(data, tuple))

    def _is_list_or_tuple_and_equal(data, length, err_info):
        if (not (_is_list_or_tuple_(data) and (len(data) == length))):
            raise ValueError(err_info)
    if (not _is_list_or_tuple_(inputs)):
        raise ValueError('inputs should be a list or tuple.')
    num_layer = len(inputs)
    if (num_layer <= 2):
        assert ((min_sizes is not None) and (max_sizes is not None))
        assert ((len(min_sizes) == num_layer) and (len(max_sizes) == num_layer))
    elif ((min_sizes is None) and (max_sizes is None)):
        min_sizes = []
        max_sizes = []
        step = int(math.floor(((max_ratio - min_ratio) / (num_layer - 2))))
        for ratio in six.moves.range(min_ratio, (max_ratio + 1), step):
            min_sizes.append(((base_size * ratio) / 100.0))
            max_sizes.append(((base_size * (ratio + step)) / 100.0))
        min_sizes = ([(base_size * 0.1)] + min_sizes)
        max_sizes = ([(base_size * 0.2)] + max_sizes)
    if aspect_ratios:
        _is_list_or_tuple_and_equal(aspect_ratios, num_layer, 'aspect_ratios should be list or tuple, and the length of inputs and aspect_ratios should be the same.')
    if (step_h is not None):
        _is_list_or_tuple_and_equal(step_h, num_layer, 'step_h should be list or tuple, and the length of inputs and step_h should be the same.')
    if (step_w is not None):
        _is_list_or_tuple_and_equal(step_w, num_layer, 'step_w should be list or tuple, and the length of inputs and step_w should be the same.')
    if (steps is not None):
        _is_list_or_tuple_and_equal(steps, num_layer, 'steps should be list or tuple, and the length of inputs and step_w should be the same.')
        step_w = steps
        step_h = steps
    mbox_locs = []
    mbox_confs = []
    box_results = []
    var_results = []
    for (i, input) in enumerate(inputs):
        min_size = min_sizes[i]
        max_size = max_sizes[i]
        if (not _is_list_or_tuple_(min_size)):
            min_size = [min_size]
        if (not _is_list_or_tuple_(max_size)):
            max_size = [max_size]
        aspect_ratio = []
        if (aspect_ratios is not None):
            aspect_ratio = aspect_ratios[i]
            if (not _is_list_or_tuple_(aspect_ratio)):
                aspect_ratio = [aspect_ratio]
        step = [(step_w[i] if step_w else 0.0), (step_h[i] if step_w else 0.0)]
        (box, var) = prior_box(input, image, min_size, max_size, aspect_ratio, variance, flip, clip, step, offset, None, min_max_aspect_ratios_order)
        box_results.append(box)
        var_results.append(var)
        num_boxes = box.shape[2]
        num_loc_output = (num_boxes * 4)
        mbox_loc = nn.conv2d(input=input, num_filters=num_loc_output, filter_size=kernel_size, padding=pad, stride=stride)
        mbox_loc = nn.transpose(mbox_loc, perm=[0, 2, 3, 1])
        mbox_loc_flatten = nn.flatten(mbox_loc, axis=1)
        mbox_locs.append(mbox_loc_flatten)
        num_conf_output = (num_boxes * num_classes)
        conf_loc = nn.conv2d(input=input, num_filters=num_conf_output, filter_size=kernel_size, padding=pad, stride=stride)
        conf_loc = nn.transpose(conf_loc, perm=[0, 2, 3, 1])
        conf_loc_flatten = nn.flatten(conf_loc, axis=1)
        mbox_confs.append(conf_loc_flatten)
    if (len(box_results) == 1):
        box = box_results[0]
        var = var_results[0]
        mbox_locs_concat = mbox_locs[0]
        mbox_confs_concat = mbox_confs[0]
    else:
        reshaped_boxes = []
        reshaped_vars = []
        for i in range(len(box_results)):
            reshaped_boxes.append(_reshape_with_axis_(box_results[i], axis=3))
            reshaped_vars.append(_reshape_with_axis_(var_results[i], axis=3))
        box = tensor.concat(reshaped_boxes)
        var = tensor.concat(reshaped_vars)
        mbox_locs_concat = tensor.concat(mbox_locs, axis=1)
        mbox_locs_concat = nn.reshape(mbox_locs_concat, shape=[0, (- 1), 4])
        mbox_confs_concat = tensor.concat(mbox_confs, axis=1)
        mbox_confs_concat = nn.reshape(mbox_confs_concat, shape=[0, (- 1), num_classes])
    box.stop_gradient = True
    var.stop_gradient = True
    return (mbox_locs_concat, mbox_confs_concat, box, var)