主要参考学习链接:https://tangshusen.me/Dive-into-DL-PyTorch/#/chapter02_prerequisite/2.2_tensor
1、内存共享
1、z = z+1和z+=1的内存共享区别
z = torch.arange(0,15, dtype=torch.long).view(5, 3)
print(z,type(z))
# tensor([[ 0, 1, 2],
# [ 3, 4, 5],
# [ 6, 7, 8],
# [ 9, 10, 11],
# [12, 13, 14]]) <class 'torch.Tensor'>
i = z.view(15)
j = z.view(-1, 5) # -1所指的维度可以根据其他维度的值推出来
print(i.size(), j.size(), z.size())
z += 1
print(i)
print(j) # 通过view共享数据,而内存地址不一样,i,j 也加了1
a= z.view(15)
b = z.view(-1, 5)
print(a, '\n', b)
print(a.size(), '\n', b.size())
z = z + 1
print(a, b, z) # a, b不变
2、索引操作是不会开辟新内存的,而像y = x + y这样的运算是会新开内存的,然后将y指向新内存。
m = torch.arange(0, 4).view(4, 1)
print(id(m))
m = m + n # 会新开内存
print(id(m))
m[:] = m + n #指定结果到原来的内存
print(id(m))
torch.add(m, n, out=m) #指定结果到原来的内存
print(id(m))
m += n #指定结果到原来的内存
print(id(m))
m.add_(n) #指定结果到原来的内存
print(id(m))
# 1831257070760
# 1831257538920
# 1831257538920
# 1831257538920
# 1831257538920
# 1831257538920
3、o和o.view()的内存共享区别
o = torch.arange(1, 5)
p = o.view(2, 2)
print(o, '\n', p, id(o) == id(p))
# tensor([1, 2, 3, 4])
# tensor([[1, 2],
# [3, 4]]) False
虽然view返回的Tensor与源Tensor是共享data的,但是依然是一个新的Tensor(因为Tensor除了包含data外还有一些其他属性),二者id (内存地址)并不一致。
4、Tensor和NumPy相互转换内存共享问题
我们很容易用 numpy()和torch.from_numpy() 将Tensor和NumPy中的数组相互转换。但是需要注意的一点是:
这两个函数所产生的的Tensor和NumPy中的数组共享相同的内存(所以他们之间的转换很快),改变其中一个时另一个也会改变!!!
q = torch.arange(1, 5)
r = q.numpy()
print(q,type(q), r, type(r))
q = torch.arange(1, 5)
r = q.numpy()
print(q,type(q), r, type(r))
# tensor([4, 5, 6, 7]) [4 5 6 7]
# tensor([5, 6, 7, 8]) [5 6 7 8]
如果中间有q = q + 1打断,则情况不一样:
q = torch.arange(1, 5)
r = q.numpy()
print(q,type(q), r, type(r))
# tensor([1, 2, 3, 4]) <class 'torch.Tensor'> [1 2 3 4] <class
'numpy.ndarray'>
q = q + 1
print(q, id(q), r)
q += 1
print(q, id(q), r)
r += 1
print(q, id(q), r)
# tensor([2, 3, 4, 5]) 1831257070256 [1 2 3 4]
# tensor([3, 4, 5, 6]) 1831257070256 [1 2 3 4]
# tensor([3, 4, 5, 6]) 1831257070256 [2 3 4 5]
# 此时r指向最初的q,而经过q = q + 1后q的地址发生了变化,所以两者不共享数据
此外上面提到还有一个常用的方法就是直接用 torch.tensor() 将NumPy数组转换成Tensor,需要注意的是该方法总是会进行数据拷贝,返回的Tensor和原来的数据不再共享内存。
2、items和item的区别
1、pytorch常用的函数就是item()
h = z[2, 0].item()
print(h, type(h))
7 <class 'int'>
# pytorch常用的函数就是item(),
# 它可以将一个标量Tensor转换成一个Python number
2、Python 字典 items() 函数作用:
以列表返回可遍历的(键, 值) 元组数组。
items()方法语法(参考原文链接:https://blog.csdn.net/u012424313/article/details/86499194):
dict.items()
dict = {'老大':'15岁',
'老二':'14岁',
'老三':'2岁',
'老四':'在墙上'
print(dict.items())
for key,values in dict.items():
print(key + '已经' + values + '了')
—————
dict_items([('老大', '15岁'), ('老二', '14岁'), ('老三', '2岁'), ('老四', '在墙上')])
老大已经15岁了
老二已经14岁了
老三已经2岁了
老四已经在墙上了了