1. 程式人生 > >Pytorch1.0關於Tensor的自我總結

Pytorch1.0關於Tensor的自我總結

關於Tensor和Numpy

PyTorch的官方介紹是一個擁有強力GPU加速的張量和動態構建網路的庫,其主要構建是張量,所以可以把PyTorch當做Numpy來用,Pytorch的很多操作好比Numpy都是類似的,但是其能夠在GPU上執行,所以有著比Numpy快很多倍的速度。

使用下述程式碼可以將numpy ndarray轉換到tensor資料型別

import numpy as np
import torch

# 建立一個numpy ndarray size=10*20
a = np,random.randn(10,20)

# 我們可以使用兩種方式將numpy的ndarray轉換到tensor上
pytorch_tensor1 = torch.Tensor(a)
pytorch_tensor2 = torch.from_numpy(a)

同樣,我們也可以將tensor轉換到ndarray

# 此方法只對位於CPU上的tensor有效
numpy_ndarray = pytorch_tensor.numpy()
#如果位於GPU上,需要採用如下程式碼
numpy_ndarray = pytorch_tensor.cpu().numpy()

Tensor放到GPU上
pytorch中的tensor相對於numpy的最大區別就是可以將Tensor放在GPU上進行計算,這樣可以極大地加快運算速度。

# 第一種方式是定義cuda資料型別
gpu_tensor = torch.randn(10,20).type(torch.cuda.FloatTensor)

# 第二種方式更簡單,推薦使用
gpu_tensor = torch.randn(10,20).cuda(0) # 將tensor放到第一個GPU上
gpu_tensor = torch.randn(10,20).cuda(1) # 將tensor放到第二個GPU上

使用第一種方式將tensor放到GPU上的時候會將資料型別轉換成定義的型別,而是用第二種方式能夠直接將tensor放到GPU上,型別跟之前保持一致
推薦在定義tensor的時候就明確資料型別,然後直接使用第二種方法將tensor放到GPU上

Tensor的一些屬性

print(pytorch_tensor1.shape)
#獲取張量的尺寸
# 得到tensor的資料型別
print(pytorch_tensor1.type())
print(pytorch_tensor1.dim())
#得到tensor的維度,比如1維,2維,3維。。。
# 得到tensor的所有元素個數
print(pytorch_tensor1.numel())

Tensor資料型別
torch.Tensor是一種包含單一資料型別元素的多維矩陣。
Torch定義了七種CPU tensor型別和八種GPU tensor型別:
在這裡插入圖片描述
如果採用torch.Tensor()建立張量,那麼它的預設資料型別為torch.FloatTensor.

不同張量之間資料型別的轉換:(一般,只要在Tensor後加long(), int(), double(), float(), byte()等函式就能將Tensor的型別進行轉換

tensor = torch.Tensor(3, 5)
torch.long() 將tensor投射為long型別
newtensor = tensor.long()
torch.int()將該tensor投射為int型別
newtensor = tensor.int()
torch.double()將該tensor投射為double型別
newtensor = tensor.double()

如何建立tensor(張量)?
自己在摸索中碰見了很多坑,寫在這裡總結一下,免得再錯!!!
1、典型的tensor構建方法

torch.tensor(data, dtype=None, device=None, requires_grad=False)
#data通常為列表
#dtype通常為上述型別
#device這個引數表示了tensor將會在哪個裝置上分配記憶體。它包含了裝置的型別(cpu、cuda)和可選裝置序號。如果這個值是預設的,那麼預設為當前的活動裝置型別。
通常為
	device=torch.device(cuda)
	torch.ones(3,3,device=device)
#requires_grad預設為False,可以設定為True

2、從numpy轉換得到
3、建立特殊值組成的tensor

torch.zeros(*sizes, out=None, dtype=None, layout=torch.strided, device=None, requires_grad=False) 
torch.ones(*sizes, out=None, dtype=None, layout=torch.strided, device=None, requires_grad=False) 
torch.randn(*sizes, out=None, dtype=None, layout=torch.strided, device=None, requires_grad=False) 

4、安裝步長或者區間建立tensor

torch.arange(start=0, end, step=1, out=None, dtype=None, layout=torch.strided, device=None, requires_grad=False) 
torch.linspace(start, end, steps=100, out=None, dtype=None, layout=torch.strided, device=None, requires_grad=False) 
torch.logspace(start, end, steps=100, out=None, dtype=None, layout=torch.strided, device=None, requires_grad=False)

重大更新
從pytorch 0.4.0 開始,Tensor和Variable類合併了,即現在開始他們兩就是一個東西啦!!!(但是Variable也依舊可以使用)

Tensor的一些基本操作
https://blog.csdn.net/qjk19940101/article/details/79555653
https://blog.csdn.net/xholes/article/details/81667211

自動求導

x = torch.tensor([[1.1, 2.2], [3.3, 4.4]],requires_grad=True)
m = x**2
print(x.requires_grad)
print(m.requires_grad)
out = m.sum()
out.backward()
print(m.grad)
print(x.grad)
True
True
None
tensor([[2.2000, 4.4000],
        [6.6000, 8.8000]])

從上面可以看到,變數x和m都可以自動求導(即requires_grad=True),但是隻有對x求出了導數,而對m沒有求出導數。

個人理解
在自動求導的時候會一直求導到最後一個可以求導的變數(中間結果不會儲存),因此只能求出對x導數,沒有對m的導數。

如何修改tensor的requires_grad屬性?

x = torch.tensor([[1.1, 2.2], [3.3, 4.4]])
m = x**2
m.requires_grad_(requires_grad=True)   #修改requires_grad屬性
print(x.requires_grad)
print(m.requires_grad)
out = m.sum()
out.backward()
print(m.grad)
print(x.grad)
False
True
tensor([[1., 1.],
        [1., 1.]])
None

如何對Tensor的維度進行修改?

1、使用view()對tensor進行reshape

#reshape前後的資料個數要一致
x = torch.randn(3,4,5)
x = x.view(-1, 5)
# -1 表示任意的大小,5表示第二維變成5
print(x.shape)
x = x.view(-1, 5)
# -1 表示任意的大小,5表示第二維變成5
print(x.shape)
torch.Size([12, 5])
torch.Size([3, 20])

2、squeeze()

torch.squeeze(input, dim=None, out=None)

input為輸入的tensor
dim為輸入的維度,如果該維度對應的維度值為1,就刪除,否則不變。如果不輸入dim,那麼就刪除所有維度值為1的維度

x = torch.randn(3,4,1,5)
print(x.size())
b = torch.squeeze(x,2)
print(b.size())
c = torch.squeeze(x,1)
print(c.size())
torch.Size([3, 4, 1, 5])
torch.Size([3, 4, 5])
torch.Size([3, 4, 1, 5])

3、unsqueeze

與squeeze的含義相反

c=torch.Tensor(3)
print(c,c.size())
d = torch.unsqueeze(c,0)
print(d.size())
e = torch.unsqueeze(c,1)
print(e.size())
tensor([1.0426e-42, 0.0000e+00, 1.0426e-42]) torch.Size([3])
torch.Size([1, 3])
torch.Size([3, 1])

torch.max()

torch.max()返回兩個結果,第一個是最大值,第二個是對應的索引值;第二個引數 0 代表按列取最大值並返回對應的行索引值,1 代表按行取最大值並返回對應的列索引值。

d=torch.Tensor([[1,3],[2,4]])
value1,index1=torch.max(d,0)
value2,index2=torch.max(d,1)
print(value1,index1)
print(value2,index2)
tensor([2., 4.]) tensor([1, 1])
tensor([3., 4.]) tensor([1, 1])