Pytorch ValueError:更改图像后,目标和输入必须具有相同数量的元素

时间:2020-06-05 15:15:59

标签: python resize pytorch reshape valueerror

我的代码可以正常工作,它可以从32个图像中提取一个Batchsize,大小为256 * 256,并且可以训练我的神经元网络。

class Netz(nn.Module):
def __init__(self):
    super(Netz,self).__init__()
    self.conv1 = nn.Conv2d(3, 6, kernel_size=5)
    self.conv2 = nn.Conv2d(6, 12, kernel_size=3)
    self.conv3 = nn.Conv2d(12, 18, kernel_size=3)
    self.conv4 = nn.Conv2d(18, 24, kernel_size=3)
    self.fc1 = nn.Linear(4704, 1000)
    self.fc2 = nn.Linear(1000, 350)
    self.fc3 = nn.Linear(350,43)


def forward (self,x):
    x = F.relu(F.max_pool2d(self.conv1(x), 2))
    x = F.relu(F.max_pool2d(self.conv2(x), 2))
    x = F.relu(F.max_pool2d(self.conv3(x), 2))
    x = F.relu(F.max_pool2d(self.conv4(x), 2))
    x = x.view(-1,4704)
    x = F.relu(self.fc1(x))
    x = F.relu(self.fc2(x))
    x = self.fc3(x)
    return torch.sigmoid(x)



    # Traningsalgorithmus
optimizer = optim.Adam(model.parameters(), lr=0.001)
def train(epoch):
    model.train()
    batch_id = 0
    for data, target in train_data_set:
        data = Variable(data)
        target = torch.Tensor(target)
        target = Variable(target)
        optimizer.zero_grad()
        out = model(data)
        criterion = F.binary_cross_entropy
        loss = criterion(out,target)
        loss.backward()
        optimizer.step()
        print ('Train Epoch: {} [{}/{} ({:.0f}%)]\tLoss: {:.6f}'.format(
            epoch, batch_id * len(data), len(train_data_set)*32,
                100. * batch_id / len(train_data_set), loss.item()))
        batch_id = batch_id + 1

当我将Image的大小更改为50 * 50时,我将代码Net更改为:

class Netz(nn.Module):
def __init__(self):
    super(Netz,self).__init__()
    self.conv1 = nn.Conv2d(3, 6, kernel_size=5)
    self.conv2 = nn.Conv2d(6, 12, kernel_size=3)
    self.conv3 = nn.Conv2d(12, 18, kernel_size=3)
    self.conv4 = nn.Conv2d(18, 24, kernel_size=3)
    self.fc1 = nn.Linear(768, 1000)
    self.fc2 = nn.Linear(1000, 350)
    self.fc3 = nn.Linear(350,43)


def forward (self,x):
    x = F.relu(F.max_pool2d(self.conv1(x), 2))
    x = F.relu(F.max_pool2d(self.conv2(x), 2))
    x = F.relu(F.max_pool2d(self.conv3(x), 2))
    x = F.relu(F.max_pool2d(self.conv4(x), 2))
    x = x.view(-1,768)
    x = F.relu(self.fc1(x))
    x = F.relu(self.fc2(x))
    x = self.fc3(x)
    return torch.sigmoid(x)

我要报错: ValueError:目标和输入必须具有相同数量的元素。目标元素(1376)!=输入元素(43)

到目前为止,我发现问题出在x = x.view(-1,768)之后,它返回了一个带有Torch.Size([1,768])的张量。当我使用图像尺寸256 * 256时,它返回带有torch.Size([32,4704])的张量,并且我没有收到错误。

有人知道我该如何解决我的问题?

1 个答案:

答案 0 :(得分:0)

在视图中使用self时要小心,因为它仅使用剩余的大小,并且如果不符合您的意图,您将不会立即知道它的行为不符合预期。您应特别避免使用-1作为批次尺寸,因为您可能会错误地更改批次大小,该大小不应更改,并且它们的数据应彼此独立。

给出一个大小为 [32,3,256,256] 的输入,卷积后的输出大小为 [32,24,14,14] ,可以如您在第一个版本中所预期的,将其展平为 [32,4704] 。将输入更改为大小 [32、3、50、50] 时,卷积后的输出大小为 [32、24、1、1] ,可以显然不会转换为大小 [32,768] ,因为将其展平会导致大小为 [32,24] 。鉴于-1,您错误地将批次合并为一个,创建了一个 [1,768] 的张量,如果您使用了不同的批次大小,它甚至将无法工作

第一个线性的正确输入大小应为24:

32 * 24 = 768

要捕获有关模型尺寸的任何错误,您可以在视图中不设置任何self.fc1 = nn.Linear(24, 1000) 的情况下设置实际尺寸,或者在批处理尺寸之后将其展平,而不是稍后进行损耗计算。视图或torch.flatten,因此如果线性图层中的尺寸不匹配,则会发生错误:

-1