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

一、tensor.data的使用

先直接看一段代码:

import torcha = torch.tensor([1,2,3.], requires_grad = True)
out = a.sigmoid()
c = out.data  # 需要走注意的是,通过.data “分离”得到的的变量会和原来的变量共用同样的数据,而且新分离得到的张量是不可求导的,c发生了变化,原来的张量也会发生变化
c.zero_()     # 改变c的值,原来的out也会改变
print(c.requires_grad)
print(c)
print(out.requires_grad)
print(out)
print("----------------------------------------------")out.sum().backward() # 对原来的out求导,
print(a.grad)  # 不会报错,但是结果却并不正确
'''运行结果为:
False
tensor([0., 0., 0.])
True
tensor([0., 0., 0.], grad_fn=<SigmoidBackward>)
----------------------------------------------
tensor([0., 0., 0.])
'''

tensor.data的两点总结:

(1)tensor .data 返回和 x 的相同数据 tensor,而且这个新的tensor和原来的tensor是共用数据的,一者改变,另一者也会跟着改变,而且新分离得到的tensor的require s_grad = False, 即不可求导的。(这一点其实detach是一样的)

(2)使用tensor.data的局限性。文档中说使用tensor.data是不安全的, 因为 x.data 不能被 autograd 追踪求微分 。什么意思呢?从上面的例子可以看出,由于我更改分离之后的变量值c,导致原来的张量out的值也跟着改变了,但是这种改变对于autograd是没有察觉的,它依然按照求导规则来求导,导致得出完全错误的导数值却浑然不知。它的风险性就是如果我再任意一个地方更改了某一个张量,求导的时候也没有通知我已经在某处更改了,导致得出的导数值完全不正确,故而风险大。

二、tensor.detach()的使用

同样是使用上面的案例代码,将.data 更改成 .detach,如下:

import torcha = torch.tensor([1,2,3.], requires_grad = True)
out = a.sigmoid()
c = out.detach()  # 需要走注意的是,通过.detach() “分离”得到的的变量会和原来的变量共用同样的数据,而且新分离得到的张量是不可求导的,c发生了变化,原来的张量也会发生变化
c.zero_()     # 改变c的值,原来的out也会改变
print(c.requires_grad)
print(c)
print(out.requires_grad)
print(out)
print("----------------------------------------------")out.sum().backward() # 对原来的out求导,
print(a.grad)  # 此时会报错,错误结果参考下面,显示梯度计算所需要的张量已经被“原位操作inplace”所更改了。
'''
False
tensor([0., 0., 0.])
True
tensor([0., 0., 0.], grad_fn=<SigmoidBackward>)
----------------------------------------------
RuntimeError: one of the variables needed for gradient computation has been modified by an inplace operation
'''

tensor.detach()的两点总结:

(1)tensor .detach() 返回和 x 的相同数据 tensor,而且这个新的tensor和原来的tensor是共用数据的,一者改变,另一者也会跟着改变,而且新分离得到的tensor的require s_grad = False, 即不可求导的。(这一点其实 .data是一样的)

(2)使用tensor.detach()的优点。从上面的例子可以看出,由于我更改分离之后的变量值c,导致原来的张量out的值也跟着改变了,这个时候如果依然按照求导规则来求导,由于out已经更改了,所以不会再继续求导了,而是报错,这样就避免了得出完全牛头不对马嘴的求导结果。

三、总结

相同点:tensor.data和tensor.detach() 都是变量从图中分离,但而这都是“原位操作 inplace operation”。

不同点:

(1).data 是一个属性,二.detach()是一个方法;

(2).data 是不安全的,.detach()是安全的。

