Pytorch反向传播(loss.backward)报错原因及解决办法

报错信息

在程序中我的损失函数定义如下所示:

loss = nn.CrossEntropyLoss(reduction='none')

但在执行loss.backward()时出现了下面这条报错信息:

RuntimeError: grad can be implicitly created only for scalar outputs

原因分析

在定义损失函数loss时,我们设置了参数reduction='none',这导致我们计算出的loss是一个二维的张量,行数为batchsize的大小。

backward只有对标量输出时才会计算梯度,而无法对张量计算梯度。

解决办法

将张量转变成一个标量,比如我们可以对loss求和,然后用求和得到的标量再反向传播求各个参数的梯度,这样不会对结果造成影响。

1.loss.backward 👉 loss.sum().backward 或者 loss.backward 👉 loss.backward(torch.ones_like(loss))

上面这两个方法表示对loss求和后再进行反向传播,其中第一个方法比较好理解,第二方法中的torch.ones_like(loss)是传入的grad_tensors参数,表示创建了一个与loss同样大小的全1张量,另losstorch.ones_like(loss)点乘后再进行反向传播,也相当于对loss求和后再进行反向传播。

在这里插入图片描述

grad_tensors的作用其实可以简单地理解成在求梯度时的权重,因为可能不同值的梯度对结果影响程度不同,所以pytorch弄了个这种接口,而没有固定为全是1。

2.loss = nn.CrossEntropyLoss(reduction='none')👉 loss = nn.CrossEntropyLoss()

reduction 参数有三种选择:

  • elementwise_mean:为默认情况,表明对N个样本的loss进行求平均之后返回
  • sum:指对N个样本的loss求和
  • none:表示直接返回N个样本的loss

参考文档

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值