1. 程式人生 > 實用技巧 >PyTorch基礎知識總結

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

來告訴PyTorch需要對該張量進行自動求導,PyTorch會記錄該張量的每一步操作歷史並自動計算導數。requires_grad預設為False。

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每層的歸一化用到的均值和方差
])



THE END