detach()、detach_()和data

detach()与detach_()

在x->y->z传播中,如果我们对y进行detach(),梯度还是能正常传播的;
但如果我们对y进行detach_(),就把x->y->z切成两部分:x和y->z,x则无法接受到后面传过来的梯度。

detach()和data

(1)共同点:
x.data和x.detach()返回和x的相同数据 tensor,这个新的tensor和原来的tensor(即x)是共用数据的,一者改变,另一者也会跟着改变,但是x.data和x.detach() 的 require s_grad = False,即是不可求导的。
(2)不同点:
①x.data 不能被 autograd 追踪求微分,即使被改了也能错误求导;而x.detach()也不能被 autograd 追踪求微分,被改了会直接报错,避免错误的产生。
②.data 是一个属性,detach()是一个方法;
③.data 是不安全的,.detach()是安全的。

代码

import torch
a0 = torch.tensor([1.1, 2.2, 3.3], requires_grad = True)
a = a0.tanh()
print('a=',a)
print('a.requires_grad=',a.requires_grad)
a_detach = a.detach()
print('a_detach=',a_detach)
print('a_detach.requires_grad=', a_detach.requires_grad)a_detach.zero_()
print('a_detach=',a_detach)
print('a=',a)
print('a.requires_grad=',a.requires_grad)
# 此时对原来的a求导
a.sum().backward()
print(a0.grad)  # 此时会报错,错误结果参考下面,显示梯度计算所需要的张量已经被“原位操作inplace”所更改了。

运行结果:

a0 = torch.tensor([1.1, 2.2, 3.3], requires_grad = True)
a = a0.tanh()
print('a=',a)
print('a.requires_grad=',a.requires_grad)
a_data = a.data
print('a_data=',a_data)
print('a_data.requires_grad=',a_data.requires_grad)
a_data.zero_()
print('a_data=',a_data)
print('a=',a)
print('a.requires_grad=',a.requires_grad)
# 此时对原来的a求导
a.sum().backward()
print(a0.grad)  # 不会报错,但是结果却并不正确

运行结果:

解释:
通过.data和.detach()得到的的变量会和原来的变量共用同样的数据,但是新分离得到的张量是不可求导的,a_data、a_detach发生了变化,原来张量的数值也会发生变化,但仍然可求导。
**使用tensor.detach()的优点:**从上面的例子可以看出,由于我更改分离之后的变量值c,导致原来的张量out的值也跟着改变了,这个时候如果依然按照求导规则来求导,由于out已经更改了,所以不会再继续求导了,而是报错,这样就避免了得出完全牛头不对马嘴的求导结果。
**使用tensor.data的局限性:**文档中说使用tensor.data是不安全的, 因为 x.data 不能被 autograd 追踪求微分 。什么意思呢?从上面的例子可以看出,由于我更改分离之后的变量值c,导致原来的张量out的值也跟着改变了,但是这种改变对于autograd是没有察觉的,它依然按照求导规则来求导,导致得出完全错误的导数值却浑然不知。它的风险性就是如果我再任意一个地方更改了某一个张量,求导的时候也没有通知我已经在某处更改了,导致得出的导数值完全不正确,故而风险大。

.cpu()

cpu()函数作用是将数据从GPU上复制到memory上,相对应的函数是cuda()

.item() VS .detach() .data

.data返回的是一个tensor
而.item()返回的是一个具体的数值。
注意:对于元素不止一个的tensor列表,使用item()会报错

a = torch.tensor([1.1, 2.2, 3.3], requires_grad = True)
b = torch.tensor([2.2 ,3.3 ,6.6], requires_grad = True)
loss = mse(a,b)
print('loss=\n', loss)
print('loss.detach()=\n', loss.detach())
print('loss.data=\n', loss.data)
print('loss.detach().cpu().data=\n', loss.detach().cpu().data)
print('loss.detach().item()=\n',loss.detach().item())
print('loss.item()=\n',loss.item())
print(type(loss.item()))

运行结果:

print('b.data=\n', b.data)
print('b.item()=\n', b.item())

解释
当tensor中只有一个值的时候:
.item()返回一个数值(将tensor类型数据转变成float型);
.data返回一个tensor。

参考链接
https://blog.csdn.net/u013289254/article/details/102557070
https://blog.csdn.net/qq_27825451/article/details/96837905?depth_1-utm_source=distribute.pc_relevant.none-task&utm_source=distribute.pc_relevant.none-task

