Pytorch ValueError: Target and input must have the same number of elements after change Image size

Pytorch ValueError: Target and input must have the same number of elements after change Image size

我有一个工作和平的代码,它从 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

当我将图像的大小更改为 50*50 并像这样更改代码网络时:

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) 之后 returns 一个带有 torch.Size ([1,768]) 的张量。当我使用 Image Size 256*256 它 returns Tensor 和 torch.Size ([32,4704]) 并且我没有得到错误。

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

在视图中使用 -1 时需要小心,因为它只使用剩余的大小,如果这不符合您的意图,您不会立即知道它没有表现正如预期的那样。 batch维度要特别避免-1,因为你可能会误改batch size,batch size不应该改变,而且他们的数据应该是相互独立的。

给定大小为 [32, 3, 256, 256] 的输入,卷积后的输出大小为 [32, 24, 14, 14] ,正如您在第一个版本中所预期的那样,可以将其展平为 [32, 4704]。当您将输入大小更改为 [32, 3, 50, 50] 时,卷积后的输出大小为 [32, 24, 1, 1],显然不能转换为大小 [32, 768],因为将其展平会导致大小为 [32, 24]。鉴于 32 * 24 = 768,您错误地将批次合并为一个,创建了一个大小为 [1, 768] 的张量,如果您使用了不同的批次大小,它就不会连工作都没有。

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

self.fc1 = nn.Linear(24, 1000)

要捕获模型中有关尺寸的任何错误,而不是稍后在损失计算中,您可以在视图中设置没有任何 -1 的实际大小,或者在批量大小之后将其展平,无论是视图还是torch.flatten,因此如果线性层中存在大小不匹配,则会发生错误:

# Reshape to [batch_size, 24]
x = x.view(x.size(0), 24)

# Flatten with view
x = x.view(x.size(0), -1)

# Flatten, starting from dimension 1 (after the batch dimension)
x = x.flatten(1)