tensor复制与保存

tesor.clone()

clone(memory_format=torch.preserve_format)→ Tensor

返回tensor的拷贝,返回的新tensor和原来的tensor具有同样的大小和数据类型。

clone()返回的tensor是中间节点,梯度会流向原tensor,即返回的tensor的梯度会叠加在原tensor上

>>> import torch
>>> a = torch.tensor(1.0, requires_grad=True)
>>> b = a.clone()
>>> id(a), id(b)  # a和b不是同一个对象
(140191154302240, 140191145593424)
>>> a.data_ptr(), b.data_ptr()  # 也不指向同一块内存地址
(94724518544960, 94724519185792)
>>> a.requires_grad, b.requires_grad  # 但b的requires_grad属性和a的一样,同样是True
(True, True)
>>> c = a * 2
>>> c.backward()
>>> a.grad
tensor(2.)
>>> d = b * 3
>>> d.backward()
>>> b.grad  # b的梯度值为None,因为是中间节点,梯度值不会被保存
>>> a.grad  # b的梯度叠加在a上
tensor(5.)
>>> import torch
>>> a = torch.tensor(1.0)
>>> b = a.clone()
>>> id(a), id(b)  # a和b不是同一个对象
(140191169099168, 140191154762208)
>>> a.data_ptr(), b.data_ptr()  # 也不指向同一块内存地址
(94724519502912, 94724519533952)
>>> a.requires_grad, b.requires_grad  # 但b的requires_grad属性和a的一样,同样是False
(False, False)
>>> b.requires_grad_()
>>> c = b * 2
>>> c.backward()
>>> b.grad
tensor(2.)
>>> a.grad  # None

tensor.detach()

从计算图中脱离出来。

返回一个新的tensor,新的tensor和原来的tensor共享数据内存,但不涉及梯度计算,即requires_grad=False。修改其中一个tensor的值,另一个也会改变,因为是共享同一块内存,但如果对其中一个tensor执行某些内置操作,则会报错,例如resize_、resize_as_、set_、transpose_。

>>> import torch
>>> a = torch.rand((3, 4), requires_grad=True)
>>> b = a.detach()
>>> id(a), id(b)  # a和b不是同一个对象了
(140191157657504, 140191161442944)
>>> a.data_ptr(), b.data_ptr()  # 但指向同一块内存地址
(94724518609856, 94724518609856)
>>> a.requires_grad, b.requires_grad  # b的requires_grad为False
(True, False)
>>> b[0][0] = 1
>>> a[0][0]  # 修改b的值,a的值也会改变
tensor(1., grad_fn=<SelectBackward>)
>>> b.resize_((4, 3))  # 报错
RuntimeError: set_sizes_contiguous is not allowed on a Tensor created from .data or .detach().

tensor.clone().detach() 还是 tensor.detach().clone()

两者的结果是一样的,即返回的tensor和原tensor在梯度上或者数据上没有任何关系,一般用前者。

clone提供了非数据共享的梯度追溯功能,而detach又“舍弃”了梯度功能,因此clone和detach意味着着只做简单的数据复制,既不数据共享,也不对梯度共享,从此两个张量无关联。

置于是先clone还是先detach,其返回值一样,一般采用tensor.clone().detach()。

4. new_tensor

new_tensor可以将源张量中的数据复制到目标张量(数据不共享),同时提供了更细致的device、dtype和requires_grad属性控制:

new_tensor(data, dtype=None, device=None, requires_grad=False) 

注意:其默认参数下的操作等同于.clone().detach(),而requires_grad=True时的效果相当于.clone().detach()requires_grad_(True)。上面两种情况都推荐使用后者。

5. copy_

copy_同样将源张量中的数据复制到目标张量(数据不共享),其device、dtype和requires_grad一般都保留目标张量的设定,仅仅进行数据复制,同时其支持broadcast操作。

a = torch.tensor([[1,2,3], [4,5,6]], device="cuda")
b = torch.tensor([7.0,8.0,9.0], requires_grad=True)
a.copy_(b)
print(a)   # tensor([[7, 8, 9], [7, 8, 9]], device='cuda:0')  
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值