针对生成模型的蒙特卡罗和重构成员推理攻击
原文题目: Monte Carlo and Reconstruction Membership Inference Attacks against Generative Models
原文链接: paper
代码链接: github
本文主要复现针对VAE的重构成员推理攻击。
1. 论文理解
VAE相关基础知识:B站: 李宏毅机器学习 (2017) P27 - P29
该重建攻击仅适用于VAE. 在训练阶段,重建的 D ( z ) D(z) D(z)如果与当前的训练数据 x x x相近, 则这种训练效果是被鼓励的. 这样, 我们就可以得到具有更高精度的VAE重建数据. 但是, 输出 D ( z ) D(z) D(z)是不确定的. D ( z ) D(z) D(z)依赖于从分布 N ( E μ ( x ) , E σ ( x ) ) N(E_\mu(x),E_\sigma(x)) N(Eμ(x),Eσ(x))(其中参数 x x x是编码器 E E E的输出)采样得到的隐变量 z z z. 于是我们重复这个过程 n n n次
f ^ r e c ( x ) = − 1 n ∑ i = 1 n ∣ ∣ D ( z i ) − x ∣ ∣ \hat{f}_{rec}(x) = -\frac{1}{n}\sum_{i=1}^{n}||D(z_i)-x|| f^rec(x)=−n1i=1∑n∣∣D(zi)−x∣∣
其中 z i ( i = 1 , … , n ) z_i(i=1,\dots,n) zi(i=1,…,n)采样自分布 N ( E μ ( x ) , E σ ( x ) ) N(E_\mu(x),E_\sigma(x)) N(Eμ(x),Eσ(x)). 上述公式被用作VAE的损失函数. 本工作的一个贡献是将这个函数用于成员推理攻击. f ^ r e c ( x ) \hat{f}_rec(x) f^rec(x)被用来作为成员推理攻击的判别函数 f ^ ( x ) \hat{f}(x) f^(x).
注意: 这个攻击的威胁模型是: 一个可以访问VAE模型的强敌手 A A A.
2. 攻击原理
从训练集和测试集中分别取出100张图片, 输入训练好的网络, 得到对应的重建图片 x ′ x' x′. 对重建的图片和原始图片做MSE, 得到200个MSE结果. 对这200个MSE结果从小到大排序(可以预知, 训练集图片对应的MSE较小, 应该排在前面; 测试集图片对应的MSE较大, 排在后面). 之后, 在排好顺序的200张图片中, 对后100张图片统计分别有多少张训练集图片和测试集图片. 这即为该成员推理攻击的准确率.
3. 代码理解
keras实现, VAE已训练好, 数据集: cifar10.
加载训练集trX和验证集vaX.
训练集:6000, 验证集:60000+10000-6000=74000
trX, vaX = load_cifar10_with_validation(0.1, True)
teX = vaX[44000:] # 30000
vaX = vaX[:44000] # 44000
随机取100个训练样本和验证样本.
trX_inds = np.arange(len(trX)) # 6000
np.random.shuffle(trX_inds)
trX_inds = trX_inds[0:100]
vaX_inds = np.arange(len(trX))
np.random.shuffle(vaX_inds)
vaX_inds = vaX_inds[0:100]
对验证集和训练集图片计算MSE, 并记录.
results_sample = np.zeros((len(vaX_inds),2))
for i in range(len(vaX_inds)):
# indicate that dataset is a sample
results_sample[i][0] = 0
# 取出验证集图片, 计算MSE
results_sample[i][1] = compute_avg_rec_error(vaX[vaX_inds][i], repeats)
results_train = np.zeros((len(trX_inds),2))
for i in range(len(trX_inds)):
# indicate that dataset is a training data set
results_train[i][0] = 1
# 取出训练集图片, 计算MSE
results_train[i][1] = compute_avg_rec_error(trX[trX_inds][i], repeats)
最后得出准确率.
# 将results_sample, results_train归总在一起
results = np.concatenate((results_sample, results_train))
# 排序后得到准确率
accuracy = 1 - results[results[:,1].argsort()][:,0][-len(results_train):].mean()
4. 注意事项
在代码实现里有repeat操作. 即对于同一张图片, 重复进行多次validation. 每次validation后都计算一个MSE, 最后对所有MSE取平均. 这样有利于减少噪声对准确率的影响.
def compute_avg_rec_error(x_sample, repeats, n=3):
x_repeated = np.repeat([x_sample],repeats,axis=0) # (30000, 32, 32, 3)
avg_dist = 0.0
for i in range(n):
avg_dist = avg_dist + vae.evaluate(x_repeated)
return avg_dist/n