Pytorch顾名思义是torch移植到python的一个实现,标榜的是与numpy相似的操作与高效利用GPU计算资源。
本来已经加入Tensorflow阵营的我在tf的静态图构建和缓慢的gpu加速的夹击之下感到绝望,故尝试Pytorch会不会对代码进行加速以及利用更好的架构来优化代码。
Pytorch与其他框架最大的不同感觉是在于Pytorch构建的是动态的计算流图,据说在计算的时候可以动态改变图的架构而不用重新构建一个新的图。
为了快速上手Pytorch,我们先把MNIST例程放在首位,通过对例程的理解学习Pytorch。
Practice
source: https://github.com/pytorch/tutorials/blob/master/Deep%20Learning%20with%20PyTorch.ipynb
Hello MNIST
本节利用torch.nn创建一个MNIST的网络,创建网络的时候继承torch.nn.Module,定义一个forward函数。
当我们定义了一个forward函数之后backward函数同时自动定义了,可以使用autograd进行自动求导。
模型中可训练的参数可以用net.parameters()返回,定义在nn.Module中。
进行一次forward和backward:
计算梯度后需要利用optimizer进行更新:
定义与训练网络的基本要件的齐全了,那么写一个统一的文件来训练一下看看效果。
文档Note部分:
第一章 Autograd mechanics:
主要介绍的是关于Pytorch中变量(variable)的一些内容。
Excluding subgraphs from backward
重点一:requires_grad,如果有其中一个输入的variable带有这个flag,那么跟这个输入有关的所有输出(output)都自动带有这个flag。
因此可以利用这个flag来使得指定的变量不进行更新(比如当使用predtrain网络时不希望前面卷积层的参数进行更新):
Example:
以上代码中关于model.resnet18的参数都不会在optimizer中更新,但fc层中的参数会更新。
重点二:volatile,如果确定你的计算图中不需要计算梯度的话(不需要调用.backward()),可以设置volatile的flag使得Pytorch使用最高效的内存管理。只要有一个输入变量的volatile设为True,则与其有关的输出变量的volatile也为True。
How autograd encodes the history
每个Variable中都有.creator的属性,指向一个输出这个Variable的函数。每进行一个操作(operation),新的函数(Function)的实例的forward()方法被调用,该函数的输出的creator就会指向这个函数。
在Pytorch中,每次迭代都会重新构建一个graph,这就使得在运行过程中可以动态改变图的结构,而不需要在初始化时把所有有可能的路径都定义好。
第二章 CUDA semantics
torch.cuda会track当前使用的GPU,所有的CUDA tensors都会在该GPU上创建。可以利用torch.cuda.device进行GPU的选择。
Cross-GPU的操作一般不被允许,除非使用了copy_()操作