微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

在联合学习中如何选择“数据”和“目标”? PySyft

如何解决在联合学习中如何选择“数据”和“目标”? PySyft

我不明白如何在下面的函数train()中选择变量(数据,目标)。

def train(args,model,device,federated_train_loader,optimizer,epoch):
    model.train()
    for batch_idx,(data,target) in enumerate(federated_train_loader): # <-- Now it is a distributed dataset
        model.send(data.location) # <-- NEW: send the model to the right location`

我猜他们是2张量,代表数据集训练的2张随机图像,但是损失函数

loss = F.nll_loss(output,target)

是在与不同目标的每次互动中计算的吗?

我还有一个不同的问题:我用猫的图像训练网络,然后用汽车的图像对其进行测试,达到的准确度是97%。这怎么可能?是正确的值还是我做错了什么?

这是完整的代码

import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim
from torchvision import datasets,transforms

import syft as sy  # <-- NEW: import the Pysyft library
hook = sy.TorchHook(torch)  # <-- NEW: hook PyTorch ie add extra functionalities to support Federated Learning
bob = sy.VirtualWorker(hook,id="bob")  # <-- NEW: define remote worker bob
alice = sy.VirtualWorker(hook,id="alice")  # <-- NEW: and alice

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

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( # <-- this is Now a FederatedDataLoader
    datasets.MNIST("C:\\users...\\train",train=True,download=True,transform=transforms.Compose([
                       transforms.ToTensor(),transforms.normalize((0.1307,),(0.3081,))
                   ]))
    .federate((bob,alice)),# <-- NEW: we distribute the dataset across all the workers,it's Now a FederatedDataset
    batch_size=args.batch_size,shuffle=True,**kwargs)

test_loader = torch.utils.data.DataLoader(
    datasets.MNIST("C:\\Users...\\test",train=False,))
                   ])),batch_size=args.test_batch_size,**kwargs)


class Net(nn.Module):
    def __init__(self):
        super(Net,self).__init__()
        self.conv1 = nn.Conv2d(1,20,5,1)
        self.conv2 = nn.Conv2d(20,50,1)
        self.fc1 = nn.Linear(4*4*50,500)
        self.fc2 = nn.Linear(500,10)

    def forward(self,x):
        x = F.relu(self.conv1(x))
        x = F.max_pool2d(x,2,2)
        x = F.relu(self.conv2(x))
        x = F.max_pool2d(x,2)
        x = x.view(-1,4*4*50)
        x = F.relu(self.fc1(x))
        x = self.fc2(x)
        return F.log_softmax(x,dim=1)

def train(args,target) in enumerate(federated_train_loader): # <-- Now it is a distributed dataset
        model.send(data.location) # <-- NEW: send the model to the right 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() # <-- NEW: get the model back
        if batch_idx % args.log_interval == 0:
            loss = loss.get() # <-- NEW: get the loss back
            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,test_loader):
    model.eval()
    test_loss = 0
    correct = 0
    with torch.no_grad():
        for data,target in test_loader:
            data,target.to(device)
            output = model(data)
            test_loss += F.nll_loss(output,target,reduction='sum').item() # sum up batch loss
            pred = output.argmax(1,keepdim=True) # get the index of the max log-probability
            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) # Todo momentum is not supported at the moment

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

if (args.save_model):
    torch.save(model.state_dict(),"mnist_cnn.pt")   

解决方法

这样考虑。当您挂钩火炬时,您的所有火炬张量都将获得额外的功能 - .send().federate() 之类的方法以及 .location._objects 之类的属性。由于 VirtualWorker,您的数据和目标(曾经是火炬张量)变成了指向位于不同 .federate((bob,alice)) 对象中的张量的指针。

现在 data 和 target 有额外的属性,包括 .location,它将返回张量的位置 - data/target 由名为 data/target 的指针指向。

联邦学习将全局模型发送到此位置,如 model.send(data.location) 所示。

现在,model 是驻留在同一位置的指针,而 data 也是驻留在同一位置的指针。因此,当您将输出视为 output = model(data) 时,输出也将驻留在那里,而我们(中央服务器或换句话说,名为 'me' 的 VirtualWorker)将获得的是指向该输出的指针。>

现在,关于您对损失计算的疑问,由于输出和目标都位于同一位置,loss 的计算也将发生在那里。反向传播和步进也是如此。

最后,您可以看到 model.get(),这里是中央服务器使用名为 model 的指针拉取远程模型的地方。 (不过我不确定它是否应该是 model = model.get())。

因此,任何带有 .get() 的东西都将从该 worker 中拉出,并在我们的 python 语句中返回。另请注意,.get() 会在调用时将该对象从其位置移除。因此,如果您需要进一步使用 .copy().get()

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?