Skip to content

Commit

Permalink
feat(protos): subsampled prototyping
Browse files Browse the repository at this point in the history
  • Loading branch information
Dariush Wahdany committed Dec 22, 2023
1 parent 702c4bb commit b75a94b
Showing 1 changed file with 36 additions and 8 deletions.
44 changes: 36 additions & 8 deletions src/dp_learning_ff/prototypes.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ def __init__(
steps: Optional[int] = None,
dist: Optional[str] = None,
Ps: Optional[Iterable[float]] = None,
p_sampling: Optional[float] = None,
seed: int = 42,
order: float = 1,
):
Expand All @@ -27,6 +28,7 @@ def __init__(
self.order = order
self.steps = steps
self.Ps = Ps
self.p_sampling = p_sampling
self.seed = seed
self.mechanism = None

Expand Down Expand Up @@ -62,6 +64,7 @@ def delta(self):

@delta.setter
def delta(self, value):
assert value is None or value > 0, "delta must be positive"
self._delta = value

@property
Expand All @@ -70,6 +73,13 @@ def dist(self):

@dist.setter
def dist(self, value):
assert value in [
"lin",
"exp",
"log",
"eq",
None,
], "dist must be in ['lin', 'exp', 'log', 'eq']"
self._dist = value

@property
Expand All @@ -86,20 +96,32 @@ def steps(self):

@steps.setter
def steps(self, value):
assert value is None or value > 0, "steps must be positive"
self._steps = value

@property
def p_sampling(self):
return self._p_sampling

@p_sampling.setter
def p_sampling(self, value):
assert value is None or (
value > 0 and value <= 1
), "p_sampling must be in (0, 1]"
self._p_sampling = value

def try_calibrate(self):
attrs1 = ["_epsilon", "_delta"]
attrs2 = ["_dist", "_order", "_steps"]
for attr in attrs1:
if not hasattr(self, attr) or getattr(self, attr) is None:
return
if self.Ps is None:
for attr in attrs2:
if getattr(self, attr) is None:
return
return self.calibrate_steps()
return self.calibrate_Ps()
if self.Ps is not None: # overwrites attrs2
return self.calibrate_Ps()
for attr in attrs2:
if getattr(self, attr) is None:
return
return self.calibrate_steps()

def calibrate_steps(self):
print(
Expand Down Expand Up @@ -175,6 +197,7 @@ def give_private_prototypes(
Ps: np.ndarray,
seed: int = 42,
subsampling: float = 1.0,
poisson_sampling: bool = True,
):
"""Returns a private prototype for each class.
Expand All @@ -198,8 +221,13 @@ def give_private_prototypes(
rng = np.random.default_rng(seed)
subsampled = []
for M_x in train_preds_sorted:
rng.shuffle(M_x, axis=0)
subsampled.append(M_x[: int(subsampling * M_x.shape[0])])
if poisson_sampling:
occurences = rng.poisson(lam=subsampling, size=M_x.shape[0])
subsampled_indices = np.arange(M_x.shape[0]).repeat(occurences)
subsampled.append(M_x[subsampled_indices])
else:
rng.shuffle(M_x, axis=0)
subsampled.append(M_x[: int(subsampling * M_x.shape[0])])
train_preds_sorted = subsampled
protos = np.asarray(
[private_mean(train_preds_sorted[i], Ps) for i, target in enumerate(targets)]
Expand Down

0 comments on commit b75a94b

Please sign in to comment.