使用 TensorFlow Privacy 實作差分隱私

在 TensorFlow.org 上檢視 在 Google Colab 中執行 在 GitHub 上檢視原始碼 下載筆記本

總覽

差分隱私 (DP) 是一種用於衡量演算法所提供隱私權保證的架構。透過差分隱私的視角,您可以設計機器學習演算法,以負責任的方式在私人資料上訓練模型。使用差分隱私進行學習可提供可衡量的隱私權保證,有助於降低在機器學習中洩露敏感訓練資料的風險。直觀來說,以差分隱私訓練的模型不應受到資料集中任何單一訓練範例或一小組訓練範例的影響。這有助於降低在 ML 中洩露敏感訓練資料的風險。

這種方法 (稱為差分隱私隨機梯度下降法 (DP-SGD)) 的基本概念是修改隨機梯度下降法 (SGD) 中使用的梯度,而 SGD 是幾乎所有深度學習演算法的核心。以 DP-SGD 訓練的模型為其輸入資料提供可證明的差分隱私保證。對原始 SGD 演算法進行了兩項修改

  1. 首先,需要限制每個梯度的敏感度。換句話說,您需要限制在小批次中取樣的每個個別訓練點,對於梯度計算和套用至模型參數的結果更新的影響程度。這可以透過裁剪針對每個訓練點計算的每個梯度來完成。
  2. 隨機雜訊會被取樣並新增至裁剪後的梯度,使統計上不可能知道特定資料點是否包含在訓練資料集中,方法是比較 SGD 在訓練資料集中包含或不包含此特定資料點時套用的更新。

本教學課程使用 tf.keras 訓練卷積神經網路 (CNN),以使用 TensorFlow Privacy 程式庫提供的 DP-SGD 最佳化工具來辨識手寫數字。TensorFlow Privacy 提供的程式碼可包裝現有的 TensorFlow 最佳化工具,以建立實作 DP-SGD 的變體。

設定

首先匯入必要的程式庫

import tensorflow as tf
tf.compat.v1.disable_v2_behavior()

import numpy as np

tf.get_logger().setLevel('ERROR')
2022-12-12 10:43:10.411464: 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-12-12 10:43:10.411665: 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-12-12 10:43:10.411681: 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.
WARNING:tensorflow:From /tmpfs/src/tf_docs_env/lib/python3.9/site-packages/tensorflow/python/compat/v2_compat.py:107: disable_resource_variables (from tensorflow.python.ops.variable_scope) is deprecated and will be removed in a future version.
Instructions for updating:
non-resource variables are not supported in the long term

安裝 TensorFlow Privacy。

pip install tensorflow-privacy
import tensorflow_privacy

from tensorflow_privacy.privacy.analysis import compute_dp_sgd_privacy

載入並預先處理資料集

載入 MNIST 資料集,並準備資料以進行訓練。

train, test = tf.keras.datasets.mnist.load_data()
train_data, train_labels = train
test_data, test_labels = test

train_data = np.array(train_data, dtype=np.float32) / 255
test_data = np.array(test_data, dtype=np.float32) / 255

train_data = train_data.reshape(train_data.shape[0], 28, 28, 1)
test_data = test_data.reshape(test_data.shape[0], 28, 28, 1)

train_labels = np.array(train_labels, dtype=np.int32)
test_labels = np.array(test_labels, dtype=np.int32)

train_labels = tf.keras.utils.to_categorical(train_labels, num_classes=10)
test_labels = tf.keras.utils.to_categorical(test_labels, num_classes=10)

assert train_data.min() == 0.
assert train_data.max() == 1.
assert test_data.min() == 0.
assert test_data.max() == 1.
Downloading data from https://storage.googleapis.com/tensorflow/tf-keras-datasets/mnist.npz
11490434/11490434 [==============================] - 0s 0us/step

定義超參數

設定學習模型超參數值。

epochs = 3
batch_size = 250

