Assess privacy risks with the TensorFlow Privacy Report

Stay organized with collections Save and categorize content based on your preferences.

View on TensorFlow.org Run in Google Colab View source on GitHub Download notebook

Overview

In this codelab you'll train a simple image classification model on the CIFAR10 dataset, and then use the "membership inference attack" against this model to assess if the attacker is able to "guess" whether a particular sample was present in the training set. You will use the TF Privacy Report to visualize results from multiple models and model checkpoints.

Setup

import numpy as np
from typing import Tuple
from scipy import special
from sklearn import metrics

import tensorflow as tf

import tensorflow_datasets as tfds

# Set verbosity.
tf.compat.v1.logging.set_verbosity(tf.compat.v1.logging.ERROR)
from sklearn.exceptions import ConvergenceWarning

import warnings
warnings.simplefilter(action="ignore", category=ConvergenceWarning)
warnings.simplefilter(action="ignore", category=FutureWarning)
2022-11-23 10:08:35.443447: W tensorflow/compiler/xla/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library 'libnvinfer.so.7'; dlerror: libnvinfer.so.7: cannot open shared object file: No such file or directory
2022-11-23 10:08:35.443552: W tensorflow/compiler/xla/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library 'libnvinfer_plugin.so.7'; dlerror: libnvinfer_plugin.so.7: cannot open shared object file: No such file or directory
2022-11-23 10:08:35.443562: W tensorflow/compiler/tf2tensorrt/utils/py_utils.cc:38] TF-TRT Warning: Cannot dlopen some TensorRT libraries. If you would like to use Nvidia GPU with TensorRT, please make sure the missing libraries mentioned above are installed properly.

Install TensorFlow Privacy.

pip install tensorflow_privacy
from tensorflow_privacy.privacy.privacy_tests.membership_inference_attack import membership_inference_attack as mia
from tensorflow_privacy.privacy.privacy_tests.membership_inference_attack.data_structures import AttackInputData
from tensorflow_privacy.privacy.privacy_tests.membership_inference_attack.data_structures import AttackResultsCollection
from tensorflow_privacy.privacy.privacy_tests.membership_inference_attack.data_structures import AttackType
from tensorflow_privacy.privacy.privacy_tests.membership_inference_attack.data_structures import PrivacyMetric
from tensorflow_privacy.privacy.privacy_tests.membership_inference_attack.data_structures import PrivacyReportMetadata
from tensorflow_privacy.privacy.privacy_tests.membership_inference_attack.data_structures import SlicingSpec
from tensorflow_privacy.privacy.privacy_tests.membership_inference_attack import privacy_report
import tensorflow_privacy

Train two models, with privacy metrics

This section trains a pair of keras.Model classifiers on the CIFAR-10 dataset. During the training process it collects privacy metrics, that will be used to generate reports in the bext section.

The first step is to define some hyperparameters:

dataset = 'cifar10'
num_classes = 10
activation = 'relu'
num_conv = 3

batch_size=50
epochs_per_report = 2
total_epochs = 50

lr = 0.001

Next, load the dataset. There's nothing privacy-specific in this code.

Loading the dataset.

Next define a function to build the models.

Build two three-layer CNN models using that function.

Configure the first to use a basic SGD optimizer, an the second to use a differentially private optimizer (tf_privacy.DPKerasAdamOptimizer), so you can compare the results.

model_2layers = small_cnn(
    input_shape, num_classes, num_conv=2, activation=activation)
model_3layers = small_cnn(
    input_shape, num_classes, num_conv=3, activation=activation)

Define a callback to collect privacy metrics

Next define a keras.callbacks.Callback to periorically run some privacy attacks against the model, and log the results.

The keras fit method will call the on_epoch_end method after each training epoch. The n argument is the (0-based) epoch number.

You could implement this procedure by writing a loop that repeatedly calls Model.fit(..., epochs=epochs_per_report) and runs the attack code. The callback is used here just because it gives a clear separation between the training logic, and the privacy evaluation logic.

class PrivacyMetrics(tf.keras.callbacks.Callback):
  def __init__(self, epochs_per_report, model_name):
    self.epochs_per_report = epochs_per_report
    self.model_name = model_name
    self.attack_results = []

  def on_epoch_end(self, epoch, logs=None):
    epoch = epoch+1

    if epoch % self.epochs_per_report != 0:
      return

    print(f'\nRunning privacy report for epoch: {epoch}\n')

    logits_train = self.model.predict(x_train, batch_size=batch_size)
    logits_test = self.model.predict(x_test, batch_size=batch_size)

    prob_train = special.softmax(logits_train, axis=1)
    prob_test = special.softmax(logits_test, axis=1)

    # Add metadata to generate a privacy report.
    privacy_report_metadata = PrivacyReportMetadata(
        # Show the validation accuracy on the plot
        # It's what you send to train_accuracy that gets plotted.
        accuracy_train=logs['val_accuracy'], 
        accuracy_test=logs['val_accuracy'],
        epoch_num=epoch,
        model_variant_label=self.model_name)

    attack_results = mia.run_attacks(
        AttackInputData(
            labels_train=y_train_indices[:, 0],
            labels_test=y_test_indices[:, 0],
            probs_train=prob_train,
            probs_test=prob_test),
        SlicingSpec(entire_dataset=True, by_class=True),
        attack_types=(AttackType.THRESHOLD_ATTACK,
                      AttackType.LOGISTIC_REGRESSION),
        privacy_report_metadata=privacy_report_metadata)

    self.attack_results.append(attack_results)

