在Pytorch中如何处理小批量损失?

时间:2019-03-27 02:08:51

标签: pytorch loss

我将小批量数据输入模型中,我只想知道如何处理损失。我可以累积损失,然后像这样调用向后:

    ...
    def neg_log_likelihood(self, sentences, tags, length):
        self.batch_size = sentences.size(0)

        logits = self.__get_lstm_features(sentences, length)
        real_path_score = torch.zeros(1)
        total_score = torch.zeros(1)
        if USE_GPU:
            real_path_score = real_path_score.cuda()
            total_score = total_score.cuda()

        for logit, tag, leng in zip(logits, tags, length):
            logit = logit[:leng]
            tag = tag[:leng]
            real_path_score += self.real_path_score(logit, tag)
            total_score += self.total_score(logit, tag)
        return total_score - real_path_score
    ...
loss = model.neg_log_likelihood(sentences, tags, length)
loss.backward()
optimizer.step()

我想知道这种积累是否会导致梯度爆炸?

所以,我应该调用反向循环吗?

for sentence, tag , leng in zip(sentences, tags, length):
    loss = model.neg_log_likelihood(sentence, tag, leng)
    loss.backward()
    optimizer.step()

或者,像张量流中的 reduce_mean 一样使用平均损失

loss = reduce_mean(losses)
loss.backward()

2 个答案:

答案 0 :(得分:0)

必须使用小批量大小将loss减少mean。如果您查看原生的PyTorch损失函数,例如CrossEntropyLoss,则有一个单独的参数reduction用于此目的,默认行为是对小批量大小执行mean。 / p>

答案 1 :(得分:0)

我们通常

  1. 通过损失函数获得损失
  2. (如有必要)操纵损失,例如进行类加权等
  3. 计算小批量生产的平均损失
  4. 通过loss.backward()
  5. 计算梯度
  6. (如有必要)操作梯度,例如,对某些RNN模型进行梯度裁剪,以避免梯度爆炸
  7. 使用optimizer.step()函数更新权重

因此,在您的情况下,您可以首先获取微型批次的平均损失,然后使用loss.backward()函数计算梯度,然后使用optimizer.step()函数进行权重更新。