reference
https://icepoint666.github.io/2019/05/27/pytorch-clone/
直接赋值 tensor 易错点
- torch中对于直接赋值的这种操作一定要小心,先看看是不是需要直接赋值,还是重新开辟一块内存来存放
- 我们可以使用类似NumPy的索引操作来访问Tensor的一部分,需要注意的是:索引出来的结果与原数据共享内存,也即修改一个,另一个会跟着修改。
view()
返回的新Tensor
与源Tensor
虽然可能有不同的size
,但是是共享data
的,也即更改其中的一个,另外一个也会跟着改变。(顾名思义,view仅仅是改变了对这个张量的观察角度,内部数据并未改变)
不要用 x += 1(与原数据共享内存,也即修改一个,另一个会跟着修改),用x=x+1就没有问题 !!!!!!
本质原因还是 共享内存,所以 x += 1这种写法 直接更改原来memory address 内容;而 x = x+1, 是新创建一个variable 具有新的memory address。(just a guess, 未经证实)
如果想用x += 1这种写法,如何避免共享内存,details can refer this blog.
1.索引出来的结果与原数据共享内存
import torch
x = torch.rand(5, 3)
print(x, '\n')
y = x[0, :]
y += 1
print(y)
print(x[0, :]) # 源tensor也被改了
tensor([[0.8773, 0.6006, 0.7565],
[0.2363, 0.7644, 0.4871],
[0.7156, 0.1406, 0.3292],
[0.8075, 0.4868, 0.7283],
[0.4470, 0.4558, 0.3665]])
tensor([1.8773, 1.6006, 1.7565])
tensor([1.8773, 1.6006, 1.7565])
不要用 x += 1,用x=x+1就没有问题
import torch
x = torch.rand(5, 3)
print(x, '\n')
y = x[0, :]
y = y + 1
print(y)
print(x[0, :]) # 源tensor没有被修改!!!!!!!
tensor([[0.6475, 0.9476, 0.6793],
[0.9083, 0.6180, 0.7341],
[0.5327, 0.9944, 0.7394],
[0.4824, 0.6551, 0.7850],
[0.5130, 0.4454, 0.2850]])
tensor([1.6475, 1.9476, 1.6793])
tensor([0.6475, 0.9476, 0.6793])
2.view()
view()
返回的新Tensor
与源Tensor
虽然可能有不同的size。
y = x.view(15)
z = x.view(-1, 5) # -1所指的维度可以根据其他维度的值推出来
print(x.size(), y.size(), z.size())
torch.Size([5, 3]) torch.Size([15]) torch.Size([3, 5])
但是,但是是共享data
的,也即更改其中的一个,另外一个也会跟着改变。
(顾名思义,view仅仅是改变了对这个张量的观察角度,内部数据并未改变)。
x += 1
print(x)
print(y) # 也加了1
tensor([[2.8773, 2.6006, 2.7565],
[1.2363, 1.7644, 1.4871],
[1.7156, 1.1406, 1.3292],
[1.8075, 1.4868, 1.7283],
[1.4470, 1.4558, 1.3665]])
tensor([2.8773, 2.6006, 2.7565, 1.2363, 1.7644, 1.4871, 1.7156, 1.1406, 1.3292,
1.8075, 1.4868, 1.7283, 1.4470, 1.4558, 1.3665])
3.如何实现 赋值
用 .clone() 创建一个新的副本,开辟新的内存以存贮数据。
使用clone
还有一个好处是会被记录在计算图中,即梯度回传到副本时也会传到源Tensor
x_cp = x.clone().view(15)
x -= 1
print(x)
print(x_cp) # copy version, do not change
tensor([[1.8773, 1.6006, 1.7565],
[0.2363, 0.7644, 0.4871],
[0.7156, 0.1406, 0.3292],
[0.8075, 0.4868, 0.7283],
[0.4470, 0.4558, 0.3665]])
tensor([2.8773, 2.6006, 2.7565, 1.2363, 1.7644, 1.4871, 1.7156, 1.1406, 1.3292,
1.8075, 1.4868, 1.7283, 1.4470, 1.4558, 1.3665])