【Pytorch坑点集合】

1. One of the differentiated Tensors appears to not have been used in the graph

出现原因:出现在使用autograd.grad(loss, x)手动求导时。出现原因一般是loss和x之间没有建立计算图关系,即loss不能由x经过计算得来,所以不能反向传播。
解决办法:检查loss的计算过程是不是用到了x。特别注意如果使用循环迭代计算loss,如Adversarial Training中的PGD,每次迭代的loss是不是用到了上次迭代的变量来计算,而如果你让loss只对此次迭代的中的变量求导就会报这个错。

2. RuntimeError: CUDA error: invalid configuration argument

出现原因:将空tensor传入模型前向传播也会报这个错。
如果在模型前向传播的时候报了这个错,网上有些地方说是因为对input的切片操作引起在gpu上内存不连续所致(如这篇),试图通过将model(x)改为model(x.contiguous())解决。虽然我也使用了对x切片的操作,但我这样搞并不能解决,后来发现是由于切片操作可能存在导致x为空tensor。将空tensor传入模型前向传播也会报这个错。
我的出错代码:

for c in range(self.num_classes):  #calculate loss class-wisely
	class_index = (y == torch.tensor(c)).nonzero().squeeze(1).cuda() #我的算法逻辑中,class_index可能为空tensor,一开始没想到
    # if len(class_index)>0: 加上判断index是否为0就不报错了
    worst_ce_loss_conditioned_on_y =F.cross_entropy(self.predict(transfered_x[class_index].contiguous()),
                                                                        y[class_index].cuda().contiguous(),
                                                                        reduction='mean')
    #改正之前,这句话会报错RuntimeError: CUDA error: invalid configuration argument
    ce_loss_conditioned_on_y = F.cross_entropy(self.predict(x[class_index].cuda().contiguous()),
                                                                y[class_index].cuda().contiguous(),
                                                                reduction='mean')
    consis_loss = consis_loss + torch.abs(worst_ce_loss_conditioned_on_y - ce_loss_conditioned_on_y)
3. 多次forward计算而不backward导致显存爆炸

如果多次进行forward计算,而不进行backward,那么前向传播时产生的中间结果会一直积累在gpu中。如果你前向计算时并不希望进行反向传播,那么可以采用如下方式:

output_features=torch.utils.checkpoint.checkpoint(model,x.cuda())

4. 使用transfrom.scale或nn.functional.interpolate时报错ValueError: size shape must match input shape. Input is 2D, size is 4

这是由于transfrom.scale和nn.functional.interpolate在进行图片放缩时,默认要求input必须是[bsz, c, h, w]四维,**且输出的目标必须是[h, w]二维!**如果这样写就会报错:

x=torch.rand(2,5,3,3)
y=torch.nn.functional.interpolate(input=x, size=(2,5,10,10),  mode='bilinear')

正确写法:

x=torch.rand(2,5,3,3)
y=torch.nn.functional.interpolate(input=x, size=(10,10),  mode='bilinear')

scale函数同理。

5. loss.backward时报错RuntimeError: element 0 of tensors does not require grad and does not have a grad_fn

这说明在准备反向传播时发现并没有变量计算了梯度以供反传。
就三种可能:①模型参数设置了requires_grad=False ②假设你希望更新非网络模型参数外的变量(该变量参与计算loss,我们想通过一个optimizer来自动优化该变量),那么有可能该变量设置了requires_grad=False ③你以为的参与loss计算的变量实际上没参与计算

对于第一种情况,可以通过查看模型参数的requires_grad来排查:

for name, param in model.named_parameters():
    print(f"{name} requires_grad: {param.requires_grad}")

另外,注意一下,设置model.eval()并不会导致requires_grad变为False。model.eval()只是将dropout设为0、不记录梯度等,并不会明确地将requires_grad变为False。同理,model.train()也并不会导致requires_grad变为True。

【关于这个bug有进一步讨论,见9】

6. RuntimeError: CUDA error: CUBLAS_STATUS_NOT_INITIALIZED when calling cublasCreate(handle)

可能是由于跑ipynb文件时由于前面的加载模型代码运行失败了(比如,一种常见的情况是:模型加载过一遍了,此时已经在gpu上了,但你又运行了一遍加载模型的代码,导致gpu爆炸,第二次加载模型失败),但是你直接跑了后面的用模型来前传的代码,就会报这个错。将notebook kernel restart一下,重新运行即可。

当然,也有可能是因为pytorch版本的问题,这个另说。

