1、 Tensorpython
a) 張量是torch的基礎數據類型數組
b) 張量的核心是座標的改變不會改變自身性質。函數
c) 0階張量爲標量(只有數值,沒有方向的量),由於它不隨座標的變化發生改變spa
d) 一階張量爲矢量(即向量),他也不隨座標變化而發生變化code
e) 二階張量爲矩陣orm
f) 生成tensor時的通用參數blog
i.
轉換數值類型:
常見生成tensor的參數:dtype。Tensor默認的份量構成爲float64
好比生成由長整型構成的全爲0的tensor:torch.zeros(2,3,dtype=torch.long)索引
ii. 指定存放容器:內存
參數:device。可賦值:cpu/gpu開發
g) 建立未初始化的張量:empty(raw, col)
h) 建立隨機初始化的張量:rand(raw,col)
i) 建立份量均爲0的張量:zeros(raw,col)
j) 直接根據數據建立向量:tensor(factor)。factor是一個用數字構成的list,只能寫一個list,即tensor函數只能生成向量
k)
其餘的張量生成函數:
l) 獲取維度信息:x.size()。輸出結果爲元組
m) x.new_*(size):建立一個tensor,複製x的dtype和device。星號位置能夠寫任意的tensor生成函數。能夠賦值強行修改dtype和device
n)
*_like(tensor):建立一個size和tensor同樣的張量。。星號位置能夠寫任意的tensor生成函數
2、 算術(這裏的x、y均爲張量)
a) 加法:
i. x+y
ii. torch.add(x,y, result=var)。若是設定了result參數,那麼加法的結果會儲存在var中,此時就不用再寫z=torch.add()了
iii. y.add_(x)
b) 矩陣運算:
i. torch.mul(a, b)是矩陣a和b對應位相乘,a和b的維度必須相等,好比a的維度是(1, 2),b的維度是(1, 2),返回的還是(1, 2)的矩陣
ii. torch.mm(a, b)是矩陣a和b矩陣相乘,好比a的維度是(1, 2),b的維度是(2, 3),返回的就是(1, 3)的矩陣
c) 線代運算:
d) 非相同形狀的tensor的運算處理:廣播機制
i. 廣播機制的定義:先適當複製元素使這兩個 Tensor 形狀相同後再按元素運算
ii. 因爲 x 和 y 分別是1行2列和3行1列的矩陣,若是要計算 x + y ,那麼 x 中第⼀行的2個元素被廣播 (複製)到了了第二行和第三行,而 y 中第一列的3個元素被廣播(複製)到了第二列。
如此,就能夠對2個3行2列的矩陣按元素相加。
1 x = torch.arange(1, 3).view(1, 2) 2 print(x) 3 y = torch.arange(1, 4).view(3, 1) 4 print(y) 5 print(x + y) 6 7 tensor([[1, 2]]) 8 tensor([[1], [2], [3]]) 9 tensor([[2, 3], [3, 4], [4, 5]])
3、 索引
a) 索引出來的結果與原數據共享內存,也即修改一個,另⼀個會跟着修改
b) X[:,0]是numpy中數組的一種寫法,torch也是相似的。表示對一個二維數組,取該二維數組第一維中的全部數據,第二維中取第0個數據,直觀來講,X[:,0]就是取全部行的第0個數據, X[:,1] 就是取全部行的第1個數據。
c) [m,n]:索引的數字爲第m項到第n-1項
d)
其他索引:
index_select():
input:要篩選的tensor
dim的參數:0或1。參數0表示按行索引,1表示按列進行索引
index:用tensor表示
例子:
import torch input_tensor = torch.tensor([1,2,3,4,5]) print(input_tensor.index_select(0,torch.tensor([0,2,4]))) input_tensor = torch.tensor([[1,2,3,4,5],[6,7,8,9,10]]) print(input_tensor.index_select(0,torch.tensor([1]))) print(input_tensor.index_select(1,torch.tensor([1])))
輸出爲:
tensor([1, 3, 5]) tensor([[ 6, 7, 8, 9, 10]]) tensor([[2], [7]])
4、改變tensor形狀
a) tensor.view(size)
b) 注意 view() 返回的新tensor與源tensor共享內存(實際上是同一個tensor),也即更改其中的⼀個,另一個也會跟着改變。(顧名思義,view僅僅是改變了對這個張量的觀察角度)
1 y = x.view(15) 2 z = x.view(-1, 5) # -1所指的維度能夠根據其餘維度的值推出來 3 print(x.size(), y.size(), z.size())
torch.Size([5, 3]) torch.Size([15]) torch.Size([3, 5])
c) 如何不影響本體改變shape呢?
使用clone()函數先對本體克隆,再使用view。使用 clone 還有一個好處是會被記錄在計算圖中,即梯度回傳到副本時也會傳到源 Tensor
x_cp = x.clone().view(15) x -= 1 print(x) print(x_cp)
tensor([[ 0.6035, 0.8110, -0.0451], [ 0.8797, 1.0482, -0.0445], [-0.7229, 2.8663, -0.5655], [ 0.1604, -0.0254, 1.0739], [ 2.2628, -0.9175, -0.2251]]) tensor([1.6035, 1.8110, 0.9549, 1.8797, 2.0482, 0.9555, 0.2771, 3.8663, 0.4345, 1.1604, 0.9746, 2.0739, 3.2628, 0.0825, 0.7749])
5、內存的使用
a) 前面提到的索引和view並不會開闢新的內存。因此一個變更其餘的也會變。可是加法會開闢一個新內存
b) 使用python自帶的id函數能夠查看內存地址
1 x = torch.tensor([1, 2]) 2 y = torch.tensor([3, 4]) 3 id_before = id(y) 4 y = y + x 5 print(id(y) == id_before) 6 7 8 False
6、數據轉換
a) item():將標量tensor轉換成python number
1 x = torch.randn(1) 2 print(x) 3 print(x.item()) 4 5 tensor([2.3466]) 6 2.3466382026672363
b) 與numpy的轉換
i. numpy():將tensor轉化成numpy數組
1 a = torch.ones(5) 2 b = a.numpy() 3 print(a, b) 4 a += 1 5 print(a, b) 6 b += 1 7 print(a, b) 8 9 10 tensor([1., 1., 1., 1., 1.]) [1. 1. 1. 1. 1.] 11 tensor([2., 2., 2., 2., 2.]) [2. 2. 2. 2. 2.] 12 tensor([3., 3., 3., 3., 3.]) [3. 3. 3. 3. 3.]
ii. from_numpy():將numpy數組轉化成tensor
1 import numpy as np 2 a = np.ones(5) 3 b = torch.from_numpy(a) 4 print(a, b) 5 a += 1 6 print(a, b) 7 b += 1
print(a, b) 8 9 10 [1. 1. 1. 1. 1.] tensor([1., 1., 1., 1., 1.], dtype=torch.float64) 11 [2. 2. 2. 2. 2.] tensor([2., 2., 2., 2., 2.], dtype=torch.float64) 12 [3. 3. 3. 3. 3.] tensor([3., 3., 3., 3., 3.], dtype=torch.float64)
iii. 根據上面的例子,咱們能夠發現,numpy和tensor之間的相互轉換是共用內存的。一個改變,另外一個也改變
iv. tensor():不共用內存將numpy轉變成tensor
1 c = torch.tensor(a) #這裏的a沿用ii中例子的結果 2 a += 1 3 print(a, c) 4 5 6 [4. 4. 4. 4. 4.] tensor([3., 3., 3., 3., 3.], dtype=torch.float64)
7、處理器的變化
使用to()使tensor在CPU與GPU之間相互移動
1 # 如下代碼只有在PyTorch GPU版本上纔會執行 2 if torch.cuda.is_available(): 3 device = torch.device("cuda") #建立device在GPU。cuda是一個英偉達開發的並行 4 y = torch.ones_like(x, device=device) # 直接建立一個在GPU上的tensor 5 x = x.to(device) #等價於 .to("cuda") 6 z = x + y 7 print(z) 8 print(z.to("cpu", torch.double)) # to()還能夠同時更更改數據類型