DP-SGD 有三個隱私權專用超參數和一個現有的超參數,您必須調整

  1. l2_norm_clip (float) - 套用以更新模型參數的每個梯度的最大歐幾里得 (L2) 範數。此超參數用於限制最佳化工具對個別訓練點的敏感度。
  2. noise_multiplier (float) - 在訓練期間取樣並新增至梯度的雜訊量。一般而言,雜訊越多,隱私權越好 (通常但非必要,以降低公用性為代價)。
  3. microbatches (int) - 每個資料批次都會分割成稱為微批次的小單位。根據預設,每個微批次應包含單一訓練範例。這讓我們可以針對每個範例裁剪梯度,而不是在跨小批次平均梯度之後。這反過來減少了裁剪對梯度中訊號的 (負面) 影響,並通常最大化公用性。但是,可以透過增加微批次的大小以包含多個訓練範例來減少運算額外負荷。然後裁剪這些多個訓練範例的平均梯度。批次中使用的範例總數 (即梯度下降的一個步驟) 保持不變。微批次的數量應平均劃分批次大小。
  4. learning_rate (float) - 此超參數已存在於原始 SGD 中。學習率越高,每次更新就越重要。如果更新有雜訊 (例如,當新增雜訊相對於裁剪閾值較大時),較低的學習率可能有助於訓練程序收斂。

使用以下超參數值以獲得相當準確的模型 (95% 測試準確度)

l2_norm_clip = 1.5
noise_multiplier = 1.3
num_microbatches = 250
learning_rate = 0.25

if batch_size % num_microbatches != 0:
  raise ValueError('Batch size should be an integer multiple of the number of microbatches')

建構模型

將卷積神經網路定義為學習模型。

model = tf.keras.Sequential([
    tf.keras.layers.Conv2D(16, 8,
                           strides=2,
                           padding='same',
                           activation='relu',
                           input_shape=(28, 28, 1)),
    tf.keras.layers.MaxPool2D(2, 1),
    tf.keras.layers.Conv2D(32, 4,
                           strides=2,
                           padding='valid',
                           activation='relu'),
    tf.keras.layers.MaxPool2D(2, 1),
    tf.keras.layers.Flatten(),
    tf.keras.layers.Dense(32, activation='relu'),
    tf.keras.layers.Dense(10)
])

定義學習模型的最佳化工具和損失函數。計算每個範例的損失向量,而不是小批次的平均值,以支援對每個訓練點進行梯度操作。

optimizer = tensorflow_privacy.DPKerasSGDOptimizer(
    l2_norm_clip=l2_norm_clip,
    noise_multiplier=noise_multiplier,
    num_microbatches=num_microbatches,
    learning_rate=learning_rate)

loss = tf.keras.losses.CategoricalCrossentropy(
    from_logits=True, reduction=tf.losses.Reduction.NONE)

訓練模型

model.compile(optimizer=optimizer, loss=loss, metrics=['accuracy'])

model.fit(train_data, train_labels,
          epochs=epochs,
          validation_data=(test_data, test_labels),
          batch_size=batch_size)
Train on 60000 samples, validate on 10000 samples
Epoch 1/3
2022-12-12 10:43:20.126016: W tensorflow/c/c_api.cc:291] Operation '{name:'training/SGD/momentum/Assign' id:500 op device:{requested: '', assigned: ''} def:{ { {node training/SGD/momentum/Assign} } = AssignVariableOp[_has_manual_control_dependencies=true, dtype=DT_FLOAT, validate_shape=false](training/SGD/momentum, training/SGD/momentum/Initializer/initial_value)} }' was changed by setting attribute after it was run by a session. This mutation will have no effect, and will trigger an error in the future. Either don't modify nodes after running them or create a new session.
60000/60000 [==============================] - 78s 1ms/sample - loss: 1.0220 - acc: 0.6809 - val_loss: 0.5134 - val_acc: 0.8517
Epoch 2/3
/tmpfs/src/tf_docs_env/lib/python3.9/site-packages/keras/engine/training_v1.py:2333: UserWarning: `Model.state_updates` will be removed in a future version. This property should not be used in TensorFlow 2.0, as `updates` are applied automatically.
  updates = self.state_updates
