2020.5.20 PyTorch从零开始笔记(1) ——tensor基本操作

主要参考学习链接: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])  [1 2 3 4] 
'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岁了
老四已经在墙上了了

你可能感兴趣的:(2020.5.20 PyTorch从零开始笔记(1) ——tensor基本操作)