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



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

我会得到错误: 值错误:目标和输入必须具有相同数量的元素。目标元素 (1376( != 输入元素 (43(

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

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

在视图中使用-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)

最新更新