联邦学习-知乎demo修正

在知乎看到的pysyft demo,跑下来有很多bug,利用 gpt与bard 迭代修复后可以运行

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
import torch
import syft as sy
# 进行简单的联邦学习模型训练
from torch import nn
from torch import optim
from torchvision import datasets, transforms
import torch.nn.functional as F

hook = sy.TorchHook(torch)

Li = sy.VirtualWorker(hook, id='li')
Zhang = sy.VirtualWorker(hook, id='zhang')


class Arguments():
def __init__(self):
self.batch_size = 64
self.test_batch_size = 128
self.epochs = 3
self.lr = 0.01
self.momentum = 0.5
self.no_cuda = False
self.seed = 1
self.log_interval = 30
self.save_model = True


args = Arguments()
use_cuda = not args.no_cuda and torch.cuda.is_available()
torch.manual_seed(args.seed)
device = torch.device('cuda' if use_cuda else 'cpu')
kwargs = {'num_workers': 1, 'pin_memory': True} if use_cuda else {}

federated_train_loader = sy.FederatedDataLoader(
datasets.MNIST('../data', train=True, download=True, transform=transforms.Compose([transforms.ToTensor(),
transforms.Normalize((0.1307,),
(0.3081,))
])).federate((Li, Zhang)),
batch_size=args.batch_size, shuffle=True, **kwargs)

test_loader = torch.utils.data.DataLoader(
datasets.MNIST('../data', train=False, transform=transforms.Compose([
transforms.ToTensor(),
# transforms.Normalize((0.1307,), (0.3081, 1))
])),
batch_size=args.test_batch_size, shuffle=True, **kwargs)


class Net(nn.Module):
def __init__(self):
super(Net, self).__init__()
# Convolutional layers
self.conv1 = nn.Conv2d(1, 32, 5)
self.conv2 = nn.Conv2d(32, 64, 5)
# Max pooling layers
self.pool1 = nn.MaxPool2d(2, 2)
self.pool2 = nn.MaxPool2d(2, 2)
# Fully connected layers
self.fc1 = nn.Linear(1024, 512)
self.fc2 = nn.Linear(512, 10)
def forward(self, x):
# Convolutional layers
x = F.relu(self.conv1(x))
x = self.pool1(x)
x = F.relu(self.conv2(x))
x = self.pool2(x)
# Fully connected layers
x = x.view(-1, 1024)
x = F.relu(self.fc1(x))
x = self.fc2(x)
# Output layer
x = F.log_softmax(x, dim=1)
return x


def train(args, model, device, federated_train_loader, optimizer, epoch):
model.train()
for batch_idx, (data, target) in enumerate(federated_train_loader):
# 发送至工作机
model.send(data.location)
data, target = data.to(device), target.to(device)
optimizer.zero_grad()
output = model(data)
loss = F.nll_loss(output, target)
loss.backward()
optimizer.step()
# 获得工作机模型
model.get()
if batch_idx % args.log_interval == 0:
# 获得loss
loss = loss.get()
print('Train Epoch : {} [ {} / {} ({:.0f}%)] \tLoss: {:.6f}'.format(
epoch, batch_idx * args.batch_size, len(federated_train_loader) *
args.batch_size,
100. * batch_idx / len(federated_train_loader), loss.item()))


# 定义测试函数
def test(args, model, device, test_loader):
model.eval()
test_loss = 0
correct = 0
with torch.no_grad():
for data, target in test_loader:
dataset, target = data.to(device), target.to(device)
output = model(data)
test_loss += F.nll_loss(output, target, reduction='sum').item()
pred = output.argmax(1, keepdim=True)
correct += pred.eq(target.view_as(pred)).sum().item()
test_loss /= len(test_loader.dataset)
print('\nTest set : Average loss : {:.4f}, Accuracy: {}/{} ( {:.0f}%)\n'.format(
test_loss, correct, len(test_loader.dataset),
100. * correct / len(test_loader.dataset)))



# 开始训练
model = Net().to(device)
optimizer = optim.SGD(model.parameters(), lr=args.lr)

for epoch in range(1, args.epochs + 1):
train(args, model, device, federated_train_loader, optimizer, epoch)
test(args, model, device, test_loader)

# 保存模型
if (args.save_model):
torch.save(model.state_dict(), "mnist_cnn.pt")

引用:

Pysyft实战4 : https://zhuanlan.zhihu.com/p/392767943