在上一节中,我们使用联合学习训练了一个玩具模型。 为此,我们在模型上调用了.send()和.get(),将其发送到训练数据的位置,对其进行了更新,最后将其恢复。但是,在示例的最后,我们意识到我们需要进一步保护人们的隐私。也就是说,我们要在调用.get()之前对梯度进行平均。这样,我们将永远不会看到任何人的确切坡度(因此更好地保护了他们的隐私!!!)
FedAVG?
import torch
import syft as sy
hook = sy.TorchHook(torch)
bob = sy.VirtualWorker(hook, id='bob')
alice = sy.VirtualWorker(hook, id='alice')
# 这是本地张量
x = torch.tensor([1,2,3,4])
print(x)
x_ptr = x.send(bob)
print(x_ptr)
# 现在我们可以把 指 针 发 送 给Alice!!!
pointer_to_x_ptr = x_ptr.send(alice)
print(pointer_to_x_ptr)
结果:
发生了什么?
在之前的示例中我们创建了一个名为 x
的张量然后发送给了Bob,并在本地计算机创建了一个指针(x_ptr
)。
然后我们调用了 x_ptr.send(alice)
,它将指针发送给Alice。
注意,这里没有移动数据,而是将指针移动到了数据上。
# 如上所示,Bob仍然具有实际数据(数据始终以LocalTensor类型存储)。
print(bob._objects)
# 另一方面,Alice有x_ptr! (注意它是如何指向Bob的)
print(alice._objects)
# 我们可以用 .get() 获取 x_ptr 返回给 Alice
x_ptr = pointer_to_x_ptr.get()
print(x_ptr)
# 我们可以用 x_ptr 获取x返回给 Bob!
x = x_ptr.get()
print(x)
Pointer -> Pointer -> Data 对象上的运算
就像普通的指针一样,我们可以在这些张量上执行任何PyTorch操作。
#Pointer -> Pointer -> Data 对象上的运算
#就像普通的指针一样,我们可以在这些张量上执行任何PyTorch操作。
print(bob._objects)
print(alice._objects)
p2p2x = torch.tensor([1,2,3,4,5]).send(bob).send(alice)
y = p2p2x + p2p2x
print(bob._objects)
print(alice._objects)
print(y.get().get())
print(bob._objects)
print(alice._objects)
print(p2p2x.get().get())
print(bob._objects)
print(alice._objects)
指针嵌套?
3.2 - 指针链操作
因此,在上一节中,每当我们调用.send()或.get()操作时,它都会直接在本地计算机的张量上调用该操作。但是,如果您有一连串的指针,有时您希望在该链中“最后”指针上调用.get()或.send()之类的操作(例如,将数据直接从一个工作程序发送到另一个工作程序)。为此,您想使用专门为此隐私保护操作设计的功能。
my_pointer2pointer.move(another_worker)
# x is now a pointer to a pointer to the data which lives on Bob's machine
# x现在是指向数据的指针,存在Bob的机器上
x = torch.tensor([1,2,3,4,5]).send(bob)
print(' bob:', bob._objects)
print('alice:',alice._objects)
x = x.move(alice)
print(' bob:', bob._objects)
print('alice:',alice._objects)