【问题标题】:Why loss function always return zero after first epoch?为什么损失函数在第一个时期后总是返回零?
【发布时间】:2022-01-07 17:06:16
【问题描述】:

为什么损失函数在第一个 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]])

【问题讨论】:

  • 取决于labels 包含的内容。请提供minimal reproducible example
  • @GoodDeeds,标签是一个有 64 个元素的张量,每个标签的 ID。我在问题中添加了一个示例。
  • 我觉得loss应该是loss = loss_fn(outputs, torch.max(labels, 1)[0])
  • 那行得通@yakhyo!谢谢!
  • @jimmy,我更新了答案。我想我在评论中犯了一个小错误。

标签: python pytorch conv-neural-network


【解决方案1】:

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

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

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

torch.max() 返回一个命名元组(values, indices),其中值是 给定的input张量每一行的最大值 尺寸dim。而indices 是找到的每个最大值的索引位置(argmax)。

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

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

【讨论】:

  • 这将返回错误:IndexError: Dimension out of range (expected to be in range of [-1, 0], but got 1)。只需记住 labels 是每个标签的 ID。
  • 您的意思是loss = loss_fn(outputs, torch.max(labels, 1)[1]) 吗?
  • 不,应该是loss = loss_fn(torch.max(outputs, 1)[0], labels),再次编辑答案)
猜你喜欢
  • 2018-03-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-10-06
  • 2018-07-04
  • 1970-01-01
  • 2017-08-04
相关资源
最近更新 更多