本仓库包含一个用于量化深度神经网络隐私评估的研究代码库。它支持在常见的训练后量化(PTQ)和量化感知训练(QAT)设置下训练目标模型/影子模型,将中间攻击特征保存到磁盘,并运行一套与成员推理相关的攻击和指标(例如 MIA、RMIA、WhiteBoxMIA、WhiteBoxMIA_Partial)。该代码库还集成了基于 Opacus 的差分隐私训练路径,用于受防御的模型(例如所提供示例脚本中的 dropout / DP / 对抗变体)。
评估工作流分为两个阶段:(1) 训练(--training target|shadow|both)以生成 save/<attack_method>/... 产物,以及 (2) 仅攻击评估(--training None),该阶段加载已保存的后验/模型,并在 result/<attack_method>/... 下报告指标。
典型实验需要一台支持 NVIDIA GPU 的机器。我们推荐为 PyTorch 使用 CUDA 12.1 的 wheel 包(见下方命令)。请使用 Python 3.10,以匹配 requirements.txt 中固定的版本。
你可以使用以下命令安装大部分依赖:
conda create --name priv-qdnn python=3.10
conda activate priv-qdnn
pip install -r requirements.txt --extra-index-url https://download.pytorch.org/whl/cu121
说明:
pip install -r requirements.txt,不要加 --extra-index-url(如果您的平台有可用的 PyPI CPU wheel)。aimet-torch 安装(参见 quantization/PTQ/adaround.py)。如果 pip 无法在您的平台上解析 aimet-torch,请先按照 Qualcomm AIMET 安装说明操作,然后再安装其余依赖项。数据集不包含在此仓库中。支持四种数据集,它们的设置需求各不相同。
两者在首次使用时都会获取到 data/ 中,因此无需手动操作——只需确保首次运行实验时机器可以访问网络。
data/load_data.py 中的 torchvision.datasets.CIFAR100(..., download=True) 下载。data/cinic10.py 中的 fetch_cinic10() 从 Edinburgh DataShare 镜像下载并解压。它是一个大型归档文件,因此首次运行时请预留时间和磁盘空间。这两个数据集没有自动下载器。请获取原始归档文件,将它们解压到 data/<dataset>/raw/ 下,然后将其转换为加载器所需的 .npy 文件。
| 数据集 | 原始归档文件 |
|---|---|
| Texas100 | https://www.comp.nus.edu.sg/~reza/files/dataset_texas.tgz |
| Location | https://github.com/privacytrustlab/datasets(location 数据集) |
解压后的预期目录结构:
data/texas/raw/texas/100/feats
data/texas/raw/texas/100/labels
data/location/raw/bangkok
然后构建训练/测试划分:
python data/prepare_tabular.py --dataset both
--dataset 接受 texas、location 或 both。使用 --raw_root 指向其他位置(默认 data/<dataset>/raw),并使用 --test_size / --seed 更改划分(默认值 0.2 和 41)。
这会写入 data/tabular_datasets.py 加载的文件:
data/<dataset>/{train_feats,train_labels,test_feats,test_labels}.npy
如果这些 .npy 文件缺失,任何使用 --dataset_name texas 或 --dataset_name location 的运行都会因 FileNotFoundError 而失败,并指出缺失的路径。
attack:攻击实现与评估入口(MIA、RMIA、WhiteBox_MIA 等)。training:目标/影子训练循环以及带防御的训练变体(DP / 对抗分支、工具函数)。model:训练和攻击所使用的模型定义与封装。quantization:PTQ/QAT 量化流水线与辅助工具(包括 AIMET AdaRound 集成)。data:数据集下载辅助工具、准备脚本以及 PyTorch Dataset 封装。dp:DP 训练路径所使用的差分隐私工具。example:用于端到端实验的 shell 脚本(MIA 数据收集 + 仅攻击评估 / 防御)。experiment:论文分析背后的机理研究——LOOD 式记忆分数(memorization.py)以及梯度范数量化表(grad_norm_quantization_table.py、grad_norm_range_normalized_table.py)。plot:为论文生成图表和表格;输出的 PDF 和 CSV 文件位于 plot/figures/。main.py:统一的 CLI 入口(--training 在训练模式和仅攻击模式之间切换)。parameter_parser.py:所有命令行参数及其默认值。extract_last_layer_grad_norm.py:为成员和非成员子集计算最后一层分类器梯度的逐样本 L2 范数,供 experiment/ 中的表格复用。以下模式与仓库的预期工作流一致:使用 MIA 进行训练以填充 save/MIA/...,然后以 --training None 运行 MIA。
# Stage 1: train target + shadow and save MIA artifacts
python main.py \
--dataset_name cifar100 \
--net_name resnet18 \
--quantization hawq --a_bit 8 --w_bit 8 \
--attack_method MIA \
--training both \
--num_epochs 50 --trials 3 \
--device cuda:0
# Stage 2: attack-only MIA evaluation (confidence threshold attack only)
python main.py \
--dataset_name cifar100 \
--net_name resnet18 \
--quantization hawq --a_bit 8 --w_bit 8 \
--attack_method MIA \
--compleaknr_attacks confidence \
--training None \
--trials 3 \
--device cuda:0
对于每次攻击运行,控制台会打印对应攻击实现的进度(例如 MIA 的逐试验指标;仅攻击运行会保存到 result/MIA/...)。
--compleaknr_attacks 控制仅攻击的 MIA 条目:
confidence — 仅运行置信度阈值攻击。它只使用已保存的后验概率,因此速度快且不需要模型文件。all(该参数的默认值)— 运行全部六种黑盒变体:置信度阈值、熵阈值、修正熵、两种基于训练的攻击(对后验概率使用 LR/RF,以及对后验概率加标签使用 LR/RF),以及 SAMIA。请注意,这两种模式的要求不同。前五种变体只读取已保存的后验概率,但 SAMIA 还会加载已保存的目标模型和影子模型,从 save/MIA/.../target/<trial>/model.pth 和 save/MIA/.../shadow/0/model.pth 加载,并在扰动输入上查询它们以估计输出敏感度。这仍然属于黑盒,因为只使用模型输出——不使用梯度或内部激活——但它确实要求这些检查点存在,而且速度明显更慢。
如果省略 --compleaknr_attacks,则全部六种都会运行。如上所述,当你只想要快速路径或模型检查点不可用时,请显式传入 confidence。
你还可以通过以下方式复现更大规模的扫描:
bash example/MIA_cifar100_train.sh
bash example/MIA_cinic10_train.sh
bash example/defense/run_adv.sh
bash example/defense/run_dp.sh
bash example/defense/run_dropout.sh
bash example/RMIA.sh
编辑这些脚本中的设备 ID(cuda:*)和超参数,以适配你的集群。
以下是防御模型的最小示例,在仅攻击模式下使用 --compleaknr_attacks confidence。
# Dropout defense (resnet18_drop010): train target, then black-box confidence attack
python main.py --training target --attack_method MIA --dataset cifar100 --net_name resnet18_drop010 --quantization Original --a_bit 32 --w_bit 32 --trials 1 --device cuda:0
python main.py --attack_method MIA --compleaknr_attacks confidence --dataset_name cifar100 --net_name resnet18_drop010 --quantization Original --a_bit 32 --w_bit 32 --training None --trials 1 --device cuda:0
# DP defense (resnet18_dp, eps=5.0): train target, then black-box confidence attack
python main.py --training target --attack_method MIA --dataset cifar100 --net_name resnet18_dp --quantization Original --a_bit 32 --w_bit 32 --num_epochs 20 --batch_size 512 --eps 5.0 --trials 1 --device cuda:0
python main.py --attack_method MIA --compleaknr_attacks confidence --dataset cifar100 --net_name resnet18_dp --quantization Original --a_bit 32 --w_bit 32 --training None --eps 5.0 --trials 1 --device cuda:0
# Adversarial defense (resnet18_adversarial): train target, then black-box confidence attack
python main.py --training target --attack_method MIA --dataset cifar100 --net_name resnet18_adversarial --quantization Original --a_bit 32 --w_bit 32 --num_epochs 50 --trials 1 --device cuda:0
python main.py --attack_method MIA --compleaknr_attacks confidence --dataset cifar100 --net_name resnet18_adversarial --quantization Original --a_bit 32 --w_bit 32 --training None --trials 1 --device cuda:0
如需对量化方法和位宽进行全面扫描,请使用:
example/defense/run_dropout.sh、example/defense/run_dp.sh 和 example/defense/run_adv.sh。
本仓库提供两个白盒攻击入口:
WhiteBoxMIA:基于影子模型的白盒 MIA(在影子特征上训练攻击模型,在目标特征上评估)。WhiteBoxMIA_Partial:仅目标拆分模式(无需影子模型;将目标特征拆分为训练/测试集)。两者都从 save/MIA/... 加载已保存的模型,因此请在阶段 1 完成后运行它们:
# WhiteBoxMIA (shadow mode)
python main.py \
--dataset_name cifar100 \
--net_name resnet18 \
--quantization hawq --a_bit 8 --w_bit 8 \
--attack_method WhiteBoxMIA \
--training None \
--trials 3 \
--device cuda:0
# WhiteBoxMIA_Partial (target-only split mode)
python main.py \
--dataset_name cifar100 \
--net_name resnet18 \
--quantization hawq --a_bit 8 --w_bit 8 \
--attack_method WhiteBoxMIA_Partial \
--training None \
--trials 3 \
--device cuda:0
结果会写入 result/WhiteBoxMIA/... 和 result/WhiteBoxMIA_Partial/...。
上面的命令明确写出了大多数参数,而不是依赖默认值。在调整这些命令时,有几个默认值值得了解(完整列表见 parameter_parser.py):
| 参数 | 默认值 | 说明 |
|---|---|---|
--trials | 5 | 上面的示例使用 3 或 1 以缩短运行时间 |
--num_epochs | 50 | |
--batch_size | 256 | |
--optim / --lr | Adam / 0.001 | |
--random | 41 | 用于目标/影子数据划分的随机种子;在第 1 阶段和第 2 阶段之间必须保持一致 |
--compleaknr_attacks | all | 参见上一节 |
--dataset_name | cifar100 | --dataset 是可接受的别名 |