Train the models

The next code block trains the two models. The all_reports list is used to collect all the results from all the models' training runs. The individual reports are tagged witht the model_name, so there's no confusion about which model generated which report.

all_reports = []
callback = PrivacyMetrics(epochs_per_report, "2 Layers")
history = model_2layers.fit(
      x_train,
      y_train,
      batch_size=batch_size,
      epochs=total_epochs,
      validation_data=(x_test, y_test),
      callbacks=[callback],
      shuffle=True)

all_reports.extend(callback.attack_results)
Epoch 1/50
1000/1000 [==============================] - 12s 4ms/step - loss: 1.5891 - accuracy: 0.4258 - val_loss: 1.3176 - val_accuracy: 0.5307
Epoch 2/50
 990/1000 [============================>.] - ETA: 0s - loss: 1.2551 - accuracy: 0.5568
Running privacy report for epoch: 2

1000/1000 [==============================] - 2s 2ms/step
200/200 [==============================] - 0s 2ms/step
1000/1000 [==============================] - 14s 14ms/step - loss: 1.2535 - accuracy: 0.5572 - val_loss: 1.1827 - val_accuracy: 0.5804
Epoch 3/50
1000/1000 [==============================] - 4s 4ms/step - loss: 1.1253 - accuracy: 0.6052 - val_loss: 1.0900 - val_accuracy: 0.6203
Epoch 4/50
 989/1000 [============================>.] - ETA: 0s - loss: 1.0457 - accuracy: 0.6347
Running privacy report for epoch: 4

1000/1000 [==============================] - 2s 2ms/step
200/200 [==============================] - 0s 2ms/step
1000/1000 [==============================] - 14s 14ms/step - loss: 1.0453 - accuracy: 0.6348 - val_loss: 1.0505 - val_accuracy: 0.6376
Epoch 5/50
1000/1000 [==============================] - 4s 4ms/step - loss: 0.9868 - accuracy: 0.6545 - val_loss: 1.0164 - val_accuracy: 0.6477
Epoch 6/50
1000/1000 [==============================] - ETA: 0s - loss: 0.9406 - accuracy: 0.6714
Running privacy report for epoch: 6

1000/1000 [==============================] - 2s 2ms/step
200/200 [==============================] - 0s 2ms/step
1000/1000 [==============================] - 14s 14ms/step - loss: 0.9406 - accuracy: 0.6714 - val_loss: 0.9655 - val_accuracy: 0.6636
Epoch 7/50
1000/1000 [==============================] - 4s 4ms/step - loss: 0.9047 - accuracy: 0.6848 - val_loss: 0.9913 - val_accuracy: 0.6634
Epoch 8/50
 989/1000 [============================>.] - ETA: 0s - loss: 0.8699 - accuracy: 0.6969
Running privacy report for epoch: 8

1000/1000 [==============================] - 2s 2ms/step
200/200 [==============================] - 0s 2ms/step
1000/1000 [==============================] - 15s 15ms/step - loss: 0.8708 - accuracy: 0.6967 - val_loss: 0.9917 - val_accuracy: 0.6602
Epoch 9/50
1000/1000 [==============================] - 4s 4ms/step - loss: 0.8463 - accuracy: 0.7059 - val_loss: 0.9393 - val_accuracy: 0.6760
Epoch 10/50
 997/1000 [============================>.] - ETA: 0s - loss: 0.8223 - accuracy: 0.7124
Running privacy report for epoch: 10

1000/1000 [==============================] - 2s 2ms/step
200/200 [==============================] - 0s 2ms/step
1000/1000 [==============================] - 14s 14ms/step - loss: 0.8225 - accuracy: 0.7123 - val_loss: 0.9234 - val_accuracy: 0.6850
Epoch 11/50
1000/1000 [==============================] - 4s 4ms/step - loss: 0.7943 - accuracy: 0.7225 - val_loss: 0.9453 - val_accuracy: 0.6825
Epoch 12/50
 988/1000 [============================>.] - ETA: 0s - loss: 0.7770 - accuracy: 0.7292
Running privacy report for epoch: 12

1000/1000 [==============================] - 2s 2ms/step
200/200 [==============================] - 0s 2ms/step
1000/1000 [==============================] - 14s 14ms/step - loss: 0.7760 - accuracy: 0.7296 - val_loss: 0.9102 - val_accuracy: 0.6956
Epoch 13/50
1000/1000 [==============================] - 4s 4ms/step - loss: 0.7608 - accuracy: 0.7342 - val_loss: 0.9459 - val_accuracy: 0.6838
Epoch 14/50
 993/1000 [============================>.] - ETA: 0s - loss: 0.7405 - accuracy: 0.7425