pytorch中的.detach和.data深入详解相关推荐

  1. Pytorch中dilation(Conv2d)参数详解

    目录 一.Conv2d 二.Conv2d中的dilation参数 一.Conv2d 首先我们看一下Pytorch中的Conv2d的对应函数(Tensor通道排列顺序是:[batch, channel, ...

  2. pytorch中的nn.LSTM模块参数详解

    直接去官网查看相关信息挺好的,但是为什么有的时候进不去 官网:https://pytorch.org/docs/stable/nn.html#torch.nn.LSTM 使用示例,在使用中解释参数 单 ...

  3. Pytorch中改变形状和交换维度详解:view()、reshape()、transpose()、permute()以及contiguous()

    文章目录 view()和reshape() transpose()和permute() contiguous 以后操作基于下述tensor. import torch a=torch.rand(2,2 ...

  4. Pytorch中的train和eval模式详解

    (一).model.train()和model.eval()分别在训练和测试中都要写,它们的作用如下: (1). model.train() 启用 BatchNormalization 和 Dropo ...

  5. java data使用_@Data注解详解及使用方法-Fun言

    @Data作用 去除Getter,Setter,equals,hashCode,toString方法,@Data注解在类上时,简化java代码编写,为该类提供读写属性.简单来说就是不用再手动添加get ...

  6. python时间函数报错_python3中datetime库,time库以及pandas中的时间函数区别与详解...

    1介绍datetime库之前 我们先比较下time库和datetime库的区别 先说下time 在 Python 文档里,time是归类在Generic Operating System Servic ...

  7. vue ajax highcharts,在vue项目中引入highcharts图表的方法(详解)

    npm进行highchars的导入,导入完成后就可以进行highchars的可视化组件开发了 npm install highcharts --save 1.components目录下新建一个char ...

  8. vue build text html,Vue中v-text / v-HTML使用实例代码详解_放手_前端开发者

    废话少说,代码如下所述: /p> 显示123 /p> 补充:vuejs {{}},v-text 和 v-html的区别 {{message}} let app = new Vue({ el ...

  9. python获取系统时间函数_python3中datetime库,time库以及pandas中的时间函数区别与详解...

    1介绍datetime库之前 我们先比较下time库和datetime库的区别 先说下time 在 Python 文档里,time是归类在Generic Operating System Servic ...

最新文章

  1. php链表笔记:单链表反转
  2. 自动生成想“变”就“变”
  3. [Leetcode] Copy list with random pointer 对带有任意指针的链表深度拷贝
  4. 用rvest包来抓取Google学术搜索数据
  5. 【学术相关】供参考:刚刚,2021 世界大学学术排名发布!
  6. iOS之深入解析Runtime的objc_msgSend“慢速查找”底层原理
  7. windows网关详解 【了解网关的重要性,增加网络性能】【FreeXploiT综合文】
  8. bbb sd6 无e2 修改
  9. 计算机专业需要汇编语言,重点大学计算机专业系列教材·汇编语言程序设计
  10. 单例模式、使用getInstance()方法的原因及作用
  11. Linux 下的驱动开发最简单例子
  12. Python的类与类型
  13. 【搞船日记】【Shapr3D的STL格式转Gcode】
  14. 如何一键下载或保存微博里面的短视频?
  15. 问题记录之---nginx temp文件夹
  16. UVM基础-Sequence、Sequencer(一)
  17. 《追风筝的人》观后感
  18. 一个不成熟的模板引擎思路
  19. B2B-Destoon--注册会员公司名称修改方法
  20. 干货|撰写创业计划书的大致框架

热门文章

  1. [2019BUAA软件工程]个人期末总结感想
  2. 闭门造轮(LVGL_2)
  3. 关于shiro授权 This subject is anonymous - it does not have any identifying principals and
  4. 微软的公有云Azure简介
  5. 【python爬虫】面向对象方法实现斗图网案例
  6. MySQL的日志 - general log
  7. Charles手机代理设置
  8. 分享Linux常见命令echo命令代码实现
  9. 西安交通大学控制专硕学硕考研资料清单(自动控制、数字信号处理、信号与系统)
  10. 《软件工程》网上书店项目需求分析