从零开始深度学习Pytorch笔记(9)—— 计算图与自动求导(下)

浏览: 2421

前文传送门:

从零开始深度学习Pytorch笔记(1)——安装Pytorch

从零开始深度学习Pytorch笔记(2)——张量的创建(上)

从零开始深度学习Pytorch笔记(3)——张量的创建(下)

从零开始深度学习Pytorch笔记(4)——张量的拼接与切分

从零开始深度学习Pytorch笔记(5)——张量的索引与变换

从零开始深度学习Pytorch笔记(6)——张量的数学运算

从零开始深度学习Pytorch笔记(7)—— 使用Pytorch实现线性回归

从零开始深度学习Pytorch笔记(8)—— 计算图与自动求导(上)

在该系列的上一篇,我们介绍了使用Pytorch的重要知识点:计算图和自动求导。

本篇我们继续学习计算图和自动求导。

首先,我们在上一节的计算图上增加复杂度,例如变成这样的计算图:

图中为了绘制方便,把张量w和x绘制在一个框中了。

其对应的计算图代码如下:

import torch
w = torch.tensor([1.],requires_grad=True)
x = torch.tensor([2.],requires_grad=True)

a = torch.add(w,x)
b = torch.add(w,2)
y = torch.mul(a,b)

y.backward()#梯度反向传播
print(w.grad)#w的梯度

需要注意的一点是,要使得某个变量支持求导,需要在赋值时使它的元素为浮点数值,如果例如上面代码中的 w 和 x 张量,如果我们定义时赋值的元素不是浮点数而是整数,如下代码:

#不用浮点数
import torch
w = torch.tensor([1],requires_grad=True)
x = torch.tensor([2],requires_grad=True)

a = torch.add(w,x)
b = torch.add(w,2)
y = torch.mul(a,b)

y.backward()#梯度反向传播
print(w.grad)#w的梯度

运行后会发现:

抛出的异常大概意思是:只有元素类型是浮点数的张量才能支持梯度计算。

所以这点大家要注意!

我们接着来聊聊一个新的概念,叫做叶子节点。

pytorch的tensor类中,有个叫做 is_leaf 的属性,可以称之为叶子节点,如果计算图中某个节点的 is_leaf 属性取值为 True,则为叶子节点。如果取值是False,则不是叶子节点。

一般将用户自己创建的变量叫做叶子节点,而由叶子节点计算得到的变量叫做非叶子节点,调用非叶子节点的backward方法,就会沿着非叶子节点一直回溯到叶子节点结束。

我们还是执行一次反向传播:

import torch
w = torch.tensor([1.],requires_grad=True)
x = torch.tensor([2.],requires_grad=True)

a = torch.add(w,x)
b = torch.add(w,2)
y = torch.mul(a,b)

y.backward()#梯度反向传播

然后查看各个节点是否叶子节点:

#查看叶子节点
print(w.is_leaf,x.is_leaf,a.is_leaf,b.is_leaf,y.is_leaf)

我们发现,其中只有我们赋值的 w 和 x 是叶子节点,而 a、b、y 是由 w 和 x 计算得到的。

我们查看一次 backward 后,每个节点的梯度值:

#查看梯度
print(w.grad,x.grad,a.grad,b.grad,y.grad)#只有叶子结点梯度存在于内存中

发现只有叶子节点的梯度值不为None,这是因为非叶子节点的梯度值并没有被保存在内存中。

所以叶子节点是该节点是否能保存梯度的前提。

欢迎关注公众号学习之后的深度学习连载部分~

扫码下图关注我们不会让你失望!

image.png

推荐 0
本文由 ID王大伟 创作,采用 知识共享署名-相同方式共享 3.0 中国大陆许可协议 进行许可。
转载、引用前需联系作者,并署名作者且注明文章出处。
本站文章版权归原作者及原出处所有 。内容为作者个人观点, 并不代表本站赞同其观点和对其真实性负责。本站是一个个人学习交流的平台,并不用于任何商业目的,如果有任何问题,请及时联系我们,我们将根据著作权人的要求,立即更正或者删除有关内容。本站拥有对此声明的最终解释权。

0 个评论

要回复文章请先登录注册