为什么损失函数在第一个时期后总是 return 为零?

Why loss function always return zero after first epoch?

为什么损失函数在第一个 epoch 后总是打印零?

我怀疑是因为 loss = loss_fn(outputs, torch.max(labels, 1)[1])

但是如果我使用loss = loss_fn(outputs, labels),我会得到错误

RuntimeError: 0D or 1D target tensor expected, multi-target not supported

.

nepochs = 5

losses = np.zeros(nepochs)

loss_fn = nn.CrossEntropyLoss()

optimizer = optim.Adam(modell.parameters(), lr = 0.001)

for epoch in range(nepochs):

    running_loss = 0.0
    n = 0
    
    for data in train_loader:
        
        #single batch
        if(n == 1):
            break;
            
        inputs, labels = data
        
        optimizer.zero_grad()

        outputs = modell(inputs)
        
        #loss = loss_fn(outputs, labels)
        loss = loss_fn(outputs, torch.max(labels, 1)[1])
        loss.backward()
        optimizer.step()
    
        running_loss += loss.item()
        n += 1
       
    losses[epoch] = running_loss / n
    print(f"epoch: {epoch+1} loss: {losses[epoch] : .3f}")

型号是:

def __init__(self, labels=10):
    super(Classifier, self).__init__()
    self.fc = nn.Linear(3 * 64 * 64, labels)
    
def forward(self, x):
    out = x.reshape(x.size(0), -1) 
    out = self.fc (out)
    return out

有什么想法吗?

标签是 64 个元素的张量,如下所示:

tensor([[7],[1],[ 2],[3],[ 2],[9],[9],[8],[9],[8],[ 1],[7],[9],[2],[ 5],[1],[3],[3],[8],[3],[7],[1],[7],[9],[8],[ 8],[3],[7],[ 5],[ 1],[7],[3],[2],[1],[ 3],[3],[2],[0],[3],[4],[0],[7],[1],[ 8],[4],[1],[ 5],[ 3],[4],[3],[ 4],[8],[4],[1],[ 9],[7],[3],[ 2],[ 6],[4],[ 8],[3],[ 7],[3]])

通常损失计算是loss = loss_fn(outputs, labels),这里outputs如下:

_ , outputs = torch.max(model(input), 1)
or
outputs = torch.max(predictions, 1)[0]

通常的做法是修改 outputs 而不是 labels:

torch.max() returns a namedtuple (values, indices) where values is the maximum value of each row of the input tensor in the given dimension dim. And indices is the index location of each maximum value found (argmax).

在您的代码片段中,labels 不是标签的索引,因此当您计算损失时,函数应如下所示:

loss = loss_fn(torch.max(outputs, 1)[0], labels)