Move to new API.
PiperOrigin-RevId: 334434385
This commit is contained in:
parent
bca2baae8d
commit
20d0b884ba
7 changed files with 186 additions and 199 deletions
|
@ -18,17 +18,6 @@ the model are used (e.g., losses, logits, predictions). Neither model internals
|
||||||
|
|
||||||
## How to use
|
## How to use
|
||||||
|
|
||||||
|
|
||||||
### API revamp note
|
|
||||||
We're **revamping our attacks API to make it more structured, modular and
|
|
||||||
extensible**. The docs below refers to the legacy experimental API and will be
|
|
||||||
updated soon. Stay tuned!
|
|
||||||
|
|
||||||
For a quick preview, you can take a look at `data_structures.py` and `membership_inference_attack_new.py`.
|
|
||||||
|
|
||||||
For now, here's a reference to the legacy API.
|
|
||||||
|
|
||||||
|
|
||||||
### Codelab
|
### Codelab
|
||||||
|
|
||||||
The easiest way to get started is to go through [the introductory codelab](https://github.com/tensorflow/privacy/blob/master/tensorflow_privacy/privacy/membership_inference_attack/codelab.ipynb).
|
The easiest way to get started is to go through [the introductory codelab](https://github.com/tensorflow/privacy/blob/master/tensorflow_privacy/privacy/membership_inference_attack/codelab.ipynb).
|
||||||
|
@ -39,213 +28,213 @@ For a more detailed overview of the library, please check the sections below.
|
||||||
|
|
||||||
### Basic usage
|
### Basic usage
|
||||||
|
|
||||||
On the highest level, there is the `run_all_attacks_and_create_summary`
|
The simplest possible usage is
|
||||||
function, which chooses sane default options to run a host of (fairly simple)
|
|
||||||
attacks behind the scenes (depending on which data is fed in), computes the most
|
```python
|
||||||
important measures and returns a summary of the results as a string of english
|
from tensorflow_privacy.privacy.membership_inference_attack import membership_inference_attack as mia
|
||||||
language (as well as optionally a python dictionary containing all results with
|
from tensorflow_privacy.privacy.membership_inference_attack.data_structures import AttackInputData
|
||||||
descriptive keys).
|
|
||||||
|
# Suppose we have the labels as integers starting from 0
|
||||||
|
# labels_train shape: (n_train, )
|
||||||
|
# labels_test shape: (n_test, )
|
||||||
|
|
||||||
|
# Evaluate your model on training and test examples to get
|
||||||
|
# loss_train shape: (n_train, )
|
||||||
|
# loss_test shape: (n_test, )
|
||||||
|
|
||||||
|
attacks_result = mia.run_attacks(
|
||||||
|
AttackInputData(
|
||||||
|
loss_train = loss_train,
|
||||||
|
loss_test = loss_test,
|
||||||
|
labels_train = labels_train,
|
||||||
|
labels_test = labels_test))
|
||||||
|
```
|
||||||
|
|
||||||
|
This example calls `run_attacks` with the default options to run a host of
|
||||||
|
(fairly simple) attacks behind the scenes (depending on which data is fed in),
|
||||||
|
and computes the most important measures.
|
||||||
|
|
||||||
> NOTE: The train and test sets are balanced internally, i.e., an equal number
|
> NOTE: The train and test sets are balanced internally, i.e., an equal number
|
||||||
> of in-training and out-of-training examples is chosen for the attacks
|
> of in-training and out-of-training examples is chosen for the attacks
|
||||||
> (whichever has fewer examples). These are subsampled uniformly at random
|
> (whichever has fewer examples). These are subsampled uniformly at random
|
||||||
> without replacement from the larger of the two.
|
> without replacement from the larger of the two.
|
||||||
|
|
||||||
The simplest possible usage is
|
Then, we can view the attack results by:
|
||||||
|
|
||||||
```python
|
```python
|
||||||
from tensorflow_privacy.privacy.membership_inference_attack import membership_inference_attack as mia
|
print(attacks_result.summary())
|
||||||
|
# Example output:
|
||||||
# Evaluate your model on training and test examples to get
|
# -> Best-performing attacks over all slices
|
||||||
# loss_train shape: (n_train, )
|
# THRESHOLD_ATTACK achieved an AUC of 0.60 on slice Entire dataset
|
||||||
# loss_test shape: (n_test, )
|
# THRESHOLD_ATTACK achieved an advantage of 0.22 on slice Entire dataset
|
||||||
|
|
||||||
summary, results = mia.run_all_attacks_and_create_summary(loss_train, loss_test, return_dict=True)
|
|
||||||
print(results)
|
|
||||||
# -> {'auc': 0.7044,
|
|
||||||
# 'best_attacker_auc': 'all_thresh_loss_auc',
|
|
||||||
# 'advantage': 0.3116,
|
|
||||||
# 'best_attacker_auc': 'all_thresh_loss_advantage'}
|
|
||||||
```
|
```
|
||||||
|
|
||||||
> NOTE: The keyword argument `return_dict` specified whether in addition to the
|
|
||||||
> `summary` the function also returns a python dictionary with the results.
|
|
||||||
|
|
||||||
If the model is a classifier, the logits or output probabilities (i.e., the
|
|
||||||
softmax of logits) can also be provided to perform stronger attacks.
|
|
||||||
|
|
||||||
> NOTE: The `logits_train` and `logits_test` arguments can also be filled with
|
|
||||||
> output probabilities per class ("posteriors").
|
|
||||||
|
|
||||||
```python
|
|
||||||
# logits_train shape: (n_train, n_classes)
|
|
||||||
# logits_test shape: (n_test, n_classes)
|
|
||||||
|
|
||||||
summary, results = mia.run_all_attacks_and_create_summary(loss_train, loss_test, logits_train,
|
|
||||||
logits_test, return_dict=True)
|
|
||||||
print(results)
|
|
||||||
# -> {'auc': 0.5382,
|
|
||||||
# 'best_attacker_auc': 'all_lr_logits_loss_test_auc',
|
|
||||||
# 'advantage': 0.0572,
|
|
||||||
# 'best_attacker_auc': 'all_mlp_logits_loss_test_advantage'}
|
|
||||||
```
|
|
||||||
|
|
||||||
The `summary` will be a string in natural language describing the results in
|
|
||||||
more detail, e.g.,
|
|
||||||
|
|
||||||
```
|
|
||||||
========== AUC ==========
|
|
||||||
The best attack (all_lr_logits_loss_test_auc) achieved an auc of 0.5382.
|
|
||||||
|
|
||||||
========== ADVANTAGE ==========
|
|
||||||
The best attack (all_mlp_logits_loss_test_advantage) achieved an advantage of 0.0572.
|
|
||||||
```
|
|
||||||
|
|
||||||
Similarly, we can run attacks on the logits alone, without access to losses:
|
|
||||||
|
|
||||||
```python
|
|
||||||
summary, results = mia.run_all_attacks_and_create_summary(logits_train=logits_train,
|
|
||||||
logits_test=logits_test,
|
|
||||||
return_dict=True)
|
|
||||||
print(results)
|
|
||||||
# -> {'auc': 0.9278,
|
|
||||||
# 'best_attacker_auc': 'all_rf_logits_test_auc',
|
|
||||||
# 'advantage': 0.6991,
|
|
||||||
# 'best_attacker_auc': 'all_rf_logits_test_advantage'}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Advanced usage
|
### Advanced usage
|
||||||
|
|
||||||
Finally, if we also have access to the true labels of the training and test
|
Sometimes, we have more information about the data, such as the logits and the
|
||||||
inputs, we can run the attacks for each class separately. If labels *and* logits
|
labels,
|
||||||
are provided, attacks only for misclassified (typically uncertain) examples are
|
and we may want to have finer-grained control of the attack, such as using more
|
||||||
also performed.
|
complicated classifiers instead of the simple threshold attack, and looks at the
|
||||||
|
attack results by examples' class.
|
||||||
|
In thoses cases, we can provide more information to `run_attacks`.
|
||||||
|
|
||||||
```python
|
```python
|
||||||
summary, results = mia.run_all_attacks_and_create_summary(loss_train, loss_test, logits_train,
|
from tensorflow_privacy.privacy.membership_inference_attack import membership_inference_attack as mia
|
||||||
logits_test, labels_train, labels_test,
|
from tensorflow_privacy.privacy.membership_inference_attack.data_structures import AttackInputData
|
||||||
return_dict=True)
|
from tensorflow_privacy.privacy.membership_inference_attack.data_structures import SlicingSpec
|
||||||
|
from tensorflow_privacy.privacy.membership_inference_attack.data_structures import AttackType
|
||||||
```
|
```
|
||||||
|
|
||||||
Here, we now also get as output the class with the maximal vulnerability
|
First, similar as before, we specify the input for the attack as an
|
||||||
according to our metrics (`max_vuln_class_auc`, `max_vuln_class_advantage`)
|
`AttackInputData` object:
|
||||||
together with the corresponding values (`class_<CLASS>_auc`,
|
|
||||||
`class_<CLASS>_advantage`). The same values exist in the `results` dictionary
|
|
||||||
for `min` instead of `max`, i.e., the least vulnerable classes. Moreover, the
|
|
||||||
gap between the maximum and minimum values (`max_class_gap_auc`,
|
|
||||||
`max_class_gap_advantage`) is also provided. Similarly, the vulnerability
|
|
||||||
metrics when the attacks are restricted to the misclassified examples
|
|
||||||
(`misclassified_auc`, `misclassified_advantage`) are also shown. Finally, the
|
|
||||||
results also contain the number of examples in each of these groups, i.e.,
|
|
||||||
within each of the reported classes as well as the number of misclassified
|
|
||||||
examples. The final `results` dictionary is of the form
|
|
||||||
|
|
||||||
```
|
|
||||||
{'auc': 0.9181,
|
|
||||||
'best_attacker_auc': 'all_rf_logits_loss_test_auc',
|
|
||||||
'advantage': 0.6915,
|
|
||||||
'best_attacker_advantage': 'all_rf_logits_loss_test_advantage',
|
|
||||||
'max_class_gap_auc': 0.254,
|
|
||||||
'class_5_auc': 0.9512,
|
|
||||||
'class_3_auc': 0.6972,
|
|
||||||
'max_vuln_class_auc': 5,
|
|
||||||
'min_vuln_class_auc': 3,
|
|
||||||
'max_class_gap_advantage': 0.5073,
|
|
||||||
'class_0_advantage': 0.8086,
|
|
||||||
'class_3_advantage': 0.3013,
|
|
||||||
'max_vuln_class_advantage': 0,
|
|
||||||
'min_vuln_class_advantage': 3,
|
|
||||||
'misclassified_n_examples': 4513.0,
|
|
||||||
'class_0_n_examples': 899.0,
|
|
||||||
'class_1_n_examples': 900.0,
|
|
||||||
'class_2_n_examples': 931.0,
|
|
||||||
'class_3_n_examples': 893.0,
|
|
||||||
'class_4_n_examples': 960.0,
|
|
||||||
'class_5_n_examples': 884.0}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Setting the precision of the reported results
|
|
||||||
|
|
||||||
Finally, `run_all_attacks_and_create_summary` takes one extra keyword argument
|
|
||||||
`decimals`, expecting a positive integer. This sets the precision of all result
|
|
||||||
values as the number of decimals to report. It defaults to 4.
|
|
||||||
|
|
||||||
## Run all attacks and get all outputs
|
|
||||||
|
|
||||||
With the `run_all_attacks` function, one can run all implemented attacks on all
|
|
||||||
possible subsets of the data (all examples, split by class, split by confidence
|
|
||||||
deciles, misclassified only). This function returns a relatively large
|
|
||||||
dictionary with all attack results. This is the most detailed information one
|
|
||||||
could get about these types of membership inference attacks (besides plots for
|
|
||||||
each attack, see next section.) This is useful if you know exactly what you're
|
|
||||||
looking for.
|
|
||||||
|
|
||||||
> NOTE: The `run_all_attacks` function takes as an additional argument which
|
|
||||||
> trained attackers to run. In the `run_all_attacks_and_create_summary`, only
|
|
||||||
> logistic regression (`lr`) is trained as a binary classifier to distinguish
|
|
||||||
> in-training form out-of-training examples. In addition, with the
|
|
||||||
> `attack_classifiers` argument, one can add multi-layered perceptrons (`mlp`),
|
|
||||||
> random forests (`rf`), and k-nearest-neighbors (`knn`) or any subset thereof
|
|
||||||
> for the attack models. Note that these classifiers may not converge.
|
|
||||||
|
|
||||||
```python
|
```python
|
||||||
mia.run_all_attacks(loss_train, loss_test, logits_train, logits_test,
|
# Evaluate your model on training and test examples to get
|
||||||
labels_train, labels_test,
|
# logits_train shape: (n_train, n_classes)
|
||||||
attack_classifiers=('lr', 'mlp', 'rf', 'knn'))
|
# logits_test shape: (n_test, n_classes)
|
||||||
```
|
# loss_train shape: (n_train, )
|
||||||
|
# loss_test shape: (n_test, )
|
||||||
|
|
||||||
Again, `run_all_attacks` can be called on all combinations of losses, logits,
|
attack_input = AttackInputData(
|
||||||
probabilities, and labels as long as at least either losses or logits
|
logits_train = logits_train,
|
||||||
(probabilities) are provided.
|
logits_test = logits_test,
|
||||||
|
loss_train = loss_train,
|
||||||
## Fine grained control over individual attacks and plots
|
|
||||||
|
|
||||||
The `run_attack` function exposes the underlying workhorse of the
|
|
||||||
`run_all_attacks` and `run_all_attacks_and_create_summary` functionality. It
|
|
||||||
allows for fine grained control of which attacks to run individually.
|
|
||||||
|
|
||||||
As another key feature, this function also exposes options to store receiver
|
|
||||||
operator curve plots for the different attacks as well as histograms of losses
|
|
||||||
or the maximum logits/probabilities. Finally, we can also store all results
|
|
||||||
(including the values to reproduce the plots) to colossus.
|
|
||||||
|
|
||||||
All options are explained in detail in the doc string of the `run_attack`
|
|
||||||
function.
|
|
||||||
|
|
||||||
For example, to run a simple threshold attack on the losses only and store plots
|
|
||||||
and result data to colossus, run
|
|
||||||
|
|
||||||
```python
|
|
||||||
data_path = '/Users/user/Desktop/test/' # set to None to not store data
|
|
||||||
figure_path = '/Users/user/Desktop/test/' # set to None to not store figures
|
|
||||||
|
|
||||||
mia.attack(loss_train=loss_train,
|
|
||||||
loss_test = loss_test,
|
loss_test = loss_test,
|
||||||
metric='auc',
|
labels_train = labels_train,
|
||||||
output_directory=data_path,
|
labels_test = labels_test)
|
||||||
figure_directory=figure_path)
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Among other things, the `run_attack` functionality allows to control:
|
Instead of `logits`, you can also specify
|
||||||
|
`probs_train` and `probs_test` as the predicted probabilty vectors of each
|
||||||
|
example.
|
||||||
|
|
||||||
|
Then, we specify some details of the attack.
|
||||||
|
The first part includes the specifications of the slicing of the data. For
|
||||||
|
example, we may want to evaluate the result on the whole dataset, or by class,
|
||||||
|
percentiles, or the correctness of the model's classification.
|
||||||
|
These can be specified by a `SlicingSpec` object.
|
||||||
|
|
||||||
|
```python
|
||||||
|
slicing_spec = SlicingSpec(
|
||||||
|
entire_dataset = True,
|
||||||
|
by_class = True,
|
||||||
|
by_percentiles = False,
|
||||||
|
by_classification_correctness = True)
|
||||||
|
```
|
||||||
|
|
||||||
|
The second part specifies the classifiers for the attacker to use.
|
||||||
|
Currently, our API supports five classifiers, including
|
||||||
|
`AttackType.THRESHOLD_ATTACK` for simple threshold attack,
|
||||||
|
`AttackType.LOGISTIC_REGRESSION`,
|
||||||
|
`AttackType.MULTI_LAYERED_PERCEPTRON`,
|
||||||
|
`AttackType.RANDOM_FOREST`, and
|
||||||
|
`AttackType.K_NEAREST_NEIGHBORS`
|
||||||
|
which use the corresponding machine learning models.
|
||||||
|
For some model, different classifiers can yield pertty different results.
|
||||||
|
We can put multiple classifers in a list:
|
||||||
|
|
||||||
|
```python
|
||||||
|
attack_types = [
|
||||||
|
AttackType.THRESHOLD_ATTACK,
|
||||||
|
AttackType.LOGISTIC_REGRESSION
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
Now, we can call the `run_attacks` methods with all specifications:
|
||||||
|
|
||||||
|
```python
|
||||||
|
attacks_result = mia.run_attacks(attack_input=attack_input,
|
||||||
|
slicing_spec=slicing_spec,
|
||||||
|
attack_types=attack_types)
|
||||||
|
```
|
||||||
|
|
||||||
|
This returns an object of type `AttackResults`. We can, for example, use the
|
||||||
|
following code to see the attack results specificed per-slice, as we have
|
||||||
|
request attacks by class and by model's classification correctness.
|
||||||
|
|
||||||
|
```python
|
||||||
|
print(attacks_result.summary(by_slices = True))
|
||||||
|
# Example output:
|
||||||
|
# -> Best-performing attacks over all slices
|
||||||
|
# THRESHOLD_ATTACK achieved an AUC of 0.75 on slice CORRECTLY_CLASSIFIED=False
|
||||||
|
# THRESHOLD_ATTACK achieved an advantage of 0.38 on slice CORRECTLY_CLASSIFIED=False
|
||||||
|
#
|
||||||
|
# Best-performing attacks over slice: "Entire dataset"
|
||||||
|
# LOGISTIC_REGRESSION achieved an AUC of 0.61
|
||||||
|
# THRESHOLD_ATTACK achieved an advantage of 0.22
|
||||||
|
#
|
||||||
|
# Best-performing attacks over slice: "CLASS=0"
|
||||||
|
# LOGISTIC_REGRESSION achieved an AUC of 0.62
|
||||||
|
# LOGISTIC_REGRESSION achieved an advantage of 0.24
|
||||||
|
#
|
||||||
|
# Best-performing attacks over slice: "CLASS=1"
|
||||||
|
# LOGISTIC_REGRESSION achieved an AUC of 0.61
|
||||||
|
# LOGISTIC_REGRESSION achieved an advantage of 0.19
|
||||||
|
#
|
||||||
|
# ...
|
||||||
|
#
|
||||||
|
# Best-performing attacks over slice: "CORRECTLY_CLASSIFIED=True"
|
||||||
|
# LOGISTIC_REGRESSION achieved an AUC of 0.53
|
||||||
|
# THRESHOLD_ATTACK achieved an advantage of 0.05
|
||||||
|
#
|
||||||
|
# Best-performing attacks over slice: "CORRECTLY_CLASSIFIED=False"
|
||||||
|
# THRESHOLD_ATTACK achieved an AUC of 0.75
|
||||||
|
# THRESHOLD_ATTACK achieved an advantage of 0.38
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
### Viewing and plotting the attack results
|
||||||
|
|
||||||
|
We have seen an example of using `summary()` to view the attack results as text.
|
||||||
|
We also provide some other ways for inspecting the attack results.
|
||||||
|
|
||||||
|
To get the attack that achieves the maximum attacker advantage or AUC, we can do
|
||||||
|
|
||||||
|
```python
|
||||||
|
max_auc_attacker = attacks_result.get_result_with_max_auc()
|
||||||
|
max_advantage_attacker = attacks_result.get_result_with_max_attacker_advantage()
|
||||||
|
```
|
||||||
|
Then, for individual attack, such as `max_auc_attacker`, we can check its type,
|
||||||
|
attacker advantage and AUC by
|
||||||
|
|
||||||
|
```python
|
||||||
|
print("Attack type with max AUC: %s, AUC of %.2f, Attacker advantage of %.2f" %
|
||||||
|
(max_auc_attacker.attack_type,
|
||||||
|
max_auc_attacker.roc_curve.get_auc(),
|
||||||
|
max_auc_attacker.roc_curve.get_attacker_advantage()))
|
||||||
|
# Example output:
|
||||||
|
# -> Attack type with max AUC: THRESHOLD_ATTACK, AUC of 0.75, Attacker advantage of 0.38
|
||||||
|
```
|
||||||
|
We can also plot its ROC curve by
|
||||||
|
|
||||||
|
```python
|
||||||
|
import tensorflow_privacy.privacy.membership_inference_attack.plotting as plotting
|
||||||
|
|
||||||
|
figure = plotting.plot_roc_curve(max_auc_attacker.roc_curve)
|
||||||
|
```
|
||||||
|
|
||||||
|
Additionally, we provide funcitonality to convert the attack results into Pandas
|
||||||
|
data frame:
|
||||||
|
|
||||||
|
```python
|
||||||
|
import pandas as pd
|
||||||
|
|
||||||
|
pd.set_option("display.max_rows", 8, "display.max_columns", None)
|
||||||
|
print(attacks_result.calculate_pd_dataframe())
|
||||||
|
# Example output:
|
||||||
|
# slice feature slice value attack type Attacker advantage AUC
|
||||||
|
# 0 entire_dataset threshold 0.216440 0.600630
|
||||||
|
# 1 entire_dataset lr 0.212073 0.612989
|
||||||
|
# 2 class 0 threshold 0.226000 0.611669
|
||||||
|
# 3 class 0 lr 0.239452 0.624076
|
||||||
|
# .. ... ... ... ... ...
|
||||||
|
# 22 correctly_classfied True threshold 0.054907 0.471290
|
||||||
|
# 23 correctly_classfied True lr 0.046986 0.525194
|
||||||
|
# 24 correctly_classfied False threshold 0.379465 0.748138
|
||||||
|
# 25 correctly_classfied False lr 0.370713 0.737148
|
||||||
|
```
|
||||||
|
|
||||||
* which metrics to output (`metric` argument, using `auc` or `advantage` or
|
|
||||||
both)
|
|
||||||
* which classifiers (logistic regression, multi-layered perceptrons, random
|
|
||||||
forests) to train as attackers beyond the simple threshold attacks
|
|
||||||
(`attack_classifiers`)
|
|
||||||
* to only attack a specific (set of) classes (`by_class`)
|
|
||||||
* to only attack specific percentiles of the data (`by_percentile`).
|
|
||||||
Percentiles here are computed by looking at the largest logit or probability
|
|
||||||
for each example, i.e., how confident the model is in its prediction.
|
|
||||||
* to only attack the misclassified examples (`only_misclassified`)
|
|
||||||
* not to balance examples between the in-training and out-of-training examples
|
|
||||||
using `balance`. By default an equal number of examples from train and test
|
|
||||||
are selected for the attacks (whichever is smaller).
|
|
||||||
* the test set size for trained attacks (`test_size`). When a classifier is
|
|
||||||
trained to distinguish between train and test examples, a train-test split
|
|
||||||
for that classifier itself is required.
|
|
||||||
* for the train-test split as well as for the class balancing randomness is
|
|
||||||
used with a seed specified by `random_state`.
|
|
||||||
|
|
||||||
## Contact / Feedback
|
## Contact / Feedback
|
||||||
|
|
||||||
|
|
|
@ -133,7 +133,7 @@
|
||||||
"source": [
|
"source": [
|
||||||
"!pip3 install git+https://github.com/tensorflow/privacy\n",
|
"!pip3 install git+https://github.com/tensorflow/privacy\n",
|
||||||
"\n",
|
"\n",
|
||||||
"from tensorflow_privacy.privacy.membership_inference_attack import membership_inference_attack_new as mia"
|
"from tensorflow_privacy.privacy.membership_inference_attack import membership_inference_attack as mia"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -163,7 +163,6 @@
|
||||||
"num_classes = 10\n",
|
"num_classes = 10\n",
|
||||||
"num_conv = 3\n",
|
"num_conv = 3\n",
|
||||||
"activation = 'relu'\n",
|
"activation = 'relu'\n",
|
||||||
"optimizer = 'adam'\n",
|
|
||||||
"lr = 0.02\n",
|
"lr = 0.02\n",
|
||||||
"momentum = 0.9\n",
|
"momentum = 0.9\n",
|
||||||
"batch_size = 250\n",
|
"batch_size = 250\n",
|
||||||
|
@ -218,7 +217,6 @@
|
||||||
"model = small_cnn(\n",
|
"model = small_cnn(\n",
|
||||||
" input_shape, num_classes, num_conv=num_conv, activation=activation)\n",
|
" input_shape, num_classes, num_conv=num_conv, activation=activation)\n",
|
||||||
"\n",
|
"\n",
|
||||||
"print('Optimizer ', optimizer)\n",
|
|
||||||
"print('learning rate %f', lr)\n",
|
"print('learning rate %f', lr)\n",
|
||||||
"\n",
|
"\n",
|
||||||
"optimizer = tf.keras.optimizers.SGD(lr=lr, momentum=momentum)\n",
|
"optimizer = tf.keras.optimizers.SGD(lr=lr, momentum=momentum)\n",
|
||||||
|
|
|
@ -27,7 +27,7 @@ from sklearn import metrics
|
||||||
from tensorflow import keras
|
from tensorflow import keras
|
||||||
from tensorflow.keras import layers
|
from tensorflow.keras import layers
|
||||||
from tensorflow.keras.utils import to_categorical
|
from tensorflow.keras.utils import to_categorical
|
||||||
from tensorflow_privacy.privacy.membership_inference_attack import membership_inference_attack_new as mia
|
from tensorflow_privacy.privacy.membership_inference_attack import membership_inference_attack as mia
|
||||||
|
|
||||||
from tensorflow_privacy.privacy.membership_inference_attack.data_structures import AttackInputData
|
from tensorflow_privacy.privacy.membership_inference_attack.data_structures import AttackInputData
|
||||||
from tensorflow_privacy.privacy.membership_inference_attack.data_structures import AttackResults
|
from tensorflow_privacy.privacy.membership_inference_attack.data_structures import AttackResults
|
||||||
|
@ -185,7 +185,7 @@ for attack_result in attack_results.single_attack_results:
|
||||||
print("Attacker advantage: %.2f\n" %
|
print("Attacker advantage: %.2f\n" %
|
||||||
attack_result.roc_curve.get_attacker_advantage())
|
attack_result.roc_curve.get_attacker_advantage())
|
||||||
|
|
||||||
max_auc_attacker = attack_results.get_result_with_max_attacker_advantage()
|
max_auc_attacker = attack_results.get_result_with_max_auc()
|
||||||
print("Attack type with max AUC: %s, AUC of %.2f" %
|
print("Attack type with max AUC: %s, AUC of %.2f" %
|
||||||
(max_auc_attacker.attack_type, max_auc_attacker.roc_curve.get_auc()))
|
(max_auc_attacker.attack_type, max_auc_attacker.roc_curve.get_auc()))
|
||||||
|
|
||||||
|
|
|
@ -21,7 +21,7 @@ from absl import logging
|
||||||
|
|
||||||
import tensorflow.compat.v1 as tf
|
import tensorflow.compat.v1 as tf
|
||||||
|
|
||||||
from tensorflow_privacy.privacy.membership_inference_attack import membership_inference_attack_new as mia
|
from tensorflow_privacy.privacy.membership_inference_attack import membership_inference_attack as mia
|
||||||
from tensorflow_privacy.privacy.membership_inference_attack.data_structures import AttackInputData
|
from tensorflow_privacy.privacy.membership_inference_attack.data_structures import AttackInputData
|
||||||
from tensorflow_privacy.privacy.membership_inference_attack.data_structures import AttackType
|
from tensorflow_privacy.privacy.membership_inference_attack.data_structures import AttackType
|
||||||
from tensorflow_privacy.privacy.membership_inference_attack.data_structures import get_flattened_attack_metrics
|
from tensorflow_privacy.privacy.membership_inference_attack.data_structures import get_flattened_attack_metrics
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
"""Tests for tensorflow_privacy.privacy.membership_inference_attack.utils."""
|
"""Tests for tensorflow_privacy.privacy.membership_inference_attack.utils."""
|
||||||
from absl.testing import absltest
|
from absl.testing import absltest
|
||||||
import numpy as np
|
import numpy as np
|
||||||
from tensorflow_privacy.privacy.membership_inference_attack import membership_inference_attack_new as mia
|
from tensorflow_privacy.privacy.membership_inference_attack import membership_inference_attack as mia
|
||||||
from tensorflow_privacy.privacy.membership_inference_attack.data_structures import AttackInputData
|
from tensorflow_privacy.privacy.membership_inference_attack.data_structures import AttackInputData
|
||||||
from tensorflow_privacy.privacy.membership_inference_attack.data_structures import AttackType
|
from tensorflow_privacy.privacy.membership_inference_attack.data_structures import AttackType
|
||||||
from tensorflow_privacy.privacy.membership_inference_attack.data_structures import SingleSliceSpec
|
from tensorflow_privacy.privacy.membership_inference_attack.data_structures import SingleSliceSpec
|
|
@ -20,7 +20,7 @@ from typing import Iterable
|
||||||
from absl import logging
|
from absl import logging
|
||||||
import numpy as np
|
import numpy as np
|
||||||
import tensorflow.compat.v1 as tf
|
import tensorflow.compat.v1 as tf
|
||||||
from tensorflow_privacy.privacy.membership_inference_attack import membership_inference_attack_new as mia
|
from tensorflow_privacy.privacy.membership_inference_attack import membership_inference_attack as mia
|
||||||
from tensorflow_privacy.privacy.membership_inference_attack.data_structures import AttackInputData
|
from tensorflow_privacy.privacy.membership_inference_attack.data_structures import AttackInputData
|
||||||
from tensorflow_privacy.privacy.membership_inference_attack.data_structures import AttackType
|
from tensorflow_privacy.privacy.membership_inference_attack.data_structures import AttackType
|
||||||
from tensorflow_privacy.privacy.membership_inference_attack.data_structures import get_flattened_attack_metrics
|
from tensorflow_privacy.privacy.membership_inference_attack.data_structures import get_flattened_attack_metrics
|
||||||
|
|
Loading…
Reference in a new issue