目录

  • 1、DLG文献解析
    • 1.1 背景介绍
    • 1.2 算法描述
    • 1.3 实验结果
  • 2、iDLG文献解析
    • 2.1 算法描述
    • 2.2 实验结果
  • 3、代码(DLG和iDLG)

1、DLG文献解析

文献地址:
Deep Leakage From Gradients.pdf
iDLG Improved Deep Leakage from Gradients.pdf

1.1 背景介绍

现在分布式机器学习和联邦学习中普遍接受的一个做法是将数据梯度进行共享,多方数据通过共享的梯度信息进行联合建模,即在原始数据不出库的前提下进行建模。

这样的梯度信息是否是安全的呢?我们知道,梯度与标签和样本特征有关,那么意味着梯度其中包含着部分的标签信息和原始信息,所以联邦学习中的梯度信息是非常不安全的数据:

1、在集中式分布式训练中,一般不存储任何训练数据的参数服务器也能够窃取所有参与者的本地训练数据。

2、对于分散的分布式训练,情况变得更糟,因为任何参与者都可以窃取其邻居的私人训练数据。

作者做了这样一个工作:通过神经网络中的梯度信息去反推原始数据和标签。

1.2 算法描述

1、从梯度中逐个像素地窃取图像和逐个单词地窃取句子是可能的。我们关注标准的同步分布式训练:在每个步骤t,每个节点I从其自己的数据集中采样一个小批(xt,I,yt,I)来计算梯度:

2、梯度在N个服务器上求平均值,然后再更新权重:

3、当正常参与者使用其私有训练数据计算∇W以更新参数时,恶意攻击者更新其伪输入和标签以最小化梯度距离。当优化完成时,恶意用户能够从真实参与者那里窃取训练数据。

这里拿一张小猫图片进行示例,对于输入样本可以通过训练过的网络得到预测值和梯度。而在攻击模型中,将随机输入我们的输入x和标签向量,将模型迁移过来。然后我们将计算我们的梯度与原模型梯度大差值,通过反推更新输入样本和标签信息,以此进行迭代。

4、给定目标函数,我们通过最小化以下目标来获得训练数据

5、算法

1.3 实验结果

1、文献实验结果
分别在MNIST、CIFAR-100 SVHN和LFW的图像上显示深层渗漏的可视化图像。我们的算法完全恢复了四幅图像,而以前的工作只在具有干净背景的简单图像上成功。

2、复现结果
测试了MNIST和CIFAR100数据集,基本上可以恢复初始图像,但也存在恢复失败的例子。

2、iDLG文献解析

IDLG(Improved Deep Leakage from Gradients)是在DLG方法的基础上进行改进。我们发现共享梯度肯定会泄露ground-truth的标签。我们提出了一种简单而可靠的方法来从梯度中提取准确的数据。特别是,相对于DLG来说,我们的方法肯定能提取出真实的标签,因此我们将其命名为改进的DLG(iDLG)。

2.1 算法描述

1、对于分类情况,NN(神经网络)模型一般是用one-hot标签的交叉熵损失来训练的,它被定义为:

2、那么,每个输出的损失梯度为

对于概率范围是(0,1),当虚拟标签 i 与真实标签相同时,此时 gi 的值为负值,反之为正值。

3、然而,我们可能无法获得关于输出 y 的梯度,因为它们不包括在共享梯度 ∇W 中,后者是关于模型W的权重的导数。我们发现梯度向量 ∇W 关于连接到输出层第 i 个 Logit 的权重 W 可以写成:

当使用非负的激活函数时,例如ReLU和Sigmoid,∇ W 和 gi 的符号是相同的。因此,我们可以简单地识别出其对应的 ∇W 为负值的ground-truth标签。有了这个规则,我们就很容易从共享梯度∇W中识别出私有训练数据x的ground-truth标签c。

4、算法

2.2 实验结果

1、文献实验结果

2、实验复现结果
相对于DLG算法,IDLG的恢复效果更快更准确。这主要是因为iDLG对于标签的提取方法比DLG更好,产生的误差更小。

3、代码(DLG和iDLG)

源代码:https://github.com/PatrickZH/Improved-Deep-Leakage-from-Gradients
改进代码含有个人的详细解释,适合初学者阅读。