Running privacy report for epoch: 14

1000/1000 [==============================] - 2s 2ms/step
200/200 [==============================] - 0s 2ms/step
1000/1000 [==============================] - 15s 15ms/step - loss: 0.7404 - accuracy: 0.7425 - val_loss: 0.9142 - val_accuracy: 0.6961
Epoch 15/50
1000/1000 [==============================] - 4s 4ms/step - loss: 0.7270 - accuracy: 0.7456 - val_loss: 0.9855 - val_accuracy: 0.6681
Epoch 16/50
 998/1000 [============================>.] - ETA: 0s - loss: 0.7077 - accuracy: 0.7519
Running privacy report for epoch: 16

1000/1000 [==============================] - 2s 2ms/step
200/200 [==============================] - 0s 2ms/step
1000/1000 [==============================] - 14s 14ms/step - loss: 0.7075 - accuracy: 0.7519 - val_loss: 0.9266 - val_accuracy: 0.6898
Epoch 17/50
1000/1000 [==============================] - 4s 4ms/step - loss: 0.6878 - accuracy: 0.7593 - val_loss: 0.9582 - val_accuracy: 0.6806
Epoch 18/50
 998/1000 [============================>.] - ETA: 0s - loss: 0.6780 - accuracy: 0.7620
Running privacy report for epoch: 18

1000/1000 [==============================] - 2s 2ms/step
200/200 [==============================] - 0s 2ms/step
1000/1000 [==============================] - 15s 15ms/step - loss: 0.6779 - accuracy: 0.7620 - val_loss: 0.9532 - val_accuracy: 0.6892
Epoch 19/50
1000/1000 [==============================] - 4s 4ms/step - loss: 0.6625 - accuracy: 0.7680 - val_loss: 0.9336 - val_accuracy: 0.6944
Epoch 20/50
 987/1000 [============================>.] - ETA: 0s - loss: 0.6530 - accuracy: 0.7724
Running privacy report for epoch: 20

1000/1000 [==============================] - 2s 2ms/step
200/200 [==============================] - 0s 2ms/step
1000/1000 [==============================] - 14s 14ms/step - loss: 0.6527 - accuracy: 0.7724 - val_loss: 0.9547 - val_accuracy: 0.6871
Epoch 21/50
1000/1000 [==============================] - 4s 4ms/step - loss: 0.6371 - accuracy: 0.7771 - val_loss: 0.9714 - val_accuracy: 0.6914
Epoch 22/50
 998/1000 [============================>.] - ETA: 0s - loss: 0.6294 - accuracy: 0.7776
Running privacy report for epoch: 22

1000/1000 [==============================] - 2s 2ms/step
200/200 [==============================] - 0s 2ms/step
1000/1000 [==============================] - 15s 15ms/step - loss: 0.6295 - accuracy: 0.7776 - val_loss: 0.9829 - val_accuracy: 0.6850
Epoch 23/50
1000/1000 [==============================] - 4s 4ms/step - loss: 0.6127 - accuracy: 0.7847 - val_loss: 1.0179 - val_accuracy: 0.6802
Epoch 24/50
 990/1000 [============================>.] - ETA: 0s - loss: 0.6025 - accuracy: 0.7880
Running privacy report for epoch: 24

1000/1000 [==============================] - 2s 2ms/step
200/200 [==============================] - 0s 2ms/step
1000/1000 [==============================] - 15s 15ms/step - loss: 0.6028 - accuracy: 0.7877 - val_loss: 0.9947 - val_accuracy: 0.6864
Epoch 25/50
1000/1000 [==============================] - 4s 4ms/step - loss: 0.5945 - accuracy: 0.7904 - val_loss: 0.9706 - val_accuracy: 0.6861
Epoch 26/50
 991/1000 [============================>.] - ETA: 0s - loss: 0.5818 - accuracy: 0.7942
Running privacy report for epoch: 26

1000/1000 [==============================] - 2s 2ms/step
200/200 [==============================] - 0s 2ms/step
1000/1000 [==============================] - 15s 15ms/step - loss: 0.5816 - accuracy: 0.7944 - val_loss: 0.9986 - val_accuracy: 0.6890
Epoch 27/50
1000/1000 [==============================] - 4s 4ms/step - loss: 0.5728 - accuracy: 0.7982 - val_loss: 0.9994 - val_accuracy: 0.6859
Epoch 28/50
 986/1000 [============================>.] - ETA: 0s - loss: 0.5570 - accuracy: 0.8037
Running privacy report for epoch: 28

