<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 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 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 """

        # 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