import time
import os
import numpy as np
import matplotlib.pyplot as plt
import torch
import torch.nn as nn
from torch.utils.data import Dataset
from torchvision import datasets, transforms
import pickle
import PIL.Image as Imageclass LeNet(nn.Module):def __init__(self, channel=3, hideen=768, num_classes=10):  # hidden是神经网络最后一层全连接层的维度super(LeNet, self).__init__()act = nn.Sigmoidself.body = nn.Sequential(nn.Conv2d(channel, 12, kernel_size=5, padding=5 // 2, stride=2),  # 输入张量大小,输出张量大小,卷积核的大小,填充,步长act(),nn.Conv2d(12, 12, kernel_size=5, padding=5 // 2, stride=2),act(),nn.Conv2d(12, 12, kernel_size=5, padding=5 // 2, stride=1),act(),)self.fc = nn.Sequential(nn.Linear(hideen, num_classes) # 全连接层)# 前向传播def forward(self, x):out = self.body(x)out = out.view(out.size(0), -1)out = self.fc(out)return outdef weights_init(m):try:# hasattr()函数 用于判断对象是否包含对应的属性。if hasattr(m, "weight"):# 使用均匀分布U(a,b)初始化Tensor,即Tensor的填充值是等概率的范围为 [a,b) 的值。均值为 (a + b)/ 2.m.weight.data.uniform_(-0.5, 0.5)except Exception:print('warning: failed in weights_init for %s.weight' % m._get_name())try:if hasattr(m, "bias"):m.bias.data.uniform_(-0.5, 0.5)except Exception:print('warning: failed in weights_init for %s.bias' % m._get_name())class Dataset_from_Image(Dataset):def __init__(self, imgs, labs, transform=None):self.imgs = imgs # img pathsself.labs = labs # labs is ndarrayself.transform = transformdel imgs, labsdef __len__(self):return self.labs.shape[0]def __getitem__(self, idx):lab = self.labs[idx]img = Image.open(self.imgs[idx])if img.mode != 'RGB':img = img.convert('RGB')img = self.transform(img)return img, labdef lfw_dataset(lfw_path, shape_img):images_all = []labels_all = []folders = os.listdir(lfw_path)for foldidx, fold in enumerate(folders):files = os.listdir(os.path.join(lfw_path, fold))for f in files:if len(f) > 4 and f[-4:] == '.jpg':images_all.append(os.path.join(lfw_path, fold, f))labels_all.append(foldidx)transform = transforms.Compose([transforms.Resize(size=shape_img)])dst = Dataset_from_Image(images_all, np.asarray(labels_all, dtype=int), transform=transform)return dstdef main():dataset = 'MNIST'root_path = '.'data_path = os.path.join(root_path, './data/MNIST').replace('\\', '/')save_path = os.path.join(root_path, './results/iDLG_%s'%dataset).replace('\\', '/')lr = 1.0num_dummy = 1Iteration = 300num_exp = 1000use_cuda = torch.cuda.is_available()device = 'cuda' if use_cuda else 'cpu'tt = transforms.Compose([transforms.ToTensor()])tp = transforms.Compose([transforms.ToPILImage()])print(dataset, 'root_path:', root_path)print(dataset, 'data_path:', data_path)print(dataset, 'save_path:', save_path)if not os.path.exists('results'):os.mkdir('results')if not os.path.exists(save_path):os.mkdir(save_path)''' load data '''if dataset == 'MNIST':shape_img = (28, 28)num_classes = 10channel = 1hidden = 588dst = datasets.MNIST(data_path, download=True)elif dataset == 'cifar100':shape_img = (32, 32)num_classes = 100channel = 3hidden = 768dst = datasets.CIFAR100(data_path, download=True)elif dataset == 'lfw':shape_img = (32, 32)num_classes = 5749channel = 3hidden = 768lfw_path = os.path.join(root_path, './data/lfw')dst = lfw_dataset(lfw_path, shape_img)# dst = lfw_dataset(data_path, shape_img)else:exit('unknown dataset')''' train DLG and iDLG '''for idx_net in range(num_exp):net = LeNet(channel=channel, hideen=hidden, num_classes=num_classes)net.apply(weights_init)print('running %d|%d experiment'%(idx_net, num_exp))net = net.to(device)idx_shuffle = np.random.permutation(len(dst))for method in ['DLG', 'iDLG']:print('%s, Try to generate %d images' % (method, num_dummy))criterion = nn.CrossEntropyLoss().to(device)  # 计算交叉熵损失函数imidx_list = []for imidx in range(num_dummy):idx = idx_shuffle[imidx]imidx_list.append(idx)tmp_datum = tt(dst[idx][0]).float().to(device)tmp_datum = tmp_datum.view(1, *tmp_datum.size())tmp_label = torch.Tensor([dst[idx][1]]).long().to(device)tmp_label = tmp_label.view(1, )if imidx == 0:gt_data = tmp_datumgt_label = tmp_labelelse:gt_data = torch.cat((gt_data, tmp_datum), dim=0)  # tensor拼接gt_label = torch.cat((gt_label, tmp_label), dim=0)# compute original gradientout = net(gt_data)y = criterion(out, gt_label)  # 计算lossdy_dx = torch.autograd.grad(y, net.parameters())  # 通过自动求微分得到真实梯度# 这一步是一个列表推导式,先从dy_dx这个Tensor中一步一步取元素出来,对原有的tensor进行克隆, 放在一个list中# https://blog.csdn.net/Answer3664/article/details/104417013original_dy_dx = list((_.detach().clone() for _ in dy_dx))# generate dummy data and labeldummy_data = torch.randn(gt_data.size()).to(device).requires_grad_(True)   # 初始化虚拟参数dummy_label = torch.randn((gt_data.shape[0], num_classes)).to(device).requires_grad_(True)if method == 'DLG':# LBFGS具有收敛速度快、内存开销少等优点???optimizer = torch.optim.LBFGS([dummy_data, dummy_label], lr=lr)  # 设置优化器为拟牛顿法elif method == 'iDLG':optimizer = torch.optim.LBFGS([dummy_data, ], lr=lr)# predict the ground-truth labellabel_pred = torch.argmin(torch.sum(original_dy_dx[-2], dim=-1), dim=-1).detach().reshape((1,)).requires_grad_(False)history = []history_iters = []losses = []mses = []train_iters = []print('lr =', lr)for iters in range(Iteration):def closure():# 清空过往梯度optimizer.zero_grad()pred = net(dummy_data)if method == 'DLG':# 将假的预测进行softmax归一化,转换为概率dummy_loss = - torch.mean(torch.sum(torch.softmax(dummy_label, -1) * torch.log(torch.softmax(pred, -1)), dim=-1))# dummy_loss = criterion(pred, gt_label)elif method == 'iDLG':dummy_loss = criterion(pred, label_pred)dummy_dy_dx = torch.autograd.grad(dummy_loss, net.parameters(), create_graph=True)grad_diff = 0for gx, gy in zip(dummy_dy_dx, original_dy_dx):grad_diff += ((gx - gy) ** 2).sum()grad_diff.backward()return grad_diffoptimizer.step(closure)current_loss = closure().item()train_iters.append(iters)losses.append(current_loss)mses.append(torch.mean((dummy_data-gt_data)**2).item())if iters % int(Iteration / 30) == 0:current_time = str(time.strftime("[%Y-%m-%d %H:%M:%S]", time.localtime()))print(current_time, iters, 'loss = %.8f, mse = %.8f' %(current_loss, mses[-1]))history.append([tp(dummy_data[imidx].cpu()) for imidx in range(num_dummy)])history_iters.append(iters)for imidx in range(num_dummy):plt.figure(figsize=(12, 8))plt.subplot(3, 10, 1)# plt.imshow(tp(gt_data[imidx].cpu()))# 得到灰度图像plt.imshow(tp(gt_data[imidx].cpu()), cmap='gray')plt.title('Truth image')for i in range(min(len(history), 29)):plt.subplot(3, 10, i + 2)plt.imshow(history[i][imidx], cmap='gray')  # 这一行是显示灰度图片的意思, 如果不是mnist数据集,将这一行改为如下# plt.imshow(history[i][imidx])plt.title('iter=%d' % (history_iters[i]))plt.axis('off')if method == 'DLG':plt.savefig('%s/DLG_on_%s_%05d.png' % (save_path, imidx_list, imidx_list[imidx]))plt.close()elif method == 'iDLG':plt.savefig('%s/iDLG_on_%s_%05d.png' % (save_path, imidx_list, imidx_list[imidx]))plt.close()if current_loss < 0.000001:  # 收敛阈值breakif method == 'DLG':loss_DLG = losseslabel_DLG = torch.argmax(dummy_label, dim=-1).detach().item()mse_DLG = mseselif method == 'iDLG':loss_iDLG = losseslabel_iDLG = label_pred.item()mse_iDLG = msesprint('imidx_list:', imidx_list)print('loss_DLG:', loss_DLG[-1], 'loss_iDLG:', loss_iDLG[-1])print('mse_DLG:', mse_DLG[-1], 'mse_iDLG:', mse_iDLG[-1])print('gt_label:', gt_label.detach().cpu().data.numpy(), 'lab_DLG:', label_DLG, 'lab_iDLG:', label_iDLG)print('----------------------\n\n')if __name__ == '__main__':main()