1000/1000 [==============================] - 2s 2ms/step
200/200 [==============================] - 0s 2ms/step
1000/1000 [==============================] - 15s 15ms/step - loss: 0.5580 - accuracy: 0.8034 - val_loss: 1.0232 - val_accuracy: 0.6842
Epoch 29/50
1000/1000 [==============================] - 4s 4ms/step - loss: 0.5471 - accuracy: 0.8080 - val_loss: 1.0427 - val_accuracy: 0.6872
Epoch 30/50
 986/1000 [============================>.] - ETA: 0s - loss: 0.5387 - accuracy: 0.8096
Running privacy report for epoch: 30

1000/1000 [==============================] - 2s 2ms/step
200/200 [==============================] - 0s 2ms/step
1000/1000 [==============================] - 15s 15ms/step - loss: 0.5402 - accuracy: 0.8093 - val_loss: 1.1290 - val_accuracy: 0.6510
Epoch 31/50
1000/1000 [==============================] - 4s 4ms/step - loss: 0.5314 - accuracy: 0.8127 - val_loss: 1.0333 - val_accuracy: 0.6855
Epoch 32/50
1000/1000 [==============================] - ETA: 0s - loss: 0.5196 - accuracy: 0.8157
Running privacy report for epoch: 32

1000/1000 [==============================] - 2s 2ms/step
200/200 [==============================] - 0s 2ms/step
1000/1000 [==============================] - 15s 15ms/step - loss: 0.5196 - accuracy: 0.8157 - val_loss: 1.0483 - val_accuracy: 0.6840
Epoch 33/50
1000/1000 [==============================] - 4s 4ms/step - loss: 0.5125 - accuracy: 0.8193 - val_loss: 1.0767 - val_accuracy: 0.6785
Epoch 34/50
 988/1000 [============================>.] - ETA: 0s - loss: 0.4976 - accuracy: 0.8241
Running privacy report for epoch: 34

1000/1000 [==============================] - 2s 2ms/step
200/200 [==============================] - 0s 2ms/step
1000/1000 [==============================] - 15s 15ms/step - loss: 0.4982 - accuracy: 0.8238 - val_loss: 1.1201 - val_accuracy: 0.6756
Epoch 35/50
1000/1000 [==============================] - 4s 4ms/step - loss: 0.4954 - accuracy: 0.8241 - val_loss: 1.0850 - val_accuracy: 0.6826
Epoch 36/50
 995/1000 [============================>.] - ETA: 0s - loss: 0.4852 - accuracy: 0.8285
Running privacy report for epoch: 36

1000/1000 [==============================] - 2s 2ms/step
200/200 [==============================] - 0s 2ms/step
1000/1000 [==============================] - 15s 15ms/step - loss: 0.4852 - accuracy: 0.8286 - val_loss: 1.0938 - val_accuracy: 0.6875
Epoch 37/50
1000/1000 [==============================] - 4s 4ms/step - loss: 0.4789 - accuracy: 0.8287 - val_loss: 1.1465 - val_accuracy: 0.6710
Epoch 38/50
 993/1000 [============================>.] - ETA: 0s - loss: 0.4672 - accuracy: 0.8347
Running privacy report for epoch: 38

1000/1000 [==============================] - 2s 2ms/step
200/200 [==============================] - 0s 2ms/step
1000/1000 [==============================] - 15s 15ms/step - loss: 0.4673 - accuracy: 0.8346 - val_loss: 1.1402 - val_accuracy: 0.6806
Epoch 39/50
1000/1000 [==============================] - 4s 4ms/step - loss: 0.4627 - accuracy: 0.8353 - val_loss: 1.1566 - val_accuracy: 0.6784
Epoch 40/50
 997/1000 [============================>.] - ETA: 0s - loss: 0.4523 - accuracy: 0.8394
Running privacy report for epoch: 40

1000/1000 [==============================] - 2s 2ms/step
200/200 [==============================] - 0s 2ms/step
1000/1000 [==============================] - 15s 15ms/step - loss: 0.4526 - accuracy: 0.8393 - val_loss: 1.1614 - val_accuracy: 0.6810
Epoch 41/50
1000/1000 [==============================] - 4s 4ms/step - loss: 0.4483 - accuracy: 0.8396 - val_loss: 1.1443 - val_accuracy: 0.6846
Epoch 42/50
 999/1000 [============================>.] - ETA: 0s - loss: 0.4391 - accuracy: 0.8438
Running privacy report for epoch: 42

1000/1000 [==============================] - 2s 2ms/step
200/200 [==============================] - 0s 2ms/step
1000/1000 [==============================] - 15s 15ms/step - loss: 0.4394 - accuracy: 0.8437 - val_loss: 1.1979 - val_accuracy: 0.6777
Epoch 43/50
1000/1000 [==============================] - 4s 4ms/step - loss: 0.4327 - accuracy: 0.8463 - val_loss: 1.1828 - val_accuracy: 0.6857
Epoch 44/50
 987/1000 [============================>.] - ETA: 0s - loss: 0.4261 - accuracy: 0.8488
Running privacy report for epoch: 44

