在 PyTorch 中执行 CrossEntropyLoss() 时出错

问题描述 投票:0回答:2

我的数据集包含形状为 [3,28,28] 的图像。我写了以下代码:

class ConvNet(nn.Module):
    def __init__(self):
        super(ConvNet, self).__init__()
        self.layer1 = nn.Sequential(nn.Conv2d(3, 28, kernel_size=5, stride=1, padding=2),nn.ReLU(),nn.MaxPool2d(kernel_size=2, stride=2))
        self.layer2 = nn.Sequential(nn.Conv2d(28, 56, kernel_size=5, stride=1, padding=2),nn.ReLU(),nn.MaxPool2d(kernel_size=2, stride=2))
        self.drop_out = nn.Dropout()
        self.fc1 = nn.Linear(7 * 7 * 56, 1000)
        self.fc2 = nn.Linear(1000, 10)
     

    def forward(self, x):
        out = self.layer1(x)
        out = self.layer2(out)
        out = out.reshape(out.size(0), -1)
        out = self.drop_out(out)
        out = self.fc1(out)
        out = self.fc2(out)
        return out

model = ConvNet()
criterion = nn.CrossEntropyLoss()
optimizer = torch.optim.Adam(model.parameters(), lr=learning_rate)
total_step = len(loader_train)

for e in range(num_epochs):
    print("Epoch ", e+1,": ")
    for i, (images, labels) in enumerate(loader_train):
        optimizer.zero_grad()
        actual_out = model(images)
        loss = criterion(actual_out, labels)
        loss.backward()
        optimizer.step()
 
        if (i+1) % 100 == 0:
            print ('Epoch [{}/{}], Step [{}/{}], Loss: {:.3f}' .format(e+1, num_epochs, i+1, total_step, loss.item()))     

但是,我收到以下错误:

AttributeError                            Traceback (most recent call last)
<ipython-input-149-8cab60dd5269> in <module>
      8         actual_out = model(images)
      9 
---> 10         loss = criterion(actual_out, labels)
     11         loss.backward()

AttributeError: 'tuple' object has no attribute 'size'

我通过以下方法将标签转换为张量:

target_out = torch.empty(batch_size,dtype=torch.long).random_(labels)
loss = criterion(actual_out, target_out)

但这会产生:

TypeError                                 Traceback (most recent call last)
<ipython-input-153-b45ba6d62808> in <module>
---> 11         target_out = torch.empty(batch_size,dtype=torch.long).random_(labels)
     12         loss = criterion(actual_out, target_out)
    
TypeError: random_() received an invalid combination of arguments - got (tuple), but expected one of:
 * (*, torch.Generator generator)
 * (int from, int to, *, torch.Generator generator)
 * (int to, *, torch.Generator generator)
neural-network pytorch conv-neural-network
2个回答
0
投票

您的

labels
对象是一个元组,您希望将其转换为 dtype long 的张量。

您可以通过以下方式执行此操作:

torch.tensor(labels, dtype=torch.long)

0
投票

假设这就是你的train_loader的结构,你可以在训练循环中而不是在forward()函数中重塑。我给出了一个例子,根据您的需要进行更改。

此外,在后退过程中,清除梯度,.to(设备)是可选的,如果你有 GPU

train_loader = torch.utils.data.DataLoader(dataset=train_dataset, 
                                               batch_size=batch_size, 
                                               shuffle=True)
    

    for epoch in range(num_epochs):
            for i, (images, labels) in enumerate(train_loader):  
                # origin shape: [100, 1, 28, 28]
                # resized: [100, 784]
                images = images.reshape(-1, 28*28).to(device)
                labels = labels.to(device)
                
                # Forward pass
                outputs = model(images)
                loss = criterion(outputs, labels)
                
                # Backward and optimize
                optimizer.zero_grad()
                loss.backward()
                optimizer.step()
© www.soinside.com 2019 - 2024. All rights reserved.