1. 程式人生 > 實用技巧 >pytorch 及其模板應用

pytorch 及其模板應用

pytorch及其應用

優點

  1. 支援GPU、靈活;
  2. 支援動態神經網路;
  3. 底層程式碼易於理解;
  4. 命令式體驗;自定義擴充套件

缺點

  1. 對比TensorFlow,全面性不足,不支援快速傅立葉、沿維翻轉張量和檢查無窮與非數值張量;

  2. 針對移動端、嵌入式部署以及高效能伺服器端的部署其效能表現有待提升;

  3. 因為框架較新,社群沒有那麼強大,在文件方面其C庫大多數沒有文件。

環境配置

  1. 有關conda虛擬環境
conda list # 檢視安裝了哪些包
conda env list # 檢視當前存在哪些虛擬環境
conda update conda # 檢查更新當前conda
python --version # 檢視python版本
conda create -n xxx python=3.6 # xxx為自己命名的虛擬環境名稱,該檔案可在Anaconda安裝目錄 envs檔案下找到
conda create -n pytorch python=3.6
conda activate yorr_env_name # 啟用虛擬環境
conda install -n your_env_name [package] # 對虛擬環境安裝額外的包
deactivate # 關閉虛擬環境
conda remove -n your_env_name --all
conda remove --name your_env_name package_name # 刪除環境中的某個包
  1. 虛擬環境下安裝 jupyter
conda activate pytorch
conda install nb_conda
  1. pytorch安裝
conda activate pytorch
conda install pytorch torchvision cpuonly -c pytorch
  1. 離線安裝(極其有用,血淚教訓)
# https://download.pytorch.org/whl/torch_stable.html
# 下載對應的whl,然後安裝
pip install D:\software\Anaconda3\whl_download\torch-1.5.0+cpu-cp36-cp36m-win_amd64.whl

Python學習中的兩大法寶函式

  1. dir() 道具:相當於你的手和眼睛,它可以幫你開啟東西和看到其中的東西。能讓你瞭解package有哪些東西,也許是更小的模組,或者是函式。dir() 函式,當輸出是帶有前後雙下劃線的,這個時候,就表明,這是一個函式,一個工具。你應該使用 help() 函式去檢視這個工具的使用方法。
  2. help() 道具:相當於說明書,你可以知道每個工具的使用方法。能讓你知道函式的使用方法。
import torch
dir(torch)
help(torch.cuda.is_available)

資料

from PIL import Image
img_path = "" # 注意,win下\\
img = Image.open(ima_path)
img.show()
import os
dir_path = "" # /
img_path_list = os.listdir(dir_path) # 資料夾下的變成列表

root_dir = "dataset/train"
label_dir = "ants"
path = os.path.join(root_dir,label_dir) # 系統自動加起來,不會出錯
from torch.utils.data import Dataset
class MyData(Dataset):
	def __init__(self, root_dir, label_dir):
		self.root_dir = root_dir
		self.label_dir = label_dir
		self.path = os.path.join(self.root_dir,self.label_dir)
		self.img_path = os.listdir(self.path) # 所有圖片的名稱
	
	def __getitem__(self,idx):
		img_name = self.img_path[idx] # 圖片名
		img_item_path = os.path.join(self.root_dir,self.label_dir, img_name) # 圖片相對路徑地址
		img = Image.open(img_item_path) # 讀取圖片
		label = self.label_dir # 這裡label就是檔名
		return img, label
	
	def __len__(self):
		return len(self.img_path) # 資料集的長度

root_dir = "dataset/train"
ants_label_dir = "ants"
bees_label_dir = "bees"
ants_dataset = MyData(root_dir, ants_label_dir)
bees_dataset = MyData(root_dir, bees_label_dir)

img, label = ants_dataset[0] # 就自動呼叫了__getitem__獲取了第一個
img.show()

train_dataset = ants_dataset + bees_dataset # 合併資料集 資料增強

構建自己的網路

  1. 處理資料
  2. 定義網路
  3. 定義損失函式
  4. 定義優化方法
  5. 訓練

一個例子

import torch

class TwoLayerNet(torch.nn.Module):
    
    def __init__(self, D_in, H, D_out):
        """
        在建構函式中,我們例項化了兩個nn.Linear模組,並將它們作為成員變數。
        """
        super(TwoLayerNet, self).__init__()
        self.linear1 = torch.nn.Linear(D_in, H)
        self.linear2 = torch.nn.Linear(H, D_out)
    
    def forward(self, x):
        """
        在前向傳播的函式中,我們接收一個輸入的張量,也必須返回一個輸出張量。
        我們可以使用建構函式中定義的模組以及張量上的任意的(可微分的)操作。
        """
        h_relu = self.linear1(x).clamp(min=0)
        y_pred = self.linear2(h_relu)
        return y_pred

# N是批大小; D_in 是輸入維度;
# H 是隱藏層維度; D_out 是輸出維度
N, D_in, H, D_out = 64, 1000, 100, 10

# 產生輸入和輸出的隨機張量
x = torch.randn(N, D_in)
y = torch.randn(N, D_out)

# 通過例項化上面定義的類來構建我們的模型。
model = TwoLayerNet(D_in, H, D_out)

# 構造損失函式和優化器。
# SGD建構函式中對model.parameters()的呼叫,
# 將包含模型的一部分,即兩個nn.Linear模組的可學習引數。
loss_fn = torch.nn.MSELoss(reduction='sum')
optimizer = torch.optim.SGD(model.parameters(), lr=1e-4)
for t in range(500):
    # 前向傳播:通過向模型傳遞x計算預測值y
    y_pred = model(x)

    #計算並輸出loss
    loss = loss_fn(y_pred, y)
    # print(t, loss.item())

    # 清零梯度,反向傳播,更新權重
    optimizer.zero_grad()
    loss.backward()
    optimizer.step()

一個可以效仿的測試函式:

def test(model, device, test_loader):
    model.eval()
    test_loss = 0
    correct = 0
    with torch.no_grad():
        for i,data in enumerate(test_loader):          
            x,y= data
            x=x.to(device)
            y=y.to(device)
            optimizer.zero_grad()
            y_hat = model(x)
            test_loss += criterion(y_hat, y).item() # sum up batch loss
            pred = y_hat.max(1, keepdim=True)[1] # get the index of the max log-probability
            correct += pred.eq(y.view_as(pred)).sum().item()
    test_loss /= len(test_loader.dataset)
    print('\nTest set: Average loss: {:.4f}, Accuracy: {}/{} ({:.0f}%)\n'.format(
        test_loss, correct, len(val_dataset),
        100. * correct / len(val_dataset)))