Infer output shapes and return dictionary of output name to shape

        :param :class:`~mxnet.symbol.Symbol` sym: symbol to perform infer shape on
        :param dic of (str, nd.NDArray) params:
        :param list of tuple(int, ...) in_shape: list of all input shapes
        :param  in_label: name of label typically used in loss that may be left in graph. This name is
            removed from list of inputs required by symbol
        :return: dictionary of output name to shape
        :rtype: dict of (str, tuple(int, ...))

def get_outputs(sym, params, in_shape, in_label):
        """ Infer output shapes and return dictionary of output name to shape

        :param :class:`~mxnet.symbol.Symbol` sym: symbol to perform infer shape on
        :param dic of (str, nd.NDArray) params:
        :param list of tuple(int, ...) in_shape: list of all input shapes
        :param  in_label: name of label typically used in loss that may be left in graph. This name is
            removed from list of inputs required by symbol
        :return: dictionary of output name to shape
        :rtype: dict of (str, tuple(int, ...))
        """
        # remove any input listed in params from sym.list_inputs() and bind them to the input shapes provided
        # by user. Also remove in_label, which is the name of the label symbol that may have been used
        # as the label for loss during training.
        inputs = {n: tuple(s) for n, s in zip([n for n in sym.list_inputs() if n not in params and n != in_label],
                                              in_shape)}
        # Add params and their shape to list of inputs
        inputs.update({n: v.shape for n, v in params.items() if n in sym.list_inputs()})
        # Provide input data as well as input params to infer_shape()
        _, out_shapes, _ = sym.infer_shape(**inputs)

        out_names = list()
        for name in sym.list_outputs():
            if name.endswith('_output'):
                out_names.append(name[:-len('_output')])
            else:
                logging.info("output '%s' does not end with '_output'", name)
                out_names.append(name)

        assert len(out_shapes) == len(out_names)
        # bind output shapes with output names
        graph_outputs = {n: s for n, s in zip(out_names, out_shapes)}

        return graph_outputs