【问题标题】:Pytorch ValueError: Target and input must have the same number of elements after change Image sizePytorch ValueError:更改图像大小后目标和输入必须具有相同数量的元素
【发布时间】:2020-09-24 20:33:45
【问题描述】:

我有一个工作和平的代码,它从 32 个图像中获取一个 256*256 形状的 Batchsize,我可以训练我的神经元网络。

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 并像这样更改代码 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:目标和输入必须具有相同数量的元素。目标 nelement (1376) != 输入 nelement (43)

到目前为止,我认为问题出现在 x = x.view(-1,768) 之后,它返回一个带有 torch.Size ([1,768]) 的张量。当我使用图像大小 256*256 时,它会返回带有 torch.Size ([32,4704]) 的张量,但我没有收到错误消息。

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

【问题讨论】:

    标签: python resize pytorch reshape valueerror


    【解决方案1】:

    在视图中使用-1 时需要小心,因为它只使用剩余的大小,如果这与您的意图不符,您不会立即知道它的行为与预期不符。您应该特别避免将-1 用于批处理维度,因为您可能会错误地更改不应更改的批处理大小,并且它们的数据应该相互独立。

    给定一个大小为 [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)
    

    【讨论】:

    • 非常感谢。你可以解决我的问题:D。
    猜你喜欢
    • 2018-05-15
    • 2019-11-11
    • 2020-07-27
    • 1970-01-01
    • 2022-11-23
    • 1970-01-01
    • 2021-07-25
    • 2016-12-15
    • 2020-02-23
    相关资源
    最近更新 更多