Pytorch自定义nn模块转发函数中的参数过多

时间:2018-09-29 15:48:31

标签: python pytorch

我正在尝试在pytorch中制作一个神经网络,该神经网络的层数可变。我的问题是,显然我正在将某种可迭代的项目与多个项目传递给只能接受一个参数的线性层。我只是不明白为什么。

所以这是一些代码。首先,我创建了自己的模块,然后将其导入到笔记本中

import torch

class NNet(torch.nn.Module):
    def __init__(self, layer_shapes, activation_functions):
        super(NNet, self).__init__()
        assert len(layer_shapes) == len(activation_functions) + 1
        self.layer_shapes = layer_shapes
        self.activation_functions = activation_functions

        linear_functions = list()
        for i in range(len(self.layer_shapes)-1):
            linear_functions.append(torch.nn.Linear(
                    self.layer_shapes[i], self.layer_shapes[i+1]))

        self.linear_functions = linear_functions

    def parameters(self):
        parameters = list()
        for function in self.linear_functions:
            parameters = parameters+list(function.parameters())

        return parameters 

    def forward(self, x):
        assert x.shape[1] == self.layer_shapes[0]
        y = x
        for i in range(len(self.layer_shapes)-1):
            lin = self.linear_functions[i](y)
            y = self.activation_functions[i](lin)
        return y

在笔记本电脑中,错误出在forward的{​​{1}}函数中

现在,我尝试使用y = self.activation_functions[i](self.linear_functions[i](y))提供的MNIST数据集并使用自己的模块。

torchvision

最后一个for循环会产生错误:

batch_size = 100
epochs = 500
learning_rate = 0.001




train_set = torchvision.datasets.MNIST(root = 
                                       '../../data',
                                        train=True,
                          transform=torchvision.transforms.ToTensor(),
                                        download=True)

test_set = torchvision.datasets.MNIST(root = 
                                      '../../data',
                                      train=False,                                      
                          transform=torchvision.transforms.ToTensor(),
                                   download=True)

train_loader = torch.utils.data.DataLoader(dataset=train_set, 
                                           batch_size=batch_size, 
                                           shuffle=True)

test_loader = torch.utils.data.DataLoader(dataset=test_set, 
                                          batch_size=batch_size, 
                                          shuffle=False)

model = nnet.NNet([784, 16, 10], [torch.nn.Tanh, 
                                  torch.nn.Softmax(dim=1)])

loss_function = torch.nn.MSELoss()
optimizer = torch.optim.SGD(model.parameters(), lr=learning_rate)

loss_items = list()

for t in range(epochs):
    for i, (images, labels) in enumerate(train_loader):
        images = images.reshape(-1,28*28)

        outputs = model(images)
        loss = loss_function(outputs, labels)
        loss_items.append(loss.item())

        optimizer.zero_grad()
        loss.backward()
        optimizer.step()

我确定有人可以告诉我为什么会这样,但是有人可以给我一个有用的调试策略吗?我是pytorch的新手,我怀疑这将是我遇到的最后一个麻烦。因此,研究这些问题的策略将很有帮助。

我将不胜感激。

2 个答案:

答案 0 :(得分:0)

model的定义中,我忘记了torch.nn.Tanh类上的括号。应该是torch.nn.Tanh()

我一直认为这些是函数而不是类。我还有一些要解决的问题,但很高兴看到了。真令人沮丧我基本上是通过在代码中放置断言和打印语句来找到它的。

答案 1 :(得分:0)

您可能想使用Sequential class

import torch.nn as nn

class NNet(nn.Module):
    def __init__(self, idim, hdim, odim, depth):
        super().__init__()
        layers = [nn.Linear(idim, hdim)]
        layers += [nn.Linear(hdim, hdim)
                   for i in range(depth)]
        layers += [nn.Linear(hdim, odim)]
        self.net = nn.Sequential(*layers)

    def forward(self, x):
        return self.net(x)

这也照顾参数等等。