首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >RuntimeError: input.size(-1)必须等于input_size。应为28,得到0

RuntimeError: input.size(-1)必须等于input_size。应为28,得到0
EN

Stack Overflow用户
提问于 2021-01-17 10:17:21
回答 1查看 512关注 0票数 0

下面是我使用Pysft编写的代码

代码语言:javascript
复制
class Arguments:
        def __init__(self):
            # self.cuda = False
            self.no_cuda = True
            self.seed = 1
            self.batch_size = 50
            self.test_batch_size = 1000
            self.epochs = 10
            self.lr = 0.01
            self.momentum = 0.5
            self.log_interval = 10

hook = sy.TorchHook(torch)  
bob = sy.VirtualWorker(hook, id="bob")  
alice = sy.VirtualWorker(hook, id="alice") 

这是我的LSTM模型,只使用pytorch就可以成功运行,但不能使用pysyft运行

代码语言:javascript
复制
 class Model(torch.nn.Module):
        def __init__(self):
            super(Model, self).__init__()
            self.rnn = torch.nn.RNN(input_size=28,
            hidden_size=16,
            num_layers=2,
            batch_first=True,
            bidirectional=True)
            self.fc = torch.nn.Linear(32, 10)
        def forward(self, x):
            print(np.shape(x))
            x = x.squeeze()
            x, _ = self.rnn(x)
            x = self.fc(x[:, -1, :])
            return x.view(-1, 10)

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) # <-- NEW: send the model to the right location
        data, target = data.to(device), target.to(device)
        # data, target = data.cuda(), target.cuda()
        optimizer.zero_grad() 
        output = model(data.to(device))
        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
            losses.append(loss.item())
            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()))

当我使用Pysyft运行我的LSTM模型时,如果我使用没有Pysyft的模型,会出现一个mistakes.But,它可以成功运行。我不知道如何解决它?

代码语言:javascript
复制
import torch
import matplotlib.pyplot as plt
from torchvision import datasets, transforms
import torch.nn.functional as F
import time
import numpy as np
import syft as sy

class Arguments:
    def __init__(self):
        self.cuda = False
        self.no_cuda = True
        self.seed = 1
        self.batch_size = 50
        self.test_batch_size = 1000
        self.epochs = 10
        self.lr = 0.01
        self.momentum = 0.5
        self.log_interval = 10

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 Model(torch.nn.Module):
    def __init__(self):
        super(Model, self).__init__()
        self.rnn = torch.nn.RNN(input_size=28,
        hidden_size=16,
        num_layers=2,
        batch_first=True,
        bidirectional=True)
        self.fc = torch.nn.Linear(32, 10)
    def forward(self, x):
        print(np.shape(x))
        x = x.squeeze()
        x, _ = self.rnn(x)
        x = self.fc(x[:, -1, :])
        return x.view(-1, 10)

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
        data, target = data.to(device), target.to(device)
        optimizer.zero_grad() 
        output = model(data.to(device))
        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
            losses.append(loss.item())
            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()))

if __name__ == '__main__':

    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 {}

    losses = []
    
    federated_train_loader = sy.FederatedDataLoader(
        datasets.MNIST('../data', 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('../data', train=False, transform=transforms.Compose([
            transforms.ToTensor(),
            transforms.Normalize((0.1307,), (0.3081,))
        ])),
        batch_size=args.test_batch_size, shuffle=True, **kwargs)
    model = Model().to(device)
    optimizer = torch.optim.Adam(model.parameters(), lr=args.lr)


    t = time.time()
    for epoch in range(1, args.epochs + 1):
        train(args, model, device, federated_train_loader, optimizer, epoch)

        test(args, model, device, test_loader)
    plt.plot(range(0,160),losses,marker='o')
    plt.xlabel("iterator")
    plt.ylabel("loss")
    plt.show()
    total_time = time.time() - t
    print(total_time)

下面是完整的代码

EN

回答 1

Stack Overflow用户

发布于 2021-01-18 13:53:49

代码语言:javascript
复制
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

hook = sy.TorchHook(torch)
bob =  sy.VirtualWorker(hook, id="bob")
alice =  sy.VirtualWorker(hook, id="alice")

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

args = Arguments()


use_cuda = not args.no_cuda and torch.cuda.is_available()
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('../data', train=True, download=True,
                   transform=transforms.Compose([
                       transforms.ToTensor(),
                       transforms.Normalize((0.1307,), (0.3081,))
                   ]))
    .federate((bob, alice)), 
    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,))
                   ])),
    batch_size=args.test_batch_size, shuffle=True, **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, 5, 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, 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)



model = Net()
model = model.to(device)  #pushing the model into available device.
optimizer = optim.SGD(model.parameters(), lr=0.01)


for epoch in range(1, args.epochs + 1):
    # Train the model
    model.train()
    for batch_idx, (data, target) in enumerate(federated_train_loader): # iterate through each worker's dataset
        
        model.send(data.location) #send the model to the right location ; data.location returns the worker name in which the data is present
        
        data, target = data.to(device), target.to(device) # pushing both the data and target labels onto the available device.
        
        optimizer.zero_grad() # 1) erase previous gradients (if they exist)
        output = model(data)  # 2) make a prediction
        loss = F.nll_loss(output, target)  # 3) calculate how much we missed
        loss.backward()  # 4) figure out which weights caused us to miss
        optimizer.step()  # 5) change those weights
        model.get()  # get the model back (with gradients)
        
        if batch_idx % args.log_interval == 0:
            loss = loss.get() #get the loss back
            print('Epoch: {} [Training: {:.0f}%]\tLoss: {:.6f}'.format(epoch, 100. * batch_idx / len(federated_train_loader), loss.item()))
    # Test the model
    model.eval()  
    test_loss = 0
    correct = 0
    with torch.no_grad():
      for data, target in test_loader:
        data, target = data.to(device), target.to(device) 
        output = model(data) # Getting a prediction

        test_loss += F.nll_loss(output, target, reduction='sum').item() #updating test loss
        pred = output.argmax(1, keepdim=True) # get the index of the max log-probability 

        correct += pred.eq(target.view_as(pred)).sum().item() #correct pred in the current test set.

    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)))

    torch.save(model.state_dict(), "mnist_cnn.pt")

我已经在torch 1.x和pysyft 0.2.5中测试了上面的代码,并且它工作正常。(但使用cnn模型)...只需在此处更改数据加载器和模型。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65756689

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档