[課堂筆記][pytorch學習][1]pytorch的tensor是什麼?如何使用cuda?和簡單的神經網路實現
阿新 • • 發佈:2021-07-08
課程地址:https://www.bilibili.com/video/BV12741177Cu
第一節課課程筆記:
PyTorch與其他框架的對比
- PyTorch:動態計算圖Dynamic Computation Graph - Tensorflow:靜態計算圖Static Computation Graph什麼是PyTorch?
PyTorch是一個基於Python的科學計算庫,它有以下特點:
- 類似於NumPy,但是它可以使用GPU
- 可以用它定義深度學習模型,可以靈活地進行深度學習模型的訓練和使用
Tensors
Tensor類似與NumPy的ndarray,唯一的區別是Tensor可以在GPU上加速運算。
tensor舉例:
1.in-place加法
y.add_(x)
輸出:
tensor([[ 1.1866, 0.0035, -0.7225],
[ 0.8220, 0.9750, 0.8406],
[ 1.2857, 0.5896, 0.6168],
[ 0.8559, 0.7026, 2.2498],
[ 0.2741, -0.4248, 0.2826]])
#任何in-place的運算都會以``_``結尾。 舉例來說:``x.copy_(y)``, ``x.t_()``, 會改變 ``x``。
2.如果你有一個只有一個元素的tensor,使用.item()
x = torch.randn(1) 輸出x: tensor([-1.1493]) x.item() 輸出x: -1.1493233442306519
3.Torch Tensor和NumPy array會共享記憶體,所以改變其中一項也會改變另一項。
a = torch.ones(5) 輸出a: tensor([1., 1., 1., 1., 1.]) b = a.numpy() 輸出b: array([1., 1., 1., 1., 1.], dtype=float32) 改變numpy array裡面的值。 b[1] = 2 輸出a: tensor([1., 2., 1., 1., 1.])
#所有CPU上的Tensor都支援轉成numpy或者從numpy轉成Tensor。
#numpy不能在GPU上計算,但是tensor可以。
4.使用.to
方法,Tensor可以被移動到別的device上。例如:移到CUDA
#一般在程式碼中都會這樣寫 if torch.cuda.is_available(): device = torch.device("cuda")
Tensor和autograd
PyTorch的一個重要功能就是autograd,也就是說只要定義了forward pass(前向神經網路),計算了loss之後,PyTorch可以自動求導計算模型所有引數的梯度。
一個PyTorch的Tensor表示計算圖中的一個節點。如果x
是一個Tensor並且x.requires_grad=True
那麼x.grad
是另一個儲存著x
當前梯度(相對於一個scalar,常常是loss)的向量。
使用PyTorch中nn這個庫來構建一個簡單的神經網路。 用PyTorch autograd來構建計算圖和計算gradients, 然後PyTorch會幫我們自動計算gradient。
import torch.nn as nn N, D_in, H, D_out = 64, 1000, 100, 10 # 隨機建立一些訓練資料 x = torch.randn(N, D_in) y = torch.randn(N, D_out) model = torch.nn.Sequential( torch.nn.Linear(D_in, H, bias=False), # w_1 * x + b_1 torch.nn.ReLU(), torch.nn.Linear(H, D_out, bias=False), ) torch.nn.init.normal_(model[0].weight) torch.nn.init.normal_(model[2].weight) # model = model.cuda() loss_fn = nn.MSELoss(reduction='sum') learning_rate = 1e-6 for it in range(500): # Forward pass y_pred = model(x) # model.forward() # compute loss loss = loss_fn(y_pred, y) # computation graph print(it, loss.item()) # Backward pass loss.backward() # update weights of w1 and w2 with torch.no_grad(): for param in model.parameters(): # param (tensor, grad) param -= learning_rate * param.grad model.zero_grad()
optim
不手動更新模型的weights,而是使用optim這個包來幫助我們更新引數。 optim這個package提供了各種不同的模型優化方法,包括SGD+momentum, RMSProp, Adam等等。
optimizer = torch.optim.SGD(model.parameters(), lr=learning_rate) optimizer.zero_grad() # Backward pass loss.backward() # update model parameters optimizer.step()
自定義 nn Modules
我們可以定義一個模型,這個模型繼承自nn.Module類。如果需要定義一個比Sequential模型更加複雜的模型,就需要定義nn.Module模型。
class TwoLayerNet(torch.nn.Module): def __init__(self, D_in, H, D_out): super(TwoLayerNet, self).__init__() # define the model architecture self.linear1 = torch.nn.Linear(D_in, H, bias=False) self.linear2 = torch.nn.Linear(H, D_out, bias=False) def forward(self, x): y_pred = self.linear2(self.linear1(x).clamp(min=0)) return y_pred