Deep Leakage From Gradients文献阅读及代码重现相关推荐

  1. 论文阅读:Deep Leakage From Gradients

    论文名字 Deep Leakage From Gradients 来源 顶会 NeurIPS 年份 2019.12 作者 Ligeng Zhu  Zhijian Liu  Song Han 核心点 主 ...

  2. 复现《Deep Leakage from Gradients》的攻击实验

    复现<Deep Leakage from Gradients>的攻击实验 Deep Leakage from Gradients 在GitHub上找到一个在pytorch实现<Dee ...

  3. Deep leakage from Gradients论文解析

    Deep leakage from Gradients论文解析 今天来给大家介绍下2019年NIPS上发表的一篇通过梯度进行原始数据恢复的论文. 论文传送门 **问题背景:**现在分布式机器学习和联邦 ...

  4. Deep Leakage from Gradients

    Summary 对于分布式学习,特别是相关之前共享梯度的学习,提出了一种攻击方式(DLG).通过窃取client之间传递的梯度反推出(也是使用机器学习迭代的方式)原始的输入.并在图像分类.Masked ...

  5. 谣言检测文献阅读四—Reply-Aided Detection of Misinformation via Bayesian Deep Learning

    系列文章目录 谣言检测文献阅读一-A Review on Rumour Prediction and Veracity Assessment in Online Social Network 谣言检测 ...

  6. 谣言检测文献阅读二—Earlier detection of rumors in online social networks using certainty‑factor‑based convolu

    系列文章目录 谣言检测文献阅读一-A Review on Rumour Prediction and Veracity Assessment in Online Social Network 谣言检测 ...

  7. 谣言检测文献阅读三—The Future of False Information Detection on Social Media:New Perspectives and Trends

    系列文章目录 谣言检测文献阅读一-A Review on Rumour Prediction and Veracity Assessment in Online Social Network 谣言检测 ...

  8. 谣言检测文献阅读六—Tracing Fake-News Footprints: Characterizing Social Media Messages by How They Propagate

    系列文章目录 谣言检测文献阅读一-A Review on Rumour Prediction and Veracity Assessment in Online Social Network 谣言检测 ...

  9. 文献阅读总结:计算机视觉

    本文是对计算机视觉 (Computer Vision, CV) 领域已读文献的归纳总结,长期更新. 更多文献阅读总结,见: 文献阅读总结合集 对应论文在网上都有免费版本可以下载,若个别朋友在网上找不到 ...