1000/1000 [==============================] - 2s 2ms/step
200/200 [==============================] - 0s 2ms/step
1000/1000 [==============================] - 15s 15ms/step - loss: 0.4268 - accuracy: 0.8485 - val_loss: 1.2384 - val_accuracy: 0.6700
Epoch 45/50
1000/1000 [==============================] - 4s 4ms/step - loss: 0.4207 - accuracy: 0.8512 - val_loss: 1.2181 - val_accuracy: 0.6781
Epoch 46/50
1000/1000 [==============================] - ETA: 0s - loss: 0.4144 - accuracy: 0.8525
Running privacy report for epoch: 46

1000/1000 [==============================] - 2s 2ms/step
200/200 [==============================] - 0s 2ms/step
1000/1000 [==============================] - 15s 15ms/step - loss: 0.4144 - accuracy: 0.8525 - val_loss: 1.2544 - val_accuracy: 0.6815
Epoch 47/50
1000/1000 [==============================] - 4s 4ms/step - loss: 0.4110 - accuracy: 0.8537 - val_loss: 1.2678 - val_accuracy: 0.6747
Epoch 48/50
 992/1000 [============================>.] - ETA: 0s - loss: 0.4030 - accuracy: 0.8558
Running privacy report for epoch: 48

1000/1000 [==============================] - 2s 2ms/step
200/200 [==============================] - 0s 2ms/step
1000/1000 [==============================] - 15s 15ms/step - loss: 0.4030 - accuracy: 0.8558 - val_loss: 1.2762 - val_accuracy: 0.6747
Epoch 49/50
1000/1000 [==============================] - 4s 4ms/step - loss: 0.3954 - accuracy: 0.8586 - val_loss: 1.3244 - val_accuracy: 0.6737
Epoch 50/50
 993/1000 [============================>.] - ETA: 0s - loss: 0.3911 - accuracy: 0.8613
Running privacy report for epoch: 50

1000/1000 [==============================] - 2s 2ms/step
200/200 [==============================] - 0s 2ms/step
1000/1000 [==============================] - 15s 15ms/step - loss: 0.3912 - accuracy: 0.8613 - val_loss: 1.3210 - val_accuracy: 0.6690
callback = PrivacyMetrics(epochs_per_report, "3 Layers")
history = model_3layers.fit(
      x_train,
      y_train,
      batch_size=batch_size,
      epochs=total_epochs,
      validation_data=(x_test, y_test),
      callbacks=[callback],
      shuffle=True)

all_reports.extend(callback.attack_results)
Epoch 1/50
1000/1000 [==============================] - 6s 5ms/step - loss: 1.6604 - accuracy: 0.3894 - val_loss: 1.4404 - val_accuracy: 0.4862
Epoch 2/50
 995/1000 [============================>.] - ETA: 0s - loss: 1.3463 - accuracy: 0.5146
Running privacy report for epoch: 2

1000/1000 [==============================] - 2s 2ms/step
200/200 [==============================] - 0s 2ms/step
1000/1000 [==============================] - 15s 15ms/step - loss: 1.3466 - accuracy: 0.5147 - val_loss: 1.2699 - val_accuracy: 0.5437
Epoch 3/50
1000/1000 [==============================] - 4s 4ms/step - loss: 1.2161 - accuracy: 0.5670 - val_loss: 1.1899 - val_accuracy: 0.5839
Epoch 4/50
 998/1000 [============================>.] - ETA: 0s - loss: 1.1224 - accuracy: 0.6032
Running privacy report for epoch: 4

1000/1000 [==============================] - 2s 2ms/step
200/200 [==============================] - 0s 2ms/step
1000/1000 [==============================] - 14s 14ms/step - loss: 1.1222 - accuracy: 0.6034 - val_loss: 1.1085 - val_accuracy: 0.6089
Epoch 5/50
1000/1000 [==============================] - 4s 4ms/step - loss: 1.0588 - accuracy: 0.6273 - val_loss: 1.0333 - val_accuracy: 0.6331
Epoch 6/50
 997/1000 [============================>.] - ETA: 0s - loss: 1.0027 - accuracy: 0.6463
Running privacy report for epoch: 6

1000/1000 [==============================] - 2s 2ms/step
200/200 [==============================] - 0s 2ms/step
1000/1000 [==============================] - 15s 15ms/step - loss: 1.0024 - accuracy: 0.6464 - val_loss: 1.0085 - val_accuracy: 0.6467
Epoch 7/50
1000/1000 [==============================] - 4s 4ms/step - loss: 0.9732 - accuracy: 0.6615 - val_loss: 1.0098 - val_accuracy: 0.6478
Epoch 8/50
1000/1000 [==============================] - ETA: 0s - loss: 0.9343 - accuracy: 0.6722
Running privacy report for epoch: 8

1000/1000 [==============================] - 2s 2ms/step
200/200 [==============================] - 0s 2ms/step
1000/1000 [==============================] - 15s 15ms/step - loss: 0.9343 - accuracy: 0.6722 - val_loss: 0.9634 - val_accuracy: 0.6634
Epoch 9/50
1000/1000 [==============================] - 4s 4ms/step - loss: 0.9102 - accuracy: 0.6828 - val_loss: 0.9665 - val_accuracy: 0.6599
Epoch 10/50
 987/1000 [============================>.] - ETA: 0s - loss: 0.8867 - accuracy: 0.6905
