refactor(membership-inference): migrate to new attack architecture#75
Open
asim29 wants to merge 1 commit intopr/4.1-distribution-inferencefrom
Open
refactor(membership-inference): migrate to new attack architecture#75asim29 wants to merge 1 commit intopr/4.1-distribution-inferencefrom
asim29 wants to merge 1 commit intopr/4.1-distribution-inferencefrom
Conversation
210b630 to
1f8c588
Compare
…cture
lira.py:
- Renames experiment_id -> exp_id to match base class.
- Removes unused __get_logits and __normalize_logits private methods.
- Simplifies attack(): pre-allocates all_logits as list-of-lists instead
of building it lazily; builds in_out_labels with a single np.array()
call; targets on CPU directly to avoid an extra .to(device) round-trip.
- Removes copy.deepcopy in __get_log_logits (not needed; softmax is
computed in-place on a per-model slice, not the original array).
- Adds return type annotation dict[str, np.ndarray] to attack().
dp_sgd.py:
- Fixes unbound loss variable: introduces last_loss sentinel so the
end-of-epoch privacy accounting line cannot reference an unbound name
when the loader is empty.
- Renames self.trainloader -> self.train_loader (matches base class attribute).
- Fixes unpacking: replaces for batch_idx, (tuple) with
for batch_idx, (data, target) to avoid shadowing the built-in.
- Docstring: renames delt -> delta to match the constructor parameter.
1f8c588 to
75b8b08
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Two files updated (
lira.py,dp_sgd.py) with targeted bug fixes and cleanup to align both with the base classes landed in PR 2. Integration and unit tests added.Stacked on:
pr/4.1-distribution-inferenceWhat changed and why
attacks/lira.pyexperiment_id→exp_idsuper().__init__()call to match the base class attribute name established in PR 2.__get_logits,__normalize_logits__get_logitswas never called inattack();__normalize_logitswas replaced inline.attack()logit collectionall_logitsaslist[list[np.ndarray]]with a known length instead of growing it lazily. Targets collected with.numpy()directly (they were already on CPU afterDataLoader).in_out_labelsconstructionnp.array([...], dtype=bool)list comprehension.copy.deepcopyin__get_log_logitspred_logits[model_idx]), so modifyingprobsin-place never affects the original array.attack()now declares-> dict[str, np.ndarray]as required by the ABC.lira_offline_preds, ___lira_offlinewas being silently overwritingtrue_labels; changed to_.defenses/dp_sgd.pylossvariableloss.item()in the end-of-epoch print was referencing the loop variable after the loop might have zero iterations. Fixed by introducinglast_loss: torch.Tensor | None = Noneupdated each iteration, guarded byif last_loss is not None.self.trainloader→self.train_loadermake_private()return value was being assigned to a new attributeself.trainloaderinstead of updating the existingself.train_loader. This causedtrain_private()to iterate the un-wrapped loader without DP.for batch_idx, (tuple) in enumerate(...)shadowed the built-intuple. Changed tofor batch_idx, (data, target) in enumerate(...).delt→deltato match the constructor parameter.Test plan
uv run pre-commit run --all-filespassesuv run pytest tests/unit/test_metrics_mi.py -vpassesfrom amulet.membership_inference.attacks import LiRAresolvesfrom amulet.membership_inference.defenses import DPSGDresolvesLiRA(..., exp_id=0)constructs without error (oldexperiment_idkwarg removed)🤖 Generated with Claude Code