最新文章

  1. 任务栏窗口和状态图标的闪动 z
  2. Android平台如何实现屏幕数据采集并推送至RTMP服务器
  3. Python机器学习:评价分类结果008多分类问题中的混淆矩阵
  4. 优秀网页案例教你如何排好内容页
  5. python如何把二进制转文本_在python3中如何把文本转换为二进制
  6. Rabbitmq+Nginx+keepalived高可用热备
  7. 【转】ubuntu 12.04 /sbin/ldconfig.real: /usr/local/lib/*.so.8 不是符号连接 解决办法
  8. Linux 压缩与解压缩工具之zip
  9. 阶段5 3.微服务项目【学成在线】_day01 搭建环境 CMS服务端开发_04-项目概述-技术栈和开发步骤...
  10. 面向公交营运管理的车路协同应用场景研究
  11. 【短视频音乐解析源码】在线解析抖音短视频音乐BGM源码+解析后自动播放mp3
  12. 中国钢铁物流行业发展策略分析及投资建议咨询报告2021-2027年
  13. 【SEU程序设计课笔记】 Mooc - Chapter 6 - (EX) - 泰勒展开求sin(x)/计算PI的近似值
  14. 2020年chx的计算机保研之路系列(5)——夏令营面试问题及感想杂谈
  15. 1. Linux系统简介
  16. OBS直播时编码器、码率控制器、分辨率帧率是什么以及如何向第三方推流
  17. 【word基础操作】如何在word中为公式编号
  18. Google Adsense西联快汇收款流程
  19. 国产电脑支持Linux吗,天玥计算机(电脑)支持UOS、银河麒麟、Deepin等国产操作系统...
  20. 聊一聊前端性能优化 CRP

热门文章

  1. 章鱼网络社区治理的4种方式
  2. 抖音直播提升人气,如何让抖音直播间人多
  3. 修改U盘显示图标,制定个性化服务
  4. MCE | Hippo 途径与靶向策略
  5. 开心网kaixin001 com外挂免费下载
  6. logback-spring.xml模板LOG_HOME说明
  7. latex中页眉怎么去掉_[转载]在latex中如何去除或设置目录\tableofcontents中的页眉问...
  8. 神经网络的整个过程包括,神经网络的实现过程
  9. 麒麟V10系统-如何获取软件商店下载的安装包
  10. 南京邮电大学计算机自杀,南京邮电大学一研究生跳楼自杀:毕业论文不过关