Pytorch的grad、backward()、zero_grad()
grad 梯度
什么样的tensor有grad?
- pytorch中只有
torch.float
和复杂类型
才能有grad。
x = torch.tensor([1, 2, 3, 4], requires_grad=True)
这里没有指定x
的dtype=torch.float
,那么是会报错的。
RuntimeError: Only Tensors of floating point and complex dtype can require gradients
- 正确的写法是:
x = torch.tensor(data=[1, 2, 3, 4], dtype=torch.float)
grad 的特点
- 如果
x
中的数据类型(dtype
)是torch.tensor
,那么requires_grad
默认是True
。 - 同时,默认
grad=None
,因为单单一个张量讲梯度是没有意义的。
backward() 反向传播
对于一个张量进行反向传播,会将所有与它关联的张量的梯度求解出来。
举个例子:
Y=W×XY = W×X Y=W×X
其中,W
是一个1x4的矩阵,X
是一个4x1的矩阵,那么Y
就是一个1x1的矩阵。
体现到代码中则是:
X = torch.tensor([[1.5],[3.7],[2.8],[6.4]], requires_grad=True, dtype=torch.float)
W = torch.tensor(data=[[1, 3, -2, 4]], requires_grad=True, dtype=torch.float)
Y = W.matmul(X)>>>W
tensor([[ 1., 3., -2., 4.]], requires_grad=True)
>>>X
tensor([[1.5000],[3.7000],[2.8000],[6.4000]], requires_grad=True)
>>>Y
tensor([[32.6000]], grad_fn=\<MmBackward0>)
那么这个时候,梯度就是可以求的,对Y
进行.backward()
,会求出W
与X
的梯度。
Y=w1×x1+w2×x2+w3×x3+w4×x4Y = w_1×x_1+ w_2×x_2+ w_3×x_3+ w_4×x_4 Y=w1×x1+w2×x2+w3×x3+w4×x4
那么Y
对x1
求偏导,得到的就是w1
,同理Y
对xi
求偏导得到wi
;Y
对wi
求偏导得到xi
。
Y
对xi
求导时:其余的变量都固定,或者说其余的变量视为常量。
∂Y∂xi=wi\frac{∂Y}{∂x_i}=w_i ∂xi∂Y=wi
Y.backward()
>>>X.grad
tensor([[ 1.],[ 3.],[-2.],[ 4.]])
>>>W.grad
tensor([[1.5000, 3.7000, 2.8000, 6.4000]])
zero_grad() 清空梯度
为什么要清空梯度呢?
仍然拿上一个例子距离,我们再次执行Y.backward()
,同时保证Y = W × X
没有变化。
"""" 必须设置为True,否则报错RuntimeError: Trying to backward through the graph a second time (or directly access saved tensors after they have already been freed). Saved intermediate values of the graph are freed when you call .backward() or autograd.grad(). Specify retain_graph=True if you need to backward through the graph a second time or if you need to access saved tensors after calling backward.RuntimeError: 试图第二次向后遍历图(或者在它们已经被释放后直接访问保存的张量)。 当您调用 .backward() 或 autograd.grad() 时,已保存的图形中间值被释放。 如果您需要第二次向后遍历图形,或者如果您需要在向后调用后访问保存的张量,请指定 retain_graph=True。 """ Y.backward(retain_graph=False)
>>>X = torch.tensor([[1.5],[3.7],[2.8],[6.4]], requires_grad=True, dtype=torch.float)
>>>W = torch.tensor(data=[[1, 3, -2, 4]], requires_grad=True, dtype=torch.float)
>>>Y = W.matmul(X)
>>>Y.backward(retain_graph=True) # 保持计算图
>>>X.grad
tensor([[ 1.],[ 3.],[-2.],[ 4.]])
>>>Y.backward(retain_graph=True)
>>>X.grad
tensor([[ 2.],[ 6.],[-4.],[ 8.]])
>>>Y.backward(retain_graph=True)
>>>X.grad
tensor([[ 3.],[ 9.],[-6.],[12.]])
可以看到,每次反向传播求梯度时,都会加上上一次的梯度,但是没有改变W
和X
,梯度也不应该变化
手动清空梯度
torch.tensor.grad.zero_()
import torchX = torch.tensor([[1.5],[3.7],[2.8],[6.4]], requires_grad=True, dtype=torch.float)
W = torch.tensor(data=[[1, 3, -2, 4]], requires_grad=True, dtype=torch.float)
Y = W.matmul(X)Y.backward(retain_graph=True)
print(X.grad)
"""
tensor([[ 1.],[ 3.],[-2.],[ 4.]])
"""Y.backward(retain_graph=True)
print(X.grad)
"""
tensor([[ 2.],[ 6.],[-4.],[ 8.]])
"""Y.backward(retain_graph=True)
print(X.grad)
"""
tensor([[ 3.],[ 9.],[-6.],[12.]])
"""X.grad.zero_()
print(X.grad)
"""
tensor([[0.],[0.],[0.],[0.]])
"""Y.backward()
print(X.grad)
"""
tensor([[ 1.],[ 3.],[-2.],[ 4.]])
"""
Pytorch的grad、backward()、zero_grad()相关推荐
- Pytorch autograd.grad与autograd.backward详解
Pytorch autograd.grad与autograd.backward详解 引言 平时在写 Pytorch 训练脚本时,都是下面这种无脑按步骤走: outputs = model(inputs ...
- Pytorch中的optimizer.zero_grad和loss和net.backward和optimizer.step的理解
引言 一般训练神经网络,总是逃不开optimizer.zero_grad之后是loss(后面有的时候还会写forward,看你网络怎么写了)之后是是net.backward之后是optimizer.s ...
- PyTorch Autograd(backward grad 等PyTorch核心)
文章目录 绪论 1. PyTorch基础 2. 人工神经网络和反向传播 3. 动态计算图(dynamic computational graph) 4. 反向函数(Backward()) 5. 数学: ...
- 使用pytorch的loss.backward()时,出现element 0 of tensors does not require grad and does not have a grad_fn
仅作为记录,大佬请跳过. 用loss.requires_grad_(True) 是因为loss没有设置梯度(所以不能反向传播)(loss的数据类型是tensor) 设置梯度后即可,展示: 参考 pyt ...
- 【pytorch】 grad、grad_fn、requires_grad()、with torch.no_grad() 、net.train()、net.eval():记录一次奇怪的debug经历
刚开始接触pytorch框架时,最让我觉得神奇的就是它居然可以–自 动 求 导 ! 于是我开始尝试理解内部的运行机制,但很快放弃了,直接当成黑盒使用-- 最近又遇到一个奇怪的bug,让我不得不去学一下 ...
- [转]一文解释PyTorch求导相关 (backward, autograd.grad)
PyTorch是动态图,即计算图的搭建和运算是同时的,随时可以输出结果:而TensorFlow是静态图. 在pytorch的计算图里只有两种元素:数据(tensor)和 运算(operation) 运 ...
- backward()和zero_grad()在PyTorch中代表什么意思
文章目录 问:`backward()`和`zero_grad()`是什么意思? backward() zero_grad() 问:求导和梯度什么关系 问:backward不是求导吗,和梯度有什么关系( ...
- Pytorch 为什么每一轮batch需要设置optimizer.zero_grad
根据pytorch中的backward()函数的计算,当网络参量进行反馈时,梯度是被积累的而不是被替换掉:但是在每一个batch时毫无疑问并不需要将两个batch的梯度混合起来累积,因此这里就需要每个 ...
- RuntimeError: grad can be implicitly created only for scalar outputs的原因:Pytorch不支持对张量的求导
一.背景介绍 原则上,Pytorch不支持对张量的求导,即如果z是张量的话,需要先将其转为标量. 浏览了很多博客,给出的解决方案都是说在求导时,加一个torch.ones_like(z)的参数. 下面 ...
最新文章
- 在 Spring 4.3.9下升级 Velocity 1.7.x to Velocity 2.0.x 出现的问题
- java动态url_使用url Param的动态主题
- JSON定义及解析,JSON文件读写
- opencv python安装linux_Ubuntu16.04、Python3.6下安装opencv4遇到的问题
- 如何在Java中使用Zxing和JFreeSVG创建QR Code SVG?
- Struts2教程9:实现自已的拦截器
- 小程序如何调用php程序,微信小程序调用PHP后台接口 解析纯html文本
- 相对、绝对、固定定位,以及其层级关系和脱离文档流的影响
- 如何调节电脑显示屏来保护双眼的小技巧
- linux系统awk、sed,Linux系统 linux awk sed
- 厂商为什么喜欢使用堆叠?
- linux 安装tomcat
- step13. ubuntu18.04下载安装配置Hive(转)
- MAC欺骗-通过思科模拟器实现
- 今日头条搜索有站长平台!
- gspca 摄像头驱动的移植(ZC3XX)
- K均值聚类算法(HCM,K-Means)
- 灵机一栋团队alpha冲刺 Ⅳ
- 行内元素与块级元素区别1.0
- Intel PinTools使用笔记——INS_InsertCall()