def get_func_output(self, func: mil.Function) -> List["proto.Model_pb2.FeatureDescription"]:
        """
        Utils to get function output feature description.
        """

        output_types = func.output_types
        output_features = []

        if output_types is not None and self.classifier_config is None:
            assert len(output_types) == len(
                func.outputs
            ), "number of mil program outputs do not match the number of outputs provided by the user"

        for i, var in enumerate(func.outputs):
            output_feature_type = proto.FeatureTypes_pb2.FeatureType()
            if types.is_tensor(var.sym_type) or types.is_primitive(var.sym_type):
                if output_types is not None and isinstance(
                    output_types[i], mil_input_types.ImageType
                ):
                    if not types.is_tensor(var.sym_type):
                        raise ValueError(
                            "Image output, '{}', is a scalar, but it should be a tensor of rank 4".format(
                                var.name
                            )
                        )

                    clr_space = _get_colorspace_enum(output_types[i].color_layout)

                    shape = var.sym_type.get_shape()
                    if any_variadic(shape):
                        raise ValueError(
                            "Variable rank model outputs, that are mil_input_types.ImageTypes, are not supported"
                        )
                    if any_symbolic(shape):
                        # For flexible shape output, we set the imageSizeRange to [1, -1],
                        # util this radar is fixed in CoreML: rdar://122895892 ([Bug] CoreML produce empty dictionary with image output with dynamic shape)
                        image_type = proto.FeatureTypes_pb2.ImageFeatureType(
                            width=1, height=1, colorSpace=clr_space
                        )
                        image_type.imageSizeRange.widthRange.lowerBound = 1
                        image_type.imageSizeRange.widthRange.upperBound = -1
                        image_type.imageSizeRange.heightRange.lowerBound = 1
                        image_type.imageSizeRange.heightRange.upperBound = -1
                    else:
                        image_type = proto.FeatureTypes_pb2.ImageFeatureType(
                            width=shape[-1], height=shape[-2], colorSpace=clr_space
                        )
                    _validate_image_input_output_shapes(
                        output_types[i].color_layout, shape, var.name, is_input=False
                    )

                    output_feature_type.imageType.CopyFrom(image_type)
                    output_features.append(
                        proto.Model_pb2.FeatureDescription(name=var.name, type=output_feature_type)
                    )
                else:
                    dataType = None
                    if self.classifier_config is None or var.name != self.predicted_feature_name:
                        # Not a classifier output, make sure model output type matches with ML Program type.
                        dataType = cast_to_framework_io_dtype(var, True)
                    else:
                        # Classifier outputs are set up separately, so default to fp32 for now.
                        dataType = proto.FeatureTypes_pb2.ArrayFeatureType.ArrayDataType.FLOAT32

                    output_shape = (
                        None
                        if any_symbolic(var.shape) or types.is_primitive(var.sym_type)
                        else var.shape
                    )
                    array_type = proto.FeatureTypes_pb2.ArrayFeatureType(
                        shape=output_shape, dataType=dataType
                    )
                    output_feature_type.multiArrayType.CopyFrom(array_type)
                    output_features.append(
                        proto.Model_pb2.FeatureDescription(name=var.name, type=output_feature_type)
                    )
            elif types.is_dict(var.sym_type):
                output_feature_type.dictionaryType.MergeFromString(b"")
                keytype, valtype = var.sym_type.T
                if types.is_str(keytype):
                    output_feature_type.dictionaryType.stringKeyType.MergeFromString(b"")
                elif keytype == types.int64:
                    output_feature_type.dictionaryType.int64KeyType.MergeFromString(b"")
                else:
                    raise ValueError("Dictionary key type not supported.")
                output_features.append(
                    proto.Model_pb2.FeatureDescription(name=var.name, type=output_feature_type)
                )
            else:
                raise NotImplementedError(f"Unsupported output type {var.sym_type}.")

        return output_features

        Utils to get function output feature description.
        
coremltools/converters/mil/backend/mil/load.py