2022-12-12 10:44:37.590033: W tensorflow/c/c_api.cc:291] Operation '{name:'loss/mul' id:157 op device:{requested: '', assigned: ''} def:{ { {node loss/mul} } = Mul[T=DT_FLOAT, _has_manual_control_dependencies=true](loss/mul/x, loss/dense_1_loss/weighted_loss/Mul)} }' was changed by setting attribute after it was run by a session. This mutation will have no effect, and will trigger an error in the future. Either don't modify nodes after running them or create a new session.
60000/60000 [==============================] - 75s 1ms/sample - loss: 0.4747 - acc: 0.8756 - val_loss: 0.4018 - val_acc: 0.9025
Epoch 3/3
60000/60000 [==============================] - 76s 1ms/sample - loss: 0.3969 - acc: 0.9075 - val_loss: 0.3698 - val_acc: 0.9160
<keras.callbacks.History at 0x7f2abb6b4fd0>

衡量差分隱私保證

執行隱私權分析,以衡量訓練演算法達成的 DP 保證。瞭解達成的 DP 等級,即可客觀比較兩個訓練執行,以判斷哪一個更具隱私權保護能力。在高層次上,隱私權分析衡量潛在的攻擊者透過觀察訓練程序的結果 (例如,模型更新和參數),可以多大程度地改進他們對任何個別訓練點屬性的猜測。

此保證有時稱為隱私權預算。較低的隱私權預算更嚴格地限制了攻擊者改進其猜測的能力。這確保了更強大的隱私權保證。直觀來說,這是因為單一訓練點更難影響學習結果:例如,ML 演算法無法記住訓練點中包含的資訊,並且保留了將此訓練點貢獻給資料集的個人的隱私權。

在本教學課程中,隱私權分析是在 Rényi 差分隱私 (RDP) 的架構中執行的,RDP 是基於 本文 的純 DP 的放寬,特別適合 DP-SGD。

使用兩個指標來表示 ML 演算法的 DP 保證

  1. Delta (\(\delta\)) - 限制隱私權保證不成立的機率。經驗法則是將其設定為小於訓練資料集大小的倒數。在本教學課程中,由於 MNIST 資料集有 60,000 個訓練點,因此設定為 10^-5
  2. Epsilon (\(\epsilon\)) - 這是隱私權預算。它透過限制包含 (或排除) 單一訓練點可能會使特定模型輸出的機率變化多少,來衡量隱私權保證的強度。 \(\epsilon\) 的值越小,表示隱私權保證越好。但是,\(\epsilon\) 值僅為上限,較大的值在實務上可能仍表示良好的隱私權。

Tensorflow Privacy 提供一個工具 compute_dp_sgd_privacy,用於在給定固定 \(\delta\) 值和訓練程序中的以下超參數的情況下,計算 \(\epsilon\) 的值

  1. 訓練資料中的點總數,n
  2. batch_size
  3. noise_multiplier
  4. 訓練的 epochs 數。
compute_dp_sgd_privacy.compute_dp_sgd_privacy(n=train_data.shape[0],
                                              batch_size=batch_size,
                                              noise_multiplier=noise_multiplier,
                                              epochs=epochs,
                                              delta=1e-5)
DP-SGD with sampling rate = 0.417% and noise_multiplier = 1.3 iterated over 720 steps satisfies differential privacy with eps = 0.563 and delta = 1e-05.
The optimal RDP order is 18.0.
(0.5631726490328062, 18.0)

該工具報告,對於上面選擇的超參數,訓練模型的 \(\epsilon\) 值為 1.18。

摘要

在本教學課程中,您瞭解了差分隱私 (DP),以及如何在現有的 ML 演算法中實作 DP 原則,以為訓練資料提供隱私權保證。尤其是,您瞭解了如何

  • 使用 TensorFlow Privacy 將現有的最佳化工具 (例如,SGD、Adam) 包裝到其差分隱私對應項中
  • 調整差分隱私機器學習引入的超參數
  • 使用 TensorFlow Privacy 中包含的分析工具衡量提供的隱私權保證