Python PyTorch:预期输入批次大小(12)与目标批次大小(64)匹配

Python PyTorch:预期输入批次大小(12)与目标批次大小(64)匹配,python,pycharm,pytorch,Python,Pycharm,Pytorch,我试用了PyTorch,想为MNIST编写一个程序。但是,我收到了错误消息: /home/michael/Programmierung/Python/PyTorch/venv/bin/python /home/michael/Programmierung/Python/PyTorch/mnist.py torch.Size([64, 20, 4, 4]) torch.Size([12, 10]) Traceback (most recent call last): File "/home/m

我试用了PyTorch,想为MNIST编写一个程序。但是,我收到了错误消息:

/home/michael/Programmierung/Python/PyTorch/venv/bin/python /home/michael/Programmierung/Python/PyTorch/mnist.py
torch.Size([64, 20, 4, 4])
torch.Size([12, 10])
Traceback (most recent call last):
  File "/home/michael/Programmierung/Python/PyTorch/mnist.py", line 69, in <module>
    train(epoch)
  File "/home/michael/Programmierung/Python/PyTorch/mnist.py", line 60, in train
    loss = criterion(out, target)
  File "/home/michael/Programmierung/Python/PyTorch/venv/lib/python3.6/site-packages/torch/nn/modules/module.py", line 493, in __call__
    result = self.forward(*input, **kwargs)
  File "/home/michael/Programmierung/Python/PyTorch/venv/lib/python3.6/site-packages/torch/nn/modules/loss.py", line 942, in forward
    ignore_index=self.ignore_index, reduction=self.reduction)
  File "/home/michael/Programmierung/Python/PyTorch/venv/lib/python3.6/site-packages/torch/nn/functional.py", line 2056, in cross_entropy
    return nll_loss(log_softmax(input, 1), target, weight, None, ignore_index, None, reduction)
  File "/home/michael/Programmierung/Python/PyTorch/venv/lib/python3.6/site-packages/torch/nn/functional.py", line 1869, in nll_loss
    .format(input.size(0), target.size(0)))
ValueError: Expected input batch_size (12) to match target batch_size (64).

Process finished with exit code 1
预期输入批次大小(12)与目标批次大小(64)匹配

我搜索了一个解决方案,但我不明白我的代码出了什么问题

#kwargs is empty because I don't use cuda
kwargs = {}
train_data = torch.utils.data.DataLoader(
    datasets.MNIST('data', train=True, download=True,
                    transform=transforms.Compose([transforms.ToTensor(),
                    transforms.Normalize((0.1307,),(0.3081,))])),
    batch_size=64, shuffle=True, **kwargs)

test_data = torch.utils.data.DataLoader(
    datasets.MNIST('data', train=False,
                    transform=transforms.Compose([transforms.ToTensor(),
                    transforms.Normalize((0.1307,),(0.3081,))])),
    batch_size=64, shuffle=True, **kwargs)

class Netz(nn.Module):
    def __init__(self):
        super(Netz, self).__init__()
        self.conv1 = nn.Conv2d(1,10, kernel_size=5)
        self.conv2 = nn.Conv2d(10, 20, kernel_size=5)
        self.conv_dropout = nn.Dropout2d()
        self.fc1 = nn.Linear(320, 60)
        self.fc2 = nn.Linear(60, 10)

    def forward(self, x):
        x = self.conv1(x)
        x = F.max_pool2d(x, 2)
        x = F.relu(x)
        x = self.conv2(x)
        x = self.conv_dropout(x)
        x = F.max_pool2d(x, 2)
        x = F.relu(x)
        print(x.shape)
        x = x.view(-1, 320)
        x = self.fc1(x)
        x = x.view(-1, 320)
        x = F.relu(self.fc1(x))
        x = self.fc2(x)
        return F.log_softmax(x, dim=0)

model = Netz()

optimizer = optim.SGD(model.parameters(), lr=0.1, momentum=0.8)
def train(epoch):
    model.train()

    for batch_id, (data, target) in enumerate(train_data):
        data = Variable(data)
        target = Variable(target)
        optimizer.zero_grad()
        out = model(data)
        print(out.shape)
        criterion = nn.CrossEntropyLoss()
        loss = criterion(out, target)
        loss.backward()
        optimizer.step()
        print('Train Epoch: {} [{}/{} ({:.0f}%)]\tLoss: {:.6f}'. format(
            epoch, batch_id * len(data), len(train_data.dataset),
            100. * batch_id / len(train_data), loss.data[0]))
