15分鐘PyTorch
沒有numpy基礎的同學可以先花10分鐘看numpy 快速入門,然後只需要再花5分鐘就能入門PyTorch
============================================================================================================================================================================================================================
PyTorch是一個貼近人類使用者習慣的深度學習框架。與Tensorflow相比,PyTorch遮蔽了很多不必要的、特別是與計算裝置相關的細節。與Tensorflow一樣,PyTorch的風格也與numpy保持高度一致,因此熟悉numpy的同學上手PyTorch非常迅速。
本文適用的PyTorch版本為0.4。
- 安裝
PyTorch不能通過PyPI安裝,需要參考官方網站,根據你Python的平臺進行選取。PyTorch支援三大主流作業系統,支援GPU加速。
2. 基本使用
剛才已經提到了,PyTorch與numpy的風格是一致的,甚至把import numpy as np改為import torch as np,你原先使用numpy的程式碼可以無改動的執行(當然不建議這樣做)
下面是numpy 快速入門提到的一些例子,原樣用PyTorch實現一遍,原來的numpy實現以註釋的方式也放在一起,供對比參考
#import numpy as np import torch #a = np.array(1) #b = np.array([1,2]) #c = np.array([[1.0,2.0,3.0],[3.0,4.0,5.0]]) a = torch.tensor(1) b = torch.tensor([1,2]) c = torch.tensor([[1.0,2.0,3.0],[3.0,4.0,5.0]]) #print(a.ndim,a.shape) #0 () #print(b.ndim,b.shape) #1 (2,) #print(c.ndim,c.shape) #2 (2,3) print(a.dim(),a.shape) #0 () print(b.dim(),b.shape) #1 (2,) print(c.dim(),c.shape) #2 (2,3) #print(np.ones((2,2))) # [[1,1],[1,1]] print(torch.ones((2,2))) # [[1,1],[1,1]] #d = c[0] #print(d,d.ndim,d.shape) # [1.0,2.0,3.0] 1 (3,) #e = c[1][2] #print(e,type(e)) # 5.0 numpy.float64 d = c[0] print(d,d.dim(),d.shape) # [1.0,2.0,3.0] 1 (3,) e = c[1][2] print(e,type(e)) # 5.0 torch.Tensor #f = np.array([[10.0,20.0,30.0],[30.0,40.0,50.0]]) #g = f + c #print(g) #[[11.0,22.0,33.0],[33.0,44.0,55.0]] f = torch.tensor([[10.0,20.0,30.0],[30.0,40.0,50.0]]) g = f + c print(g) #[[11.0,22.0,33.0],[33.0,44.0,55.0]] #h = c * 3 #print(h) #[[3.0,6.0,9.0],[9.0,12.0,15.0]] h = c * 3 print(h) #[[3.0,6.0,9.0],[9.0,12.0,15.0]] #i = np.abs(c-3) #print(i) # [[2., 1., 0.],[0., 1., 2.]] i = torch.abs(c-3) print(i) # [[2., 1., 0.],[0., 1., 2.]] #j = np.sin(i) #print(j) # [[0.90929743, 0.84147098, 0.],[0., 0.84147098, 0.90929743]]) j = torch.sin(i) print(j) # [[0.90929743, 0.84147098, 0.],[0., 0.84147098, 0.90929743]]) #k = np.array([[1],[2]]) #l = k.T #print(k.shape) # (2, 1) #print(l.shape) # (1, 2) #m = np.dot(k,l) #print(m) # [[1, 2],[2, 4]] k = torch.tensor([[1],[2]]) l = k.t() print(k.shape) # (2, 1) print(l.shape) # (1, 2) m = torch.matmul(k,l) print(m) # [[1, 2],[2, 4]]
3. GPU加速
在GPU加速之前應該檢查Cuda正常安裝,並且能夠被PyTorch識別
torch.cuda.is_available() #True torch.cuda.get_device_name(0) # 'GeForce ****' 此處用來炫富
與TensorFlow不同,PyTorch的每一個tensor都綁定了它對應的計算裝置,這也是PyTorch『動態特性』的體現。可以在構造tensor的時候指定其繫結的裝置,也可以通過裝置切換的方法得到不同裝置的tensor。例如
a_cpu = torch.tensor([1,2]) # tensor([1, 2]) a_gpu = a_cpu.cuda() # tensor([1, 2], device='cuda:0') b_gpu = torch.tensor([1,2],device='cuda:0') b_cpu = b_gpu.cpu() #tensor([1, 2])
綁定了同一個裝置的tensor可以進行計算,計算的過程就使用這些tensor所繫結的裝置。不同裝置的tensor不能進行計算。
c_cpu = a_cpu * b_cpu #tensor([1, 4]) c_gpu = a_gpu * b_gpu #tensor([1, 4], device='cuda:0') c = a_cpu * b_gpu #RuntimeError
4. 與numpy的互動
Numpy的資料型別可以以複製的方式轉換為PyTorch的Tensor,同時會複製其資料型別。
a_np = np.array([1,2]) a_torch = torch.tensor(a_np) a_np[1] = 3 print(a_torch) #tensor([1, 2], dtype=torch.int32)
也可以以共享的方式使一個PyTorch.tensor和Numpy.ndarray使用同一個儲存空間
a_np = np.array([1,2]) a_torch_shared = torch.from_numpy(a_np) a_np[1] = 3 print(a_torch_shared) #tensor([1, 3], dtype=torch.int32) b_np_shared = a_torch_shared.numpy() a_torch_shared[1] = 5 print(a_np) #5 print(b_np_shared) #5
需要說明的是,PyTorch.tensor和Numpy.ndarray不能夠直接計算。希望後續的版本PyTorch能夠進行支援。