model.eval()和loss.backward(retain_graph = True)

1:model.eval()会固定网络的nn.BN层和nn.Dropout层,nn.BN层在train的时候针对每一个batch会计算一次均值方差,然后最后归纳整个训练集的均值方差,所以在test的时候就不能再让BN层的均值方差发生变化了。参考文章:(1条消息) Pytorch model.eval()的作用_嘿,兄弟,好久不见的博客-CSDN博客_model.eval()作用

2:loss.backward(retain_graph = True),首先,forward一次会建立一个计算图,正常backward()会释放掉forward()过程所建立的计算图。而在backward中指定retain_graph = True以后,则每次backward不会释放当次forward()产生的计算图,这样会导致内存中计算图越来越多,使得训练会越来越慢。

另外为了保证每次backward()之后,梯度不会积累,在backward之前一般会采取optmizer.zero_grad()的方法。

参考自:

为什么向后设置(retain_graph = True)会占用大量GPU内存?-python黑洞网 (pythonheidong.com)(1条消息) Pytorch中backward(retain_graph=True)的 retain_graph参数解释_今 晚 打 老 虎的博客-CSDN博客_retain_graph=true为什么向后设置(retain_graph = True)会占用大量GPU内存?-python黑洞网 (pythonheidong.com)

以下是针对MNIST数据集的DeepFool攻击代码和测试代码: ```python import torch import torch.nn as nn import torch.optim as optim import torchvision.datasets as datasets import torchvision.transforms as transforms import numpy as np class Net(nn.Module): def __init__(self): super(Net, self).__init__() self.conv1 = nn.Conv2d(1, 10, kernel_size=5) self.conv2 = nn.Conv2d(10, 20, kernel_size=5) self.fc1 = nn.Linear(320, 50) self.fc2 = nn.Linear(50, 10) def forward(self, x): x = nn.functional.relu(nn.functional.max_pool2d(self.conv1(x), 2)) x = nn.functional.relu(nn.functional.max_pool2d(self.conv2(x), 2)) x = x.view(-1, 320) x = nn.functional.relu(self.fc1(x)) x = self.fc2(x) return x def deepfool(net, image, num_classes=10, overshoot=0.02, max_iter=50): """ DeepFool算法的实现 """ image = image.unsqueeze(0).clone().detach().requires_grad_(True) f_image = net(image) I = f_image.argmax().item() w = torch.zeros_like(image) r = torch.zeros_like(image) for k in range(max_iter): pert = np.inf f_image = net(image) for i in range(num_classes): if i == I: continue # compute w^k_i and f^k_i net.zero_grad() f_i = f_image[0, i] f_i.backward(retain_graph=True) grad_i = image.grad.clone().detach() net.zero_grad() f_I = f_image[0, I] f_I.backward(retain_graph=True) grad_I = image.grad.clone().detach() w_i = grad_i - grad_I f_i = f_i - f_I # compute perturbation pert_i = abs(f_i) / w_i.norm() if pert_i < pert: pert = pert_i w = w_i # compute r^k+1 r = r + pert * w / w.norm() image = image + pert * w / w.norm() image = torch.clamp(image, 0, 1) return image.squeeze() if __name__ == '__main__': # 加载MNIST数据集 transform = transforms.Compose([ transforms.ToTensor(), transforms.Normalize((0.1307,), (0.3081,)) ]) testset = datasets.MNIST(root='./data', train=False, download=True, transform=transform) testloader = torch.utils.data.DataLoader(testset, batch_size=1, shuffle=True) # 加载神经网络 net = Net() net.load_state_dict(torch.load('mnist_cnn.pt', map_location=torch.device('cpu'))) net.eval() # 对抗性攻击 num_samples = 100 num_classes = 10 num_success = 0 for i, (image, label) in enumerate(testloader): if i == num_samples: break image = image.squeeze() label = label.item() adv_image = deepfool(net, image) # 测试攻击成功率 f_image = net(image.unsqueeze(0)).squeeze() f_adv_image = net(adv_image.unsqueeze(0)).squeeze() I = f_image.argmax().item() J = (f_adv_image - f_image).argmax().item() if I != J: num_success += 1 print('Sample %d, true label: %d, predicted label: %d, adversarial label: %d' % (i+1, label, I, J)) print('Success rate: %.2f%%' % (num_success / num_samples * 100)) ``` 在上面的代码中,我们首先加载了MNIST数据集和训练好的神经网络,然后定义了DeepFool算法的实现。对于每个测试样本,我们使用DeepFool算法生成对抗性样本,并计算攻击成功率。最终输出测试结果,其中包括每个样本的真实标签、神经网络的预测标签和攻击后的标签,以及整个测试集的攻击成功率。 需要注意的是,由于DeepFool算法需要对每个类别都进行一次梯度计算,因此攻击的时间会比较长。为了加速测试过程,可以将测试样本数量设置为较小的值。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值