学习记录总结专栏:机器学习:PyTorch框架-个人学习总结(专栏)
https://blog.csdn.net/spiderb/category_12838886.html
1 前言
在之前的学习记录中,学习了张量的一系列操作,而深度学习就是对张量进行了一系列操作。随着操作种类和数量的增多,其实会导致各种各样想不到的问题,比如我们多个操作之间,该并行还是顺序执行,如何协同不同底层设备。以及如何避免各种冗余的操作等等,以上的问题都会影响我们的运算效率,甚至会引入Bug。
而计算图的概念就是为了解决上述问题的而设计的。而在之前的【机器学习:pytorch框架(4)--张量操作和创建,实现一元线性回归】中,我们实现了一元线性回归。在这个线性方程中,W和b是需要计算的参数,而X和Y由训练数据提供。
对实现一元线性回归的自动微分过程描述:训练开始时我们随机初始化W和b,当输入X训练数据后,可以通过WX+b这样的线性方程计算出一个Y*值。Y*值和真正的Y值存在明显的误差,因为随机初始化W和b,所以可以用Y*和Y计算出一个损失值Loss。根据该损失值对W和b计算偏导数,而偏导数正好可以表示W和b对误差的贡献程度,因此可以使用计算出来的偏导数更新权重参数W和b,使它们向着误差减小的方向靠近。经过几次迭代之后,W和b就被更新到足够能拟合数据的程度,这时停止迭代。此时我们的模型就学习到了Y=WX+b的权重参数,而在该过程中,PyTorch自动微分系统自动完成了偏导数的计算。
在PyTorch中,为了能够支持有向无环图(Directed Acyclic Graph,DAG)的构建和反向传播的链式法则,引入了一种特殊的数据结构,这个数据结构正是Tensor。
2 pytorch计算图的理解
而计算图是用来描述运算的有向无环图(DAG),有两个主要元素:节点(Node)和边(Edge)。其中,节点表示数据,如:向量,矩阵,张量;边表示运算,如:加、减、乘、除、卷积等。
例如, y=sin(a×x+b)×x 的计算图,在计算图中所有的输入表示叶子节点,而输出则是根节点。当计算拓扑沿着有向无环图进行计算得出output后,通过output计算出损失值,由链式法则可以将梯度传回叶子节点,从而更新权重参数。
在PyTorch的底层实现中,除了输入、输出,所有的节点都是一个Function对象。在这个对象中实现了从in到out的计算逻辑,并且可以通过apply()执行。从输入到输出的前向传播过程中,自动微分系统一边执行前向计算,一边搭建graph计算图,而图的节点是用于计算梯度的函数,这些函数保存在Tensor的.grad_fn中。当反向传播时,会用Tensor中记录的.grad_fn来计算相应的梯度。有向无环图的计算拓扑图如下图所示,该拓扑图展示了方程式 sin(a×x+b)×x 的计算过程,计算节点为Function对象,图中的*表示乘号。

从下到上执行
3 计算图的代码实操
下面,我们创建一个简单的实例并结合代码进行深入的理解。对下面的等式进行研究:
y=(x+w)×(w+1) ,其中,假设叶子节点: x=2,w=1 ,那么根节点: y=6
3.1 使用计算图表示

梯度的计算是需要依据设定的叶子节点的值进行计算的
3.2 具体代码实现
import torch
w = torch.tensor([1.], requires_grad=True)
x = torch.tensor([2.], requires_grad=True)
a = torch.add(w,x)
a.retain_grad() # 非叶子节点手动保存梯度值,在反向传播之前调用
b = torch.add(w,1)
y = torch.mul(a,b)
y.backward() # 梯度反向传播
print('求导结果:',w.grad)
# 查看叶子结点(非叶子节点,计算过程中梯度值会被释放掉,节省内存)
print("is leaf:\n",w.is_leaf, x.is_leaf, a.is_leaf, b.is_leaf, y.is_leaf)
# 查看梯度(导数结果)
print("gradient:\n",w.grad, x.grad, a.grad, b.grad, y.grad)
# grad_fn--记录创建该张量时所用的计算方法,即记录边(Edge)的信息,梯度反向传播时会用到
# 查看 grad_fn,用户创建的输入叶子结点是会打印None
print("grad fn:\n", w.grad_fn, x.grad_fn, a.grad_fn, b.grad_fn, y.grad_fn)
#输出结果及说明
求导结果: tensor([5.]) # 这与手动计算的结果是一致的
is leaf:
True True False False False
gradient:
tensor([5.]) tensor([2.]) tensor([2.]) None None
grad fn:
None None <AddBackward0 ‘加法’> <AddBackward0 ‘加法’> <MulBackward0 ‘乘法’>
4 动态图和静态图
我们常常听说pytorch采用的是动态图机制,而tensorflow采用的是静态图机制,那到底什么样的图是静态的?什么样的图是动态的呢?在计算图当中,根据搭建方式的不同,可以将计算图分为动态和静态。

不同点对比
***个人学习过程总结,持续记录ing
2521

被折叠的 条评论
为什么被折叠?