Running privacy report for epoch: 10

1000/1000 [==============================] - 2s 2ms/step
200/200 [==============================] - 0s 2ms/step
1000/1000 [==============================] - 15s 15ms/step - loss: 0.8867 - accuracy: 0.6904 - val_loss: 0.9766 - val_accuracy: 0.6636
Epoch 11/50
1000/1000 [==============================] - 4s 4ms/step - loss: 0.8644 - accuracy: 0.6963 - val_loss: 0.9554 - val_accuracy: 0.6694
Epoch 12/50
1000/1000 [==============================] - ETA: 0s - loss: 0.8404 - accuracy: 0.7047
Running privacy report for epoch: 12

1000/1000 [==============================] - 2s 2ms/step
200/200 [==============================] - 0s 2ms/step
1000/1000 [==============================] - 15s 15ms/step - loss: 0.8404 - accuracy: 0.7047 - val_loss: 0.9268 - val_accuracy: 0.6789
Epoch 13/50
1000/1000 [==============================] - 4s 4ms/step - loss: 0.8212 - accuracy: 0.7113 - val_loss: 0.9012 - val_accuracy: 0.6890
Epoch 14/50
 991/1000 [============================>.] - ETA: 0s - loss: 0.8055 - accuracy: 0.7178
Running privacy report for epoch: 14

1000/1000 [==============================] - 2s 2ms/step
200/200 [==============================] - 0s 2ms/step
1000/1000 [==============================] - 14s 14ms/step - loss: 0.8056 - accuracy: 0.7177 - val_loss: 0.9119 - val_accuracy: 0.6836
Epoch 15/50
1000/1000 [==============================] - 4s 4ms/step - loss: 0.7918 - accuracy: 0.7226 - val_loss: 0.9256 - val_accuracy: 0.6755
Epoch 16/50
 992/1000 [============================>.] - ETA: 0s - loss: 0.7764 - accuracy: 0.7290
Running privacy report for epoch: 16

1000/1000 [==============================] - 2s 2ms/step
200/200 [==============================] - 0s 2ms/step
1000/1000 [==============================] - 15s 15ms/step - loss: 0.7767 - accuracy: 0.7289 - val_loss: 0.9049 - val_accuracy: 0.6918
Epoch 17/50
1000/1000 [==============================] - 4s 4ms/step - loss: 0.7641 - accuracy: 0.7319 - val_loss: 0.8948 - val_accuracy: 0.6912
Epoch 18/50
 995/1000 [============================>.] - ETA: 0s - loss: 0.7492 - accuracy: 0.7375
Running privacy report for epoch: 18

1000/1000 [==============================] - 2s 2ms/step
200/200 [==============================] - 0s 2ms/step
1000/1000 [==============================] - 15s 15ms/step - loss: 0.7491 - accuracy: 0.7376 - val_loss: 0.9137 - val_accuracy: 0.6869
Epoch 19/50
1000/1000 [==============================] - 4s 4ms/step - loss: 0.7355 - accuracy: 0.7408 - val_loss: 0.9135 - val_accuracy: 0.6925
Epoch 20/50
1000/1000 [==============================] - ETA: 0s - loss: 0.7244 - accuracy: 0.7446
Running privacy report for epoch: 20

1000/1000 [==============================] - 2s 2ms/step
200/200 [==============================] - 0s 2ms/step
1000/1000 [==============================] - 15s 15ms/step - loss: 0.7244 - accuracy: 0.7446 - val_loss: 0.8999 - val_accuracy: 0.6939
Epoch 21/50
1000/1000 [==============================] - 4s 4ms/step - loss: 0.7151 - accuracy: 0.7481 - val_loss: 0.8747 - val_accuracy: 0.7005
Epoch 22/50
 994/1000 [============================>.] - ETA: 0s - loss: 0.7052 - accuracy: 0.7517
Running privacy report for epoch: 22

1000/1000 [==============================] - 2s 2ms/step
200/200 [==============================] - 0s 2ms/step
1000/1000 [==============================] - 14s 14ms/step - loss: 0.7052 - accuracy: 0.7516 - val_loss: 0.8885 - val_accuracy: 0.7000
Epoch 23/50
1000/1000 [==============================] - 4s 4ms/step - loss: 0.6931 - accuracy: 0.7567 - val_loss: 0.9097 - val_accuracy: 0.6938
Epoch 24/50
 989/1000 [============================>.] - ETA: 0s - loss: 0.6814 - accuracy: 0.7607
Running privacy report for epoch: 24

