【動手學pytorch】pytorch的基礎操做

1、 Tensorpython

a)       張量是torch的基礎數據類型數組

b)       張量的核心是座標的改變不會改變自身性質。函數

c)        0階張量爲標量(只有數值,沒有方向的量),由於它不隨座標的變化發生改變spa

d)       一階張量爲矢量(即向量),他也不隨座標變化而發生變化code

e)       二階張量爲矩陣orm

f)         生成tensor時的通用參數blog

                     i.            轉換數值類型:
常見生成tensor的參數:dtypeTensor默認的份量構成爲float64
好比生成由長整型構成的全爲0tensortorch.zeros(2,3,dtype=torch.long)索引

                    ii.            指定存放容器:內存

參數:device。可賦值:cpu/gpu開發

g)       建立未初始化的張量:empty(raw, col)

h)       建立隨機初始化的張量:rand(rawcol)

i)         建立份量均爲0的張量:zeros(rawcol)

j)         直接根據數據建立向量:tensor(factor)factor是一個用數字構成的list,只能寫一個list,即tensor函數只能生成向量

k)       其餘的張量生成函數:

 

l)       獲取維度信息:x.size()。輸出結果爲元組

m)       x.new_*(size):建立一個tensor,複製xdtypedevice。星號位置能夠寫任意的tensor生成函數。能夠賦值強行修改dtypedevice

n)        *_like(tensor):建立一個sizetensor同樣的張量。。星號位置能夠寫任意的tensor生成函數

 

2、 算術(這裏的xy均爲張量)

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)是矩陣ab對應位相乘,ab的維度必須相等,好比a的維度是(1, 2)b的維度是(1, 2),返回的還是(1, 2)的矩陣

                    ii.            torch.mm(a, b)是矩陣ab矩陣相乘,好比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的參數:01。參數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()還能夠同時更更改數據類型                    
相關文章
相關標籤/搜索