pytorch那些事(1)

笔记小汇总,详情参照https://pytorch-cn.readthedocs.io/zh/latest/notes/autograd/

1.从后向中排除子图

每个变量有requires_grad和volatile两个标志,允许从梯度计算中精细地排除子图

如果所有变量都不需要梯度,后向计算不在子图中执行,requires_grad可以冻结部分模型;volatile决定requires_grad为false,不需要更改模型的任何设置来用于inference,不会保存中间状态

2.自动求导编码历史信息

每个变量有一个.creator属性,指向把它作为输出的函数;每执行一个操作,一个表示它的新Function被实例化,forward()函数被调用,输出的Variable的创建者被设置为这个Function,通过跟踪从任何变量到叶节点的路径重建创建数据的操作序列并自动计算梯度;整个图在每次迭代时从头开始重新创建,故每次迭代时可改变图的整体形状和大小

3.Variable上In-place操作

限制原因:覆盖梯度计算所需的值;需要实现重写计算图,当许多变量引用相同存储且被修改输入的存储被其他Variable引用时,函数会抛出错误

4.In-place正确性检查

每个变量保留有version counter,每次递增;Function保存任何用于后向的tensor时会保存其包含变量的version counter;访问self.saved_tensors时被检查如果大于保存的值会引起错误

5.CUDA语义

torch.cuda记录当前选择的GPU,并分配所有CUDA张量在上面创建,使用torch.cuda.device更改所选设备

一旦张量被分配直接对其操作不考虑所选设备,默认不支持跨GPU操作,copy_()例外

例子:with torch.cuda.device(1)        torch.randn(2).cuda(2)

6.最佳实践

使用固定内存缓冲区——当副本来自固定内存时主机到GPU的复制速度快很多;CPU张量和存储开放了pin_memory()方法,返回对象副本,数据放在固定区域;可使用异步GPU副本,只传递额外的async=True参数到cuda()调用;pin_memory=True传递给构造参数可使DataLoader将batch返回到固定内存

使用nn.DataParallel替代multiprocessing——多数涉及批量输入和多个GPU的情况默认使用DataParallel来使用多个GPU

7.扩展PyTorch(如何扩展torch.nn, torch.autograd和使用C库编写自定义的C扩展)

添加新的Operation到autograd,Operation继承class Function;autograd使用Function计算结果和梯度,并编码operation的历史;【每个operation(function)需实现三个方法:(1)__init__(optional)——如果operation包含非Variable参数,将其作为__init__的参数传入operation中;(2)forward()——写执行此operation的代码,可有任意数量参数,参数只能是Variable,返回值既可以是Variable也可以是Variables的tuple;(3)backward()——梯度计算公式,参数个数和forward返回值个数一样,每个返回值对应输入值的梯度,如果operation的输入不需要梯度或不可导可返回None】

8.扩展torch.nn

nn包含两种接口——modules和它们的functional版本,建议扩展layer时使用modules,modules保存着参数和buffer;不需要参数则使用functional(激活函数,pooling,这些都不需要参数);增加一个module,因nn重度使用autograd,添加一个新module需实现一个用来执行计算和计算梯度的Function

例子:实现一个Linear module,之前已经实现一个Linear Function;需实现两个方法__init__(optional)和forward()用来实例化一个执行operation的Function,使用它执行operation

9.多进程最佳实践

torch.multiprocessing替代python的multiprocessing,支持完全相同操作但扩展了,以便通过multiprocessing.Queue发送的所有张量将其数据移动到共享内存中,且只会向其他进程发送一个句柄;当Variable发送到另一个进程时,Variable.data和Variable.grad.data都将被共享

10.共享CUDA张量

仅python3使用spawn或forkserver启动方法才支持在进程间共享CUDA张量,python2中multiprocessing只能使用fork创建子进程,且不被CUDA运行时所支持

避免和抵制死锁——死锁可能原因:后台线程;multiprocessing.Queue用于序列化,发送和接收对象的多个线程;可使用multiprocessing.queues.SimpleQueue

重用经过队列的缓冲区——每次将Tensor放入multiprocessing.Queue时,需将其移动到共享内存;如果已经被共享则为无效操作

异步多进程训练——torch.multiprocessing,可异步训练模型,参数可一直共享,也可以定期同步;建议使用multiprocessing.Queue来在进程间传递各种PyTorch对象

11.序列化语义

保存模型的方法——序列化和恢复模型(第一种只保存和加载模型参数torch.save:.state_dict(),torch.load:.load_state_dict;第二种保存和加载整个模型)




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值