grad 梯度

什么样的tensor有grad?

  • pytorch中只有torch.float复杂类型才能有grad。
x = torch.tensor([1, 2, 3, 4], requires_grad=True)

这里没有指定xdtype=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(),会求出WX的梯度。
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​
那么Yx1求偏导,得到的就是w1,同理Yxi求偏导得到wiYwi求偏导得到xi

  • Yxi求导时:其余的变量都固定,或者说其余的变量视为常量。
    ∂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.]])

可以看到,每次反向传播求梯度时,都会加上上一次的梯度,但是没有改变WX,梯度也不应该变化

手动清空梯度

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()相关推荐

  1. Pytorch autograd.grad与autograd.backward详解

    Pytorch autograd.grad与autograd.backward详解 引言 平时在写 Pytorch 训练脚本时,都是下面这种无脑按步骤走: outputs = model(inputs ...

  2. Pytorch中的optimizer.zero_grad和loss和net.backward和optimizer.step的理解

    引言 一般训练神经网络,总是逃不开optimizer.zero_grad之后是loss(后面有的时候还会写forward,看你网络怎么写了)之后是是net.backward之后是optimizer.s ...

  3. PyTorch Autograd(backward grad 等PyTorch核心)

    文章目录 绪论 1. PyTorch基础 2. 人工神经网络和反向传播 3. 动态计算图(dynamic computational graph) 4. 反向函数(Backward()) 5. 数学: ...

  4. 使用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 ...

  5. 【pytorch】 grad、grad_fn、requires_grad()、with torch.no_grad() 、net.train()、net.eval():记录一次奇怪的debug经历

    刚开始接触pytorch框架时,最让我觉得神奇的就是它居然可以–自 动 求 导 ! 于是我开始尝试理解内部的运行机制,但很快放弃了,直接当成黑盒使用-- 最近又遇到一个奇怪的bug,让我不得不去学一下 ...

  6. [转]一文解释PyTorch求导相关 (backward, autograd.grad)

    PyTorch是动态图,即计算图的搭建和运算是同时的,随时可以输出结果:而TensorFlow是静态图. 在pytorch的计算图里只有两种元素:数据(tensor)和 运算(operation) 运 ...

  7. backward()和zero_grad()在PyTorch中代表什么意思

    文章目录 问:`backward()`和`zero_grad()`是什么意思? backward() zero_grad() 问:求导和梯度什么关系 问:backward不是求导吗,和梯度有什么关系( ...

  8. Pytorch 为什么每一轮batch需要设置optimizer.zero_grad

    根据pytorch中的backward()函数的计算,当网络参量进行反馈时,梯度是被积累的而不是被替换掉:但是在每一个batch时毫无疑问并不需要将两个batch的梯度混合起来累积,因此这里就需要每个 ...

  9. RuntimeError: grad can be implicitly created only for scalar outputs的原因:Pytorch不支持对张量的求导

    一.背景介绍 原则上,Pytorch不支持对张量的求导,即如果z是张量的话,需要先将其转为标量. 浏览了很多博客,给出的解决方案都是说在求导时,加一个torch.ones_like(z)的参数. 下面 ...

最新文章

  1. 在 Spring 4.3.9下升级 Velocity 1.7.x to Velocity 2.0.x 出现的问题
  2. java动态url_使用url Param的动态主题
  3. JSON定义及解析,JSON文件读写
  4. opencv python安装linux_Ubuntu16.04、Python3.6下安装opencv4遇到的问题
  5. 如何在Java中使用Zxing和JFreeSVG创建QR Code SVG?
  6. Struts2教程9:实现自已的拦截器
  7. 小程序如何调用php程序,微信小程序调用PHP后台接口 解析纯html文本
  8. 相对、绝对、固定定位,以及其层级关系和脱离文档流的影响
  9. 如何调节电脑显示屏来保护双眼的小技巧
  10. linux系统awk、sed,Linux系统 linux awk sed
  11. 厂商为什么喜欢使用堆叠?
  12. linux 安装tomcat
  13. step13. ubuntu18.04下载安装配置Hive(转)
  14. MAC欺骗-通过思科模拟器实现
  15. 今日头条搜索有站长平台!
  16. gspca 摄像头驱动的移植(ZC3XX)
  17. K均值聚类算法(HCM,K-Means)
  18. 灵机一栋团队alpha冲刺 Ⅳ
  19. 行内元素与块级元素区别1.0
  20. Intel PinTools使用笔记——INS_InsertCall()

热门文章

  1. 固态硬盘和机械硬盘的区别
  2. pycharm远程连接服务器完整教程
  3. input type=file选择图片按钮样式修改与图片预览
  4. 改变ubutun 默认配色
  5. 500块搞定Windows下NAS和高清播放平台
  6. 计算机偏置,深度学习中偏置的作用
  7. 6个Excel操作技巧,期待明年更好的自己
  8. Nginx 日志和监控 - HTTP 健康监测
  9. 基于51单片机的故障灯检测
  10. 2020年英语六级翻译