def add_unary(
        self,
        name,
        input_name,
        output_name,
        mode,
        alpha=1.0,
        shift=0,
        scale=1.0,
        epsilon=None,
    ):
        """
        Add a Unary layer. Applies the specified function (mode) to all the elements of the input.
        Prior to the application of the function the input can be scaled and shifted by using the 'scale',
        'shift' parameters.
        Refer to the ``UnaryFunctionLayerParams`` message in the specification (NeuralNetwork.proto) for more details.

        Parameters
        ----------
        name: str
            The name of this layer.

        input_name: str
            The input blob name of this layer.
        output_name: str
            The output blob name of this layer.

        mode: str
            Unary function.
            Allowed values: 'sqrt', 'rsqrt', 'inverse', 'power', 'exp', 'log', 'abs', threshold'.

        alpha: float
            constant used in with modes 'power' and 'threshold'.

        shift, scale: float
            input is modified by scale and shift prior to the application of the unary function.

        epsilon: float
            small bias to prevent division by zero.

        See Also
        --------
        add_activation
        """
        spec_layer = self._add_generic_layer(name, [input_name], [output_name])
        spec_layer_params = spec_layer.unary
        if epsilon is None:
            # Use the default value of epsilon to be 1e-4, instead of 1e-6, if mode = "rsqrt" or "inverse"
            if mode == "inverse" or mode == "rsqrt":
                epsilon = 1e-4
            elif mode == "log":
                epsilon = 1e-45
            else:
                epsilon = 1e-6
        spec_layer_params.epsilon = epsilon
        spec_layer_params.alpha = alpha
        spec_layer_params.shift = shift
        spec_layer_params.scale = scale

        mode = mode.lower() if isinstance(mode, str) else mode
        if mode == "sqrt":
            spec_layer_params.type = (
                _proto.NeuralNetwork_pb2.UnaryFunctionLayerParams.Operation.Value("SQRT")
            )
        elif mode == "rsqrt":
            spec_layer_params.type = (
                _proto.NeuralNetwork_pb2.UnaryFunctionLayerParams.Operation.Value("RSQRT")
            )
        elif mode == "inverse":
            spec_layer_params.type = (
                _proto.NeuralNetwork_pb2.UnaryFunctionLayerParams.Operation.Value("INVERSE")
            )
        elif mode == "power":
            spec_layer_params.type = (
                _proto.NeuralNetwork_pb2.UnaryFunctionLayerParams.Operation.Value("POWER")
            )
        elif mode == "exp":
            spec_layer_params.type = (
                _proto.NeuralNetwork_pb2.UnaryFunctionLayerParams.Operation.Value("EXP")
            )
        elif mode == "log":
            spec_layer_params.type = (
                _proto.NeuralNetwork_pb2.UnaryFunctionLayerParams.Operation.Value("LOG")
            )
        elif mode == "abs":
            spec_layer_params.type = (
                _proto.NeuralNetwork_pb2.UnaryFunctionLayerParams.Operation.Value("ABS")
            )
        elif mode == "threshold":
            spec_layer_params.type = (
                _proto.NeuralNetwork_pb2.UnaryFunctionLayerParams.Operation.Value("THRESHOLD")
            )
        else:
            raise NotImplementedError("Unknown unary function %s " % mode)
        return spec_layer

        Add a Unary layer. Applies the specified function (mode) to all the elements of the input.
        Prior to the application of the function the input can be scaled and shifted by using the 'scale',
        'shift' parameters.
        Refer to the ``UnaryFunctionLayerParams`` message in the specification (NeuralNetwork.proto) for more details.

        Parameters
        ----------
        name: str
            The name of this layer.

        input_name: str
            The input blob name of this layer.
        output_name: str
            The output blob name of this layer.

        mode: str
            Unary function.
            Allowed values: 'sqrt', 'rsqrt', 'inverse', 'power', 'exp', 'log', 'abs', threshold'.

        alpha: float
            constant used in with modes 'power' and 'threshold'.

        shift, scale: float
            input is modified by scale and shift prior to the application of the unary function.

        epsilon: float
            small bias to prevent division by zero.

        See Also
        --------
        add_activation
        
coremltools/models/neural_network/builder.py