pytorch中的.detach()和detach_()和.data和.cpu()和.item()的深入详解与区别联系
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()的深入详解与区别联系相关推荐
- Sql Server 中 GAM、SGAM、PAM、IAM、DCM 和 BCM 的详解与区别
Sql Server 中 GAM.SGAM.PAM.IAM.DCM 和 BCM 的详解与区别 GAM.SGAM.PAM.IAM.DCM 和 BCM 都是 SQL Server 中用来管理空间分配的一些 ...
- Pytorch 中的detach 和detach_
本文转自 http://blog.csdn.net/u012436149/article/details/76714349 pytorch 的 Variable 对象中有两个方法,detach和 de ...
- Node.js中package.json中库的版本号详解(^和~区别)
Node.js中package.json中库的版本号详解(^和~区别) 当我们查看package.json中已安装的库的时候,会发现他们的版本号之前都会加一个符号,有的是插入符号(^),有的是波浪符号 ...
- 计算机曝光模式有哪些,摄影:单反相机中P、A、S、M四种曝光模式的用法详解 -电脑资料...
这篇教程是向脚本之家的朋友介绍单反相机中P.A.S.M四种曝光模式的用法,对于摄影爱好者非常值得学习,推荐到脚本之家,喜欢的朋友一起来看看吧 很多朋友在初接触单反相机时对相机的P.A.S.M四种曝光模 ...
- python中import re_Python3中正则模块re.compile、re.match及re.search函数用法详解
本文实例讲述了Python3中正则模块re.compile.re.match及re.search函数用法.分享给大家供大家参考,具体如下: re模块 re.compile.re.match. re.s ...
- 如何在Python中获取图片分辨率?——Python实现获取图片分辨率的代码及详解。
如何在Python中获取图片分辨率?--Python实现获取图片分辨率的代码及详解. 在进行图片处理或者图片分析的时候,获取图片的分辨率信息是必不可少的.Python提供了许多库可以方便地获取图片的分 ...
- c语言运算符 amp 的意思,C++中运算符 amp;和amp;amp;、|和|| 的详解及区别
C++中运算符 &和&&.|和|| 的详解及区别 简介: &&是逻辑与运算符,||是逻辑或运算符,都是逻辑运算符,两边只能是bool类型 &与| 既可以 ...
- 站长在线Python精讲:Python中集合的交集、并集、差集和对称差集运算方法详解
欢迎你来到站长在线的站长学堂学习Python知识,本文学习的是<Python中集合的交集.并集.差集和对称差集运算方法详解>.主要讲的是集合运算的相关的概念,及运算方法,包括:集合的交集. ...
- pytorch中的.detach和.data深入详解
前言:这两个方法都可以用来从原有的计算图中分离出某一个tensor,有相似的地方,也有不同的地方,下面来比较性的看一看.PyTorch0.4以及之后的版本中,.data 仍保留,但建议使用 .deta ...
最新文章
- LAMP笔记之MySQL高阶篇(5)
- matlab+snapshot采集图片
- 使用PHP时出现乱码,php出现乱码该怎么解决?
- 电脑亮度多少对眼睛好_电脑显示器亮度多少合适呢??
- [转载] python文件操作--写入文件
- sqlplus connect oracle
- 多媒体数据处理实验1:算术编码
- 正确将博客网页保存为pdf
- 最新+电脑象棋测试软件,中国象棋2017电脑版
- 何凯明深度残差网络翻译
- 求95859回文数c语言程序,csdn 回文数
- 陶哲轩实分析 习题6.3.3
- Qt 之显示网络图片
- HTML Purifier
- 关键词提取——有监督方法
- java 庖丁解牛_庖丁解牛 --JAVA 栈的实现
- TMS320F280049C 学习笔记9 CMD文件 程序从FLASH复制到RAM中运行
- 坐标系之间的简单变换
- webpack之entry
- 【某OTA网站加密参数还原生成】
热门文章
- APP首页、详情改版心得
- springcloud学习(七)-Sidecar(多语言支持)
- 转给迷茫的自己---专访周家安:我的十年编程自学之路
- 佛洛依德算法的学习与实现
- GIS的框选范围查询
- java weakhashmap_Java WeakHashMap类
- 【iTools】Clipboard 扩展 -- Ditto
- 阅读代码的一些心得体会
- 那类水果含维生素B多?
- 微信小程序 - 返回前一个页面时,执行前一个页面的函数方(wx.navigateBack 返回后,执行上一页的某个函数方法刷新数据)回前一个页面时,执行前一个页面的函数方法。支持改变 data 数据。