7. import pandas时:ImportError: /lib/x86_64-linux-gnu/libstdc++.so.6: version `GLIBCXX_3.4.29’ not found

一个很奇怪的bug,触发条件是在import pandas前面先import了torch相关的库,比如:

import torch
from torch.nn import functional as F
from torch.utils.data import DataLoader

import pandas

将torch相关库改到pandas后面import就没问题了。

8. RuntimeError: CUDA error: device-side assert triggered

错误信息:
RuntimeError: CUDA error: device-side assert triggered
CUDA kernel errors might be asynchronously reported at some other API call,so the stacktrace below might be incorrect.
For debugging consider passing CUDA_LAUNCH_BLOCKING=1.

原因: 越界

注意点: 有时报错不一定在越界的那一句!!!有可能是在越界的那句之后的某个语句报这个错。需要一点一点排查。

** 一种常见可能**:算cross_entropy loss时有label的id大于预测logit的类别数维度。

9. RuntimeError: element 0 of variables does not require grad and does not have a grad_fn

【关于这个bug的其他讨论,见5】

典型错误。说明计算loss时有个中间变量的requires_grad时False,大多是在反向传播时,即loss.backward()时出现。

可能的错误原因:
首先需要明确,只要前向计算时,**至少存在一个输入给网络的变量requires_grad为True(比如一个模型之外的想要被优化的权重矩阵),那么即使模型freeze了(模型参数requires_grad为False),此时loss也是可以backward的。**出现这个错误说明所有的输入以及网络参数都requires_grad=False了。

解决方案
逐条检查:

  1. 当网络参数被freeze时,假如一个输给网络的变量需要优化,那么它是不是requires_grad=True;
  2. 如果是在with torch.no_grad(): 环境下执行的,那么requires_grad自动为False。注意:with torch.no_grad(): 有可能会加在整个函数的定义开始处,作为一个装饰器出现,比较难以发现
  3. 【极其坑】torch.set_grad_enabled(False)这句话会导致全局自动设置requires_grad为False。在这种情况下,甚至会出现前一句你刚定义了一个w=tensor.randn(10, requires_grad=True),下一行打印w.requires_grad就是False,如果不知道这句话的话非常难debug。
10. ValueError: can’t optimize a non-leaf Tensor

non-leaf Tensor指计算的中间结果对应的变量,而非创建的tensor。如z=x*y,z就是non-leaf Tensor,而x和y时leaf-node。

如果确定z不是non-leaf node但还是报错,可能是由于使用了.to(device):

import torch
import torch.optim as optim
weights = torch.randn(10, requires_grad=True).to("cuda:0")
optimizer = optim.Adam([weights], lr=0.01) #报错

但如果改成

weights = torch.randn(10, requires_grad=True, device=device)

就不报错了。

11. RuntimeError: Trying to backward through the graph a second time (or directly access saved tensors after they have already been freed). Saved intermediate values of the graph are freed when you call .backward() or autograd.grad().

**错误原因:**在一次loss.backward之后计算图已经被释放,如果没有重新前传计算就再次loss.backward,就会报错。
解决方案:

loss.backward(retain_graph=True)
  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在Windows操作系统下,同样可以使用PyTorch进行深度学习相关的计算。以下是一些PyTorch的基本知识点: 1. 安装PyTorch:在Windows上安装PyTorch可以通过pip或conda包管理器进行。可以在PyTorch官方网站上找到相应的安装指南。 2. 张量(Tensors):PyTorch中的核心数据结构是张量,它类似于NumPy的多维数组。张量可以用来存储和操作数据。 3. 自动求导(Autograd):PyTorch通过自动求导技术,可以自动计算张量上的梯度。这使得在神经网络训练中的反向传播算法更加方便。 4. 神经网络模块(nn.Module):PyTorch提供了一个模块化的接口(nn.Module),用于构建神经网络模型。可以定义各种层、损失函数、优化器等。 5. 数据加载(Data Loading):PyTorch提供了一些工具,用于加载和预处理数据。可以使用内置的数据集类或自定义数据集类来加载和处理数据。 6. 训练模型:使用PyTorch可以定义训练循环,包括前向传播、计算损失、反向传播和参数更新等步骤。可以使用不同的优化器(如SGD、Adam等)来更新模型参数。 7. GPU加速:PyTorch支持在GPU上进行计算,可以使用CUDA来利用GPU进行并行计算,加速模型训练和推理。 这些是PyTorch的一些基本知识点,在实际应用中还有更多的功能和技术可以探索和学习。可以参考PyTorch的官方文档和示例代码来深入学习和使用PyTorch

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值