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)
|