输出应显示历元和一些其他信息。实际上,我打印出了张量的形状,但我不知道出了什么问题。以下是错误消息:

/home/michael/Programmierung/Python/PyTorch/venv/bin/python /home/michael/Programmierung/Python/PyTorch/mnist.py
torch.Size([64, 20, 4, 4])
torch.Size([12, 10])
Traceback (most recent call last):
  File "/home/michael/Programmierung/Python/PyTorch/mnist.py", line 69, in <module>
    train(epoch)
  File "/home/michael/Programmierung/Python/PyTorch/mnist.py", line 60, in train
    loss = criterion(out, target)
  File "/home/michael/Programmierung/Python/PyTorch/venv/lib/python3.6/site-packages/torch/nn/modules/module.py", line 493, in __call__
    result = self.forward(*input, **kwargs)
  File "/home/michael/Programmierung/Python/PyTorch/venv/lib/python3.6/site-packages/torch/nn/modules/loss.py", line 942, in forward
    ignore_index=self.ignore_index, reduction=self.reduction)
  File "/home/michael/Programmierung/Python/PyTorch/venv/lib/python3.6/site-packages/torch/nn/functional.py", line 2056, in cross_entropy
    return nll_loss(log_softmax(input, 1), target, weight, None, ignore_index, None, reduction)
  File "/home/michael/Programmierung/Python/PyTorch/venv/lib/python3.6/site-packages/torch/nn/functional.py", line 1869, in nll_loss
    .format(input.size(0), target.size(0)))
ValueError: Expected input batch_size (12) to match target batch_size (64).

Process finished with exit code 1
/home/michael/Programmierung/Python/pythorch/venv/bin/Python/home/michael/Programmierung/Python/pythorch/mnist.py
火炬尺寸([64,20,4,4])
火炬尺寸([12,10])
回溯(最近一次呼叫最后一次):
文件“/home/michael/Programmierung/Python/PyTorch/mnist.py”,第69行,在
列车(新纪元)
文件“/home/michael/Programmierung/Python/PyTorch/mnist.py”,第60行,列车中
损失=标准(输出、目标)
文件“/home/michael/Programmierung/pythor/venv/lib/python3.6/site packages/torch/nn/modules/module.py”,第493行,在调用中__
结果=自我转发(*输入,**kwargs)
文件“/home/michael/Programmierung/pythor/venv/lib/python3.6/site packages/torch/nn/modules/loss.py”,第942行,向前
忽略索引=自我。忽略索引,减少=自我。减少)
文件“/home/michael/Programmierung/Python/pythorch/venv/lib/python3.6/site packages/torch/nn/functional.py”,第2056行,交叉显示
返回nll_损失(log_softmax(输入,1),目标,重量,无,忽略索引,无,减少)
文件“/home/michael/Programmierung/Python/pythorch/venv/lib/python3.6/site packages/torch/nn/functional.py”,第1869行,nll_loss
.format(输入.size(0)、目标.size(0)))
ValueError:预期输入批次大小(12)与目标批次大小(64)匹配。
进程已完成,退出代码为1

发生错误的原因是您的模型输出,
out
具有形状
(12,10)
,而您的
目标
的长度为64

由于您使用的批大小为64,并且预测了10个类的概率,因此您希望模型输出的形状为
(64,10)
,因此
forward()
方法显然存在一些问题

逐行检查,并注意每一步的
x
大小,我们可以尝试找出哪里出了问题:

    ...
    # x.shape = (64, 20, 4, 4) at this point as seen in your print statement
    x = x.view(-1, 320)             # x.shape = (64, 320)
    x = self.fc1(x)                 # x.shape = (64, 60)
    x = x.view(-1, 320)             # x.shape = (12, 320)
    x = F.relu(self.fc1(x))         # x.shape = (12, 60)
    x = self.fc2(x)                 # x.shape = (12, 10)
    return F.log_softmax(x, dim=0)  # x.shape = (12, 10)
您实际上最可能想要的是:

    ...
    # x.shape = (64, 20, 4, 4) at this point as seen in your print statement
    x = x.view(-1, 320)             # x.shape = (64, 320)
    x = F.relu(self.fc1(x))         # x.shape = (64, 60)
    x = self.fc2(x)                 # x.shape = (64, 10)
    return F.log_softmax(x, dim=1)  # x.shape = (64, 10)
注意:虽然与错误无关,但也请注意,您希望softmax over
dim=1
,因为这是包含类登录的维度