如何处理 Pytorch 中的小批量损失?
Posted
技术标签:
【中文标题】如何处理 Pytorch 中的小批量损失?【英文标题】:How to deal with mini-batch loss in Pytorch? 【发布时间】:2019-08-17 12:29:47 【问题描述】:我将小批量数据提供给模型,我只想知道如何处理损失。我可以累积损失,然后像这样向后调用:
...
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()
不知道堆积会不会导致梯度爆炸?
那么,我应该在循环中调用backward吗:
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()
【问题讨论】:
【参考方案1】:loss
必须使用小批量大小减少mean
。如果您查看原生 PyTorch 损失函数,例如 CrossEntropyLoss,则有一个单独的参数 reduction
仅用于此目的,默认行为是在 mini-batch 大小上执行 mean
。
【讨论】:
【参考方案2】:我们通常
-
通过损失函数得到损失
(如有必要)操纵损失,例如做类加权等
计算小批量的平均损失
通过
loss.backward()
计算梯度
(如有必要)操纵梯度,例如,对某些 RNN 模型进行梯度裁剪以避免梯度爆炸
使用optimizer.step()
函数更新权重
因此,在您的情况下,您可以先获取小批量的平均损失,然后使用 loss.backward()
函数计算梯度,然后使用 optimizer.step()
函数进行权重更新。
【讨论】:
以上是关于如何处理 Pytorch 中的小批量损失?的主要内容,如果未能解决你的问题,请参考以下文章
Pytorch Dataloader 如何处理可变大小的数据?
KnockoutJS:我应该如何处理繁重的小部件初始化代码?