记 Pytorch 使用错误与排查

今天,调试深度学习网络代码时,遇到了两个错误,想着之前也遇见过,今天再遇见,要记下来,方便查错,也可以帮助别人,遇到这类错误的人可以有所借鉴,快速解决 Bug。

1. RuntimeError: Expected object of type torch.FloatTensor but found type torch.cuda.FloatTensor for argument

  • 分析

    这个错误的含义是需要传入一个 torch.FloatTensor,但是却给了一个 torch.cuda.FloatTensor。Pytorch 中的类型若需要使用 GPU 进行运算加速,就要用 *.cuda() 或者 *.to(device) 来转换。比如我有个模型为 model 和 Tensor 变量 x,如需要用 GPU 加速 modelx,就可以用 model.cuda()x.cuda(),而通过查看 model.weight.type()x.type(),就可以看到它们的类型。

    我在出现这个错误的地方,输出了 xmodel 参数的类型,发现 xtorch.cuda.FloatTensor,而 model 的参数是 torch.FloatTensor,二者不能直接运算。而我之前,明明就执行过 model.cuda(),为何偏偏没有生效呢?

    原来,我在定义模型的时候,用了Python 中的 list 类型来保存一组模块,而就是这一组模块没能转到 GPU 上。

  • 解决办法

    直接存储在 list 中的模块并不能成功用 GPU 加速,需要用 Pytorch自带的 ModuleList 容器再包装一下,之后,model.cuda()也就能起作用了。

    models = [torch.nn.Liner(10,10) for i in range(10)]
    models = torch.nn.ModuleList(models)
    

2. RuntimeError: Trying to backward through the graph a second time, but the buffers have already been freed. Specify retain_graph=True when calling backward the first time

  • 分析

    这个错误是因为在 Pytorch 中构建的计算图只能进行一次 backward() 操作,之后,计算图的内存空间就会被释放。而倘若有两个 loss 值,需要对这个网络部分共同更新参数,那第二次 backward() 时,就会出现这个运行时错误。

  • 解决办法

    办法也很简单粗暴,就是在第一次 backward 时加入参数 retain_graph=True,让计算图先保存一会儿,并不立即释放,进行完第二次 backward() 之后,再自行释放。缺点就是所占的显存变大了许多,尤其是我的网络模型比较深。在不换显卡的情况下,只能减小 batchsize 了。

    loss1.backward(retain_graph=True)
    loss2.backward()
    

3. 意外中断程序,显存未释放

使用 fuser -v /dev/nvidia* | awk '{print $2}'|xargs kill -9 命令,强杀进程。

你可能感兴趣的:(深度学习,python)