PyTorch基礎知識總結
PyTorch基礎知識總結
Tensor(張量)
張量是PyTorch裡的基本運算單位,與numpy的ndarray相同都表示一個多維的矩陣。與ndarray最大的區別在於Tensor能使用GPU加速,而ndarray只能用在CPU上。
與Numpy之間進行轉換
將Tensor轉換成numpy,只需呼叫.numpy()方法即可。
將numpy轉換成Tensor,使用torch.from_numpy()進行轉換。
# a --> Tensor a = torch.rand(3, 2) # Tensor --> numpy numpy_a = a.numpy() # numpy --> Tensor b = torch.from_numpy(numpy_a)
Tensor初始化
- torch.rand(*size) : 使用[0, 1]均勻分佈隨機初始化
- torch.randn(*size) : 服從正太分佈初始化
- torch.zeros(*size) : 使用0填充
- torch.ones(*size):使用1填充
- torch.eye(*size) :初始化一個單位矩陣,即對角線為1,其餘為0
Autograd
PyTorch中的Autograd模組實現了深度學習的演算法中的反向傳播求導數,在Tensor上的所有操作,Autograd都能為它們自動計算微分,簡化了手動求導數的過程。
在張量建立時,通過設定requires_grad = True
x = torch.randn(5, 5, requires_grad = True)
在計算完成後,呼叫backward()方法會自動根據歷史操作來計算梯度,並儲存在grad中。
神經網路包nn (torch.nn)
torch.nn是專門為神經網路設計的模組化介面,建立在Autogard之上。
通常定義一個神經網路類除了使用到nn之外還會引用nn.functional,這個包中包含了神經網路中使用的一些常見函式(ReLu, pool, sigmoid, softmax等),這些函式一般放在forward函式中。
通常一個神經網路類需要繼承nn.Module,並實現forward方法,PyTorch就會根據autograd自動實現backward方法。下面是LeNet網路模型的定義。
import torch.nn as nn
import torch.nn.functional as F
class Net(nn.Module):
def __init__(self):
super(Net, self).__init__()
# 卷積層
self.conv1 = nn.Conv2d(1, 6, 5)
self.conv2 = nn.Conv2d(6, 16, 5)
# 全連線層
self.fc1 = nn.Linear(16 * 5 * 5, 120)
self.fc2 = nn.Linear(120, 84)
self.fc3 = nn.Linear(84, 10)
def forward(self, x):
# 卷積 --> ReLu --> 池化
x = F.max_pool2d(F.relu(self.conv1(x)), (2, 2))
x = F.max_pool2d(F.relu(self.conv2(x)), (2, 2))
# reshape, '-1'表示自適應
# x = (n * 16 * 5 * 5) --> n : batch size
# x.size()[0] == n --> batch size
x = x.view(x.size()[0], -1)
# 全連線層
x = F.relu(self.fc1(x))
x = F.relu(self.fc2(x))
x = self.fc3(x)
return x
損失函式
在torch.nn中還定義了一些常用的損失函式,比如MESLoss(均方誤差),CrossEntropyLoss(交叉熵誤差)等。
labels = torch.arange(10).view(1, 10).float()
out = net(input)
criterion = nn.MSELoss()
# 計算loss
loss = criterion(labels, out)
優化器(torch.optim)
在反向傳播計算完所有引數的梯度後,還需要使用優化方法來更新網路的引數,常用的優化方法有隨機梯度下降法(SGD),策略如下:
weight = weight - learning_rate * gradient
import torch.optim
import torch.nn as nn
out = net(input)
criterion = nn.MSELoss(out, labels)
# 新建一個優化器,SGD只需要輸入要調整的引數和學習率
optimizer = torch.optim.SGD(net.parameters(), lr = 0.01)
# 反向傳播前,先梯度清0, optimizer.zero_grad()等同於net.zero_grad()
optimizer.zero_grad()
loss.backward()
# 更新引數
optimizer.step()
資料的載入和預處理
PyTorch通過torch.utils.data對一般常用的資料載入進行了封裝,可以很容易實現資料預處理和批量載入。torchvision已經有一些常用的資料集以及訓練好的模型(例如,CIFAR-10, ImageNet, COCO等),可以很方便的在這些模型上進行訓練以及測試。
Dataset(torch.utils.data.Dataset)
為了方便資料的讀取,通常需要將使用的資料集包裝為Dataset類。可以使用torchvision.dataset包中存在資料集來生成Dataset,同時也可以自定義Dataset類。
以torchvision.dataset中MNIST資料集為例生成dataset
dataset = tv.datasets.MNIST(
root='data/',
train=True,
download=True,
transform=None
)
自定義Dataset,當torchvision.dataset包中沒有相應的資料集,這時候就需要我們自定義Dataset類了,自定義類必須繼承於torch.utils.data.Dataset類,並且實現__ len __ () 和 __ getitem __ () 方法。
- __ len __ () 該方法返回資料集的總長度。
- __ getitem __ () 該方法通過索引[0, len(self) - 1]來獲取一條資料或者一個樣本。
DataLoader(torch.utils.data.DataLoader)
DataLoader為我們提供了對Dataset的讀取操作,常用的引數有batch_size(每一批資料的大小), shuffle(是否進行隨機讀取操作), num_workers(載入資料的時候使用幾個子程序)
trainloader = torch.utils.data.DataLoader(dataset, batch_size=10, shuffle=True, num_works=0)
# trainloader是一個可迭代的物件,我們可以使用iter分次獲取資料。
# 但是通常使用for迴圈來對其進行遍歷,如下。
for i, data in enumerate(trainloader):
# deal the data
pass
此時,我們可以通過Dataset加裝資料集,並使用DataLoader來遍歷處理資料。
torchvision包
torchvision是專門用來處理影象的庫,裡面有datasets, models, transforms等類,其中最常用的類是transforms,它通常用來進行資料的預處理(ToTensor, 歸一化等),如下。
from torchvision import transforms as transforms
transform = transforms.Compose([
transforms.ToTensor(),
transforms.Normalize((0.4914, 0.4822, 0.4465), (0.229, 0.224, 0.225)), #R,G,B每層的歸一化用到的均值和方差
])