pytorch中的.detach()和detach_()和.data和.cpu()和.item()的深入详解与区别联系相关推荐

  1. Sql Server 中 GAM、SGAM、PAM、IAM、DCM 和 BCM 的详解与区别

    Sql Server 中 GAM.SGAM.PAM.IAM.DCM 和 BCM 的详解与区别 GAM.SGAM.PAM.IAM.DCM 和 BCM 都是 SQL Server 中用来管理空间分配的一些 ...

  2. Pytorch 中的detach 和detach_

    本文转自 http://blog.csdn.net/u012436149/article/details/76714349 pytorch 的 Variable 对象中有两个方法,detach和 de ...

  3. Node.js中package.json中库的版本号详解(^和~区别)

    Node.js中package.json中库的版本号详解(^和~区别) 当我们查看package.json中已安装的库的时候,会发现他们的版本号之前都会加一个符号,有的是插入符号(^),有的是波浪符号 ...

  4. 计算机曝光模式有哪些,摄影:单反相机中P、A、S、M四种曝光模式的用法详解 -电脑资料...

    这篇教程是向脚本之家的朋友介绍单反相机中P.A.S.M四种曝光模式的用法,对于摄影爱好者非常值得学习,推荐到脚本之家,喜欢的朋友一起来看看吧 很多朋友在初接触单反相机时对相机的P.A.S.M四种曝光模 ...

  5. python中import re_Python3中正则模块re.compile、re.match及re.search函数用法详解

    本文实例讲述了Python3中正则模块re.compile.re.match及re.search函数用法.分享给大家供大家参考,具体如下: re模块 re.compile.re.match. re.s ...

  6. 如何在Python中获取图片分辨率?——Python实现获取图片分辨率的代码及详解。

    如何在Python中获取图片分辨率?--Python实现获取图片分辨率的代码及详解. 在进行图片处理或者图片分析的时候,获取图片的分辨率信息是必不可少的.Python提供了许多库可以方便地获取图片的分 ...

  7. c语言运算符 amp 的意思,C++中运算符 amp;和amp;amp;、|和|| 的详解及区别

    C++中运算符 &和&&.|和|| 的详解及区别 简介: &&是逻辑与运算符,||是逻辑或运算符,都是逻辑运算符,两边只能是bool类型 &与| 既可以 ...

  8. 站长在线Python精讲:Python中集合的交集、并集、差集和对称差集运算方法详解

    欢迎你来到站长在线的站长学堂学习Python知识,本文学习的是<Python中集合的交集.并集.差集和对称差集运算方法详解>.主要讲的是集合运算的相关的概念,及运算方法,包括:集合的交集. ...

  9. pytorch中的.detach和.data深入详解

    前言:这两个方法都可以用来从原有的计算图中分离出某一个tensor,有相似的地方,也有不同的地方,下面来比较性的看一看.PyTorch0.4以及之后的版本中,.data 仍保留,但建议使用 .deta ...

最新文章

  1. LAMP笔记之MySQL高阶篇(5)
  2. matlab+snapshot采集图片
  3. 使用PHP时出现乱码,php出现乱码该怎么解决?
  4. 电脑亮度多少对眼睛好_电脑显示器亮度多少合适呢??
  5. [转载] python文件操作--写入文件
  6. sqlplus connect oracle
  7. 多媒体数据处理实验1:算术编码
  8. 正确将博客网页保存为pdf
  9. 最新+电脑象棋测试软件,中国象棋2017电脑版
  10. 何凯明深度残差网络翻译
  11. 求95859回文数c语言程序,csdn 回文数
  12. 陶哲轩实分析 习题6.3.3
  13. Qt 之显示网络图片
  14. HTML Purifier
  15. 关键词提取——有监督方法
  16. java 庖丁解牛_庖丁解牛 --JAVA 栈的实现
  17. TMS320F280049C 学习笔记9 CMD文件 程序从FLASH复制到RAM中运行
  18. 坐标系之间的简单变换
  19. webpack之entry
  20. 【某OTA网站加密参数还原生成】

热门文章

  1. APP首页、详情改版心得
  2. springcloud学习(七)-Sidecar(多语言支持)
  3. 转给迷茫的自己---专访周家安:我的十年编程自学之路
  4. 佛洛依德算法的学习与实现
  5. GIS的框选范围查询
  6. java weakhashmap_Java WeakHashMap类
  7. 【iTools】Clipboard 扩展 -- Ditto
  8. 阅读代码的一些心得体会
  9. 那类水果含维生素B多?
  10. 微信小程序 - 返回前一个页面时,执行前一个页面的函数方(wx.navigateBack 返回后,执行上一页的某个函数方法刷新数据)回前一个页面时,执行前一个页面的函数方法。支持改变 data 数据。