1000/1000 [==============================] - 2s 2ms/step
200/200 [==============================] - 0s 2ms/step
1000/1000 [==============================] - 15s 15ms/step - loss: 0.6811 - accuracy: 0.7610 - val_loss: 0.8943 - val_accuracy: 0.6993
Epoch 25/50
1000/1000 [==============================] - 4s 4ms/step - loss: 0.6714 - accuracy: 0.7632 - val_loss: 0.8890 - val_accuracy: 0.7035
Epoch 26/50
 997/1000 [============================>.] - ETA: 0s - loss: 0.6642 - accuracy: 0.7668
Running privacy report for epoch: 26

1000/1000 [==============================] - 2s 2ms/step
200/200 [==============================] - 0s 2ms/step
1000/1000 [==============================] - 15s 15ms/step - loss: 0.6646 - accuracy: 0.7666 - val_loss: 0.9099 - val_accuracy: 0.6980
Epoch 27/50
1000/1000 [==============================] - 4s 4ms/step - loss: 0.6565 - accuracy: 0.7684 - val_loss: 0.8960 - val_accuracy: 0.6985
Epoch 28/50
 995/1000 [============================>.] - ETA: 0s - loss: 0.6449 - accuracy: 0.7732
Running privacy report for epoch: 28

1000/1000 [==============================] - 2s 2ms/step
200/200 [==============================] - 0s 2ms/step
1000/1000 [==============================] - 15s 15ms/step - loss: 0.6454 - accuracy: 0.7730 - val_loss: 0.8840 - val_accuracy: 0.7085
Epoch 29/50
1000/1000 [==============================] - 4s 4ms/step - loss: 0.6335 - accuracy: 0.7760 - val_loss: 0.9173 - val_accuracy: 0.7002
Epoch 30/50
 992/1000 [============================>.] - ETA: 0s - loss: 0.6301 - accuracy: 0.7750
Running privacy report for epoch: 30

1000/1000 [==============================] - 2s 2ms/step
200/200 [==============================] - 0s 2ms/step
1000/1000 [==============================] - 15s 15ms/step - loss: 0.6301 - accuracy: 0.7751 - val_loss: 0.9078 - val_accuracy: 0.7052
Epoch 31/50
1000/1000 [==============================] - 4s 4ms/step - loss: 0.6269 - accuracy: 0.7796 - val_loss: 0.9157 - val_accuracy: 0.6988
Epoch 32/50
1000/1000 [==============================] - ETA: 0s - loss: 0.6137 - accuracy: 0.7823
Running privacy report for epoch: 32

1000/1000 [==============================] - 2s 2ms/step
200/200 [==============================] - 0s 2ms/step
1000/1000 [==============================] - 15s 15ms/step - loss: 0.6137 - accuracy: 0.7823 - val_loss: 0.9130 - val_accuracy: 0.7066
Epoch 33/50
1000/1000 [==============================] - 4s 4ms/step - loss: 0.6096 - accuracy: 0.7830 - val_loss: 0.9538 - val_accuracy: 0.6976
Epoch 34/50
 994/1000 [============================>.] - ETA: 0s - loss: 0.6064 - accuracy: 0.7847
Running privacy report for epoch: 34

1000/1000 [==============================] - 2s 2ms/step
200/200 [==============================] - 0s 2ms/step
1000/1000 [==============================] - 15s 15ms/step - loss: 0.6058 - accuracy: 0.7850 - val_loss: 0.9136 - val_accuracy: 0.7015
Epoch 35/50
1000/1000 [==============================] - 4s 4ms/step - loss: 0.5934 - accuracy: 0.7889 - val_loss: 0.9063 - val_accuracy: 0.7088
Epoch 36/50
 997/1000 [============================>.] - ETA: 0s - loss: 0.5897 - accuracy: 0.7905
Running privacy report for epoch: 36

1000/1000 [==============================] - 2s 2ms/step
200/200 [==============================] - 0s 2ms/step
1000/1000 [==============================] - 15s 15ms/step - loss: 0.5899 - accuracy: 0.7902 - val_loss: 0.9411 - val_accuracy: 0.7030
Epoch 37/50
1000/1000 [==============================] - 4s 4ms/step - loss: 0.5846 - accuracy: 0.7936 - val_loss: 0.9279 - val_accuracy: 0.7042
Epoch 38/50
 998/1000 [============================>.] - ETA: 0s - loss: 0.5761 - accuracy: 0.7957
Running privacy report for epoch: 38

1000/1000 [==============================] - 2s 2ms/step
200/200 [==============================] - 0s 2ms/step
1000/1000 [==============================] - 15s 15ms/step - loss: 0.5759 - accuracy: 0.7957 - val_loss: 0.9275 - val_accuracy: 0.7076
Epoch 39/50
1000/1000 [==============================] - 4s 4ms/step - loss: 0.5706 - accuracy: 0.7967 - val_loss: 0.9486 - val_accuracy: 0.7012
Epoch 40/50
 996/1000 [============================>.] - ETA: 0s - loss: 0.5669 - accuracy: 0.7992
Running privacy report for epoch: 40

1000/1000 [==============================] - 2s 2ms/step
200/200 [==============================] - 0s 2ms/step
1000/1000 [==============================] - 15s 15ms/step - loss: 0.5672 - accuracy: 0.7993 - val_loss: 0.9493 - val_accuracy: 0.7042
Epoch 41/50
1000/1000 [==============================] - 4s 4ms/step - loss: 0.5588 - accuracy: 0.8014 - val_loss: 0.9749 - val_accuracy: 0.6933
Epoch 42/50
 988/1000 [============================>.] - ETA: 0s - loss: 0.5540 - accuracy: 0.8039
Running privacy report for epoch: 42

1000/1000 [==============================] - 2s 2ms/step
200/200 [==============================] - 0s 2ms/step
1000/1000 [==============================] - 15s 15ms/step - loss: 0.5549 - accuracy: 0.8036 - val_loss: 0.9576 - val_accuracy: 0.6988
Epoch 43/50
1000/1000 [==============================] - 4s 4ms/step - loss: 0.5466 - accuracy: 0.8055 - val_loss: 0.9509 - val_accuracy: 0.7044
Epoch 44/50
 994/1000 [============================>.] - ETA: 0s - loss: 0.5431 - accuracy: 0.8072
Running privacy report for epoch: 44

1000/1000 [==============================] - 2s 2ms/step
200/200 [==============================] - 0s 2ms/step
1000/1000 [==============================] - 15s 15ms/step - loss: 0.5434 - accuracy: 0.8072 - val_loss: 1.0512 - val_accuracy: 0.6773
Epoch 45/50
1000/1000 [==============================] - 4s 4ms/step - loss: 0.5366 - accuracy: 0.8079 - val_loss: 0.9932 - val_accuracy: 0.6899
Epoch 46/50
 998/1000 [============================>.] - ETA: 0s - loss: 0.5370 - accuracy: 0.8087
Running privacy report for epoch: 46

1000/1000 [==============================] - 2s 2ms/step
200/200 [==============================] - 0s 2ms/step
1000/1000 [==============================] - 15s 15ms/step - loss: 0.5369 - accuracy: 0.8087 - val_loss: 0.9607 - val_accuracy: 0.7001
Epoch 47/50
1000/1000 [==============================] - 4s 4ms/step - loss: 0.5309 - accuracy: 0.8100 - val_loss: 0.9853 - val_accuracy: 0.6997
Epoch 48/50
 996/1000 [============================>.] - ETA: 0s - loss: 0.5265 - accuracy: 0.8124
Running privacy report for epoch: 48

1000/1000 [==============================] - 2s 2ms/step
200/200 [==============================] - 0s 2ms/step
1000/1000 [==============================] - 15s 15ms/step - loss: 0.5277 - accuracy: 0.8121 - val_loss: 1.0013 - val_accuracy: 0.6883
Epoch 49/50
1000/1000 [==============================] - 4s 4ms/step - loss: 0.5188 - accuracy: 0.8142 - val_loss: 0.9791 - val_accuracy: 0.7089
Epoch 50/50
 998/1000 [============================>.] - ETA: 0s - loss: 0.5156 - accuracy: 0.8151
Running privacy report for epoch: 50

1000/1000 [==============================] - 2s 2ms/step
200/200 [==============================] - 0s 2ms/step
1000/1000 [==============================] - 15s 15ms/step - loss: 0.5157 - accuracy: 0.8150 - val_loss: 0.9835 - val_accuracy: 0.7029

Epoch Plots

You can visualize how privacy risks happen as you train models by probing the model periodically (e.g. every 5 epochs), you can pick the point in time with the best performance / privacy trade-off.

Use the TF Privacy Membership Inference Attack module to generate AttackResults. These AttackResults get combined into an AttackResultsCollection. The TF Privacy Report is designed to analyze the provided AttackResultsCollection.

results = AttackResultsCollection(all_reports)
privacy_metrics = (PrivacyMetric.AUC, PrivacyMetric.ATTACKER_ADVANTAGE)
epoch_plot = privacy_report.plot_by_epochs(
    results, privacy_metrics=privacy_metrics)

png

See that as a rule, privacy vulnerability tends to increase as the number of epochs goes up. This is true across model variants as well as different attacker types.

Two layer models (with fewer convolutional layers) are generally more vulnerable than their three layer model counterparts.

Now let's see how model performance changes with respect to privacy risk.

Privacy vs Utility

privacy_metrics = (PrivacyMetric.AUC, PrivacyMetric.ATTACKER_ADVANTAGE)
utility_privacy_plot = privacy_report.plot_privacy_vs_accuracy(
    results, privacy_metrics=privacy_metrics)

for axis in utility_privacy_plot.axes:
  axis.set_xlabel('Validation accuracy')

png

Three layer models (perhaps due to too many parameters) only achieve a train accuracy of 0.85. The two layer models achieve roughly equal performance for that level of privacy risk but they continue to get better accuracy.

You can also see how the line for two layer models gets steeper. This means that additional marginal gains in train accuracy come at an expense of vast privacy vulnerabilities.

This is the end of the tutorial. Feel free to analyze your own results.