Skip to content

declearn.optimizer.modules.GaussianNoiseModule

Bases: NoiseModule

Gaussian-noise addition module for DP-SGD.

This module uses either fast numpy pseudo-random number generation, or slower cryptographically secure pseudo-random numbers (CSPRN).

Source code in declearn/optimizer/modules/_noise.py
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
class GaussianNoiseModule(NoiseModule):
    """Gaussian-noise addition module for DP-SGD.

    This module uses either fast numpy pseudo-random number generation,
    or slower cryptographically secure pseudo-random numbers (CSPRN).
    """

    name: ClassVar[str] = "gaussian-noise"

    def __init__(
        self,
        std: float = 1.0,
        safe_mode: bool = True,
        seed: Optional[int] = None,
    ) -> None:
        """Instantiate the gaussian noise module.

        Parameters
        ----------
        std: float, default=1.0,
            Standard deviation of the gaussian noise.
        safe_mode: bool, default=True
            Whether to use cryptographically-secure pseudo-random numbers
            (CSPRN) rather than the default numpy generator.
            For experimental purposes, set flag to False, as generating CSPRN
            is significantly slower.
        seed: int or None, default=None
            Seed used for initiliazing the non-secure random number generator.
            If `safe_mode=True`, seed is ignored.
        """
        self.std = std
        super().__init__(safe_mode, seed)

    def get_config(
        self,
    ) -> Dict[str, Any]:
        config = super().get_config()
        config["std"] = self.std
        return config

    def _sample_noise(
        self,
        shape: Tuple[int, ...],
        dtype: str,
    ) -> np.ndarray:
        """Sample a noise tensor from a Gaussian distribution."""
        # Case when using CSPRN, that only provides uniform value sampling.
        # REVISE: improve performance, possibly using torch's CSPRN lib
        if isinstance(self._rng, SystemRandom):
            value = [self._rng.random() for _ in range(np.prod(shape))]
            array = np.array(value).reshape(shape).astype(dtype)
            return scipy.stats.norm.ppf(array, scale=self.std)
        # Case when using numpy RNG, that provides with gaussian sampling.
        if isinstance(self._rng, np.random.Generator):
            # false-positive; pylint: disable=no-member
            return self._rng.normal(scale=self.std, size=shape).astype(dtype)
        # Theoretically-unreachable case.
        raise RuntimeError(  # pragma: no cover
            "Unexpected `GaussianeNoiseModule._rng` type."
        )

__init__(std=1.0, safe_mode=True, seed=None)

Instantiate the gaussian noise module.

Parameters:

Name Type Description Default
std float

Standard deviation of the gaussian noise.

1.0
safe_mode bool

Whether to use cryptographically-secure pseudo-random numbers (CSPRN) rather than the default numpy generator. For experimental purposes, set flag to False, as generating CSPRN is significantly slower.

True
seed Optional[int]

Seed used for initiliazing the non-secure random number generator. If safe_mode=True, seed is ignored.

None
Source code in declearn/optimizer/modules/_noise.py
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
def __init__(
    self,
    std: float = 1.0,
    safe_mode: bool = True,
    seed: Optional[int] = None,
) -> None:
    """Instantiate the gaussian noise module.

    Parameters
    ----------
    std: float, default=1.0,
        Standard deviation of the gaussian noise.
    safe_mode: bool, default=True
        Whether to use cryptographically-secure pseudo-random numbers
        (CSPRN) rather than the default numpy generator.
        For experimental purposes, set flag to False, as generating CSPRN
        is significantly slower.
    seed: int or None, default=None
        Seed used for initiliazing the non-secure random number generator.
        If `safe_mode=True`, seed is ignored.
    """
    self.std = std
    super().__init__(safe_mode, seed)