前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >PyTorch踩坑记

PyTorch踩坑记

作者头像
卡尔曼和玻尔兹曼谁曼
发布2019-01-22 09:47:56
5200
发布2019-01-22 09:47:56
举报

PyTorch踩坑记

前言

自己刚开始使用深度学习框架做事情的时候,选择了最容易入门的Keras。Keras是在其它深度学习框架(谷歌的TensorFlow,微软的CNTK以及Theano)的基础上,抽象了底层实现的差异,提供的更高层的API接口。说说Keras的好处吧!个人觉得Keras最吸引人的地方就是API接口的设计特别人性化,对于样本的训练,结果的测试都有一种使用传统机器学习库的感觉;函数式接口设计使得深度网络的时候特别容易,简直就像在玩乐高。如果有人想入门深度学习,我一定也会推荐Keras。

后来,我为什么转到PyTorch呢?因为PyTorch大部分框架是基于Python实现的(虽然底层也有C代码),PyTorch提供了很简单的接口使得tensor和NumPy中的ndarray互相转换,这样基于NumPy的各种库我们也可以直接拿来使用。当然,这不是最重要的。我选择PyTorch的原因是因为:第一,基于Python实现,而不是像其它库一样只是提供了一个Python的调用接口而已。这样对于深度框架的调试就特别容易,如果你使用TensorFlow或者Keras,底层的实现都是C/C++,无法很好地进行底层的调试;第二,PyTorch使用动态图,而TensorFlow这样的框架使用静态图。这就是说当你使用TensorFlow框架编译一个深度模型,模型就是固定的,不容易改变,而PyTorch的动态图提供了更多的灵活性,特别是对RNN网络。所以,我在PyTorch脱离了Beta版本(0.4)以后,我果断转到了PyTorch,开始了新的学习之旅。

下面记录的是我在使用PyTorch遇到的一些问题及其解决方案:

In-place operation

这个问题是在我设计一个残差网络(ResNet)的时候遇到的,报错如下:RuntimeError: one of the variables needed for gradient computation has been modified by an inplace operation.

我是参考了PyTorch官方的ResNet实现来设计我自己的网络的。其实,问题主要出在forward()函数中的out += residual这句代码。

我们首先来看一下+=这个操作符,这是一个原位操作符因为+=是对out张量直接进行的+操作,就是说执行完+=操作以后原来out指向的那个张量已经改变了。如果使用out = out + residual会有什么不同呢?这个操作是将outresidual相加,然后将结果赋值给out变量。在这个过程中原来out变量指向的那个张量并没有被修改。

那么问题来了,为什么PyTorch官方的实现中,使用+=的写法没有问题,而我自己代码中这样写就有问题了呢?这是因为官方的ResNet中forward()函数中进行相加赋值操作以后就是一个relu激活函数,而激活函数层不需要反向传播,所以是没问题的;而我自己设计的网络中后面还有别的层,所以就不能这样写了。

Input type and weight type should be the same

这个问题是我将代码移植到GPU上运行时遇到的问题,报错如下:RuntimeError: Input type (CUDAFloatTensor) and weight type (CPUFloatTensor) should be the same

有人可能说,这个简单!这是你的输入数据在GPU上,而模型参数不在GPU上,使用to()方法将模型复制到GPU上即可。非也,我这里说的不是个问题。当然,如果有人遇到这个错误了,第一要检查的是你是不是使用to()或者cuda()方法将模型搬运到GPU上去了。

我的代码已经使用to()将模型复制到GPU上去了,为什么还会有这个问题呢?通过两天的调试,我发现我的模型大部分参数是位于GPU上的,而模型中的一些层却在CPU上,所以导致了这个问题。

注:在调试程序的时候怎么查看模型是否在GPU上呢?使用如下函数可以进行测试:next(model.parameters()).is_cuda

我后来发现,是我在设计ResNet的时候使用了list存储我的残差层导致的。如果在定义模型的时候,使用普通的list存储的模型层,PyTorch提供的to()方法是不会将对应的层复制到GPU上去的。解决办法也很简单,使用torch.nn.ModuleList容器来存储就好了。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2018年07月25日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • PyTorch踩坑记
    • 前言
      • In-place operation
        • Input type and weight type should be the same
        相关产品与服务
        容器服务
        腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档