如何入門Pytorch之一:Pytorch基本知識介紹


前言

       PyTorch和Tensorflow是目前最為火熱的兩大深度學習框架,Tensorflow主要用戶群在於工業界,而PyTorch主要用戶分布在學術界。目前視覺三大頂會的論文大多都是基於PyTorch,如何快速入門PyTorch成了當務之急。

正文

      本着循序漸進的原則,我會依次從易到難的內容進行介紹,並采用定期更新的方式來補充該文。

一、安裝PyTorch 

      參考鏈接:https://blog.csdn.net/miao0967020148/article/details/80394270

      安裝PyTorch前需要先安裝Anaconda,然后使用如下命令

      conda install pytorch torchvision cuda80 -c soumith  { for cuda8.0  }

      conda install pytorch torchvision -c soumith         { for cuda7.5  }

      pip3 install -i https://pypi.tuna.tsinghua.edu.cn/simple torch==1.3.1  (sudo apt install python3-pip)

      pip3 install -i https://pypi.tuna.tsinghua.edu.cn/simple torchvision==0.4.2(同時會裝上Torch1.3.1)

二、搭建第一個神經網絡

一個簡單的神經網絡包含這些內容(數據准備,可調節參數,網絡模型,損失函數,優化器)

1)數據准備

     x,y=get_data()

2) 可調節參數

    w,b=get_weight()

3) 網絡模型

    y_pred = simple_network(x)         {y = wx+b }

4)損失函數

    loss = loss_fn(y,y_pred)     

5)優化器

   optimize(learning_rate)   

完整的神經網絡如下:

x,y = get_data() # x - represents training data,y - represents target variables
w,b = get_weights() # w,b - Learnable parameters
for i in range(500):
    y_pred = simple_network(x) # function which computes wx + b
    loss = loss_fn(y,y_pred) # calculates sum of the squared differences of y and y_pred
if i % 50 == 0:
    print(loss)
    optimize(learning_rate) # Adjust w,b to minimize the loss

三、數據准備

     在PyTorch中,有兩種類型的數據:1、張量;2.變量。其中Tensors類似於Numpy,就象Python中的Arrays,可以動態地修改大小。比如:一張正常的圖像,可以用三維張量來表達,我們可以動態地放大到5維的張量。接下來逐一介紹各個維度的張量:

3.1張量

1)標量Scalar(0維張量)

x = torch.rand(10)
x.size()
Output - torch.Size([10])

2)向量Vector(1維張量)

temp = torch.FloatTensor([23,24,24.5,26,27.2,23.0])
temp.size()
Output - torch.Size([6])

3)矩陣Matrix(2維張量)

from sklearn.datasets import load_boston
boston=load_boston()
boston_tensor = torch.from_numpy(boston.data) boston_tensor.size() Output: torch.Size([506, 13]) boston_tensor[:2] Output: Columns 0 to 7 0.0063 18.0000 2.3100 0.0000 0.5380 6.5750 65.2000 4.0900 0.0273 0.0000 7.0700 0.0000 0.4690 6.4210 78.9000 4.9671 Columns 8 to 12 1.0000 296.0000 15.3000 396.9000 4.9800 2.0000 242.0000 17.8000 396.9000 9.1400 [torch.DoubleTensor of size 2x13]

4)3維張量Tensor

一張圖片在內存空間中就是3維的。

from PIL import Image
import matplotlib.pyplot as plt
# Read a panda image from disk using a library called PIL and convert it to numpy array
panda = np.array(Image.open('panda.jpg').resize((224,224)))
panda_tensor = torch.from_numpy(panda)
panda_tensor.size()
Output - torch.Size([224, 224, 3])
#Display panda
plt.imshow(panda)

5)4維張量Tensor

一張圖片為3維的Tensor,4維的張量就是多張圖片的組合。使用GPU,我們可以一次性導入多張圖片用來訓練,導入的圖片張數取決於GPU內存大小,一般情況下,批量導入的大小為16,32,64。

#Read cat images from disk
cats = glob(data_path+'*.jpg')
#Convert images into numpy arrays
cat_imgs = np.array([np.array(Image.open(cat).resize((224,224))) for cat in cats[:64]])
cat_imgs = cat_imgs.reshape(-1,224,224,3)
cat_tensors = torch.from_numpy(cat_imgs)
cat_tensors.size()
Output - torch.Size([64, 224, 224, 3])

6)5維張量Tensor

視頻文件一般為5維的張量,在處理視頻時,我們通常是把視頻分解成一幀幀的圖片,可以存儲為[1,f,w,h,3]。而同時處理多個視頻時,就是5維張量。

7)  切片張量Slicing Tensor

sales = torch.FloatTensor([1000.0,323.2,333.4,444.5,1000.0,323.2,333.4,444.5])
sales[:5]
1000.0000
323.2000
333.4000
444.5000
1000.0000
[torch.FloatTensor of size 5]
sales[:-5]
1000.0000
323.2000
333.4000
[torch.FloatTensor of size 3]

顯示單維圖片:

plt.imshow(panda_tensor[:,:,0].numpy())
#0 represents the first channel of RGB

顯示裁剪圖片:

plt.imshow(panda_tensor[25:175,60:130,0].numpy())

生成一個全為1矩陣:

#torch.eye(shape) produces an diagonal matrix with 1 as it diagonal #elements.
sales = torch.eye(3,3)
sales[0,1]

8)GPU中張量Tensor

(1) TensorCPU操作

#Various ways you can perform tensor addition
a = torch.rand(2,2)
b = torch.rand(2,2)
c = a + b
d = torch.add(a,b)
#For in-place addition
a.add_(5)
#Multiplication of different tensors
a*b
a.mul(b)
#For in-place multiplication
a.mul_(b)

(2) TensorGPU操作

a = torch.rand(10000,10000)
b = torch.rand(10000,10000)
a.matmul(b)
Time taken: 3.23 s
#Move the tensors to GPU
a = a.cuda()
b = b.cuda()
a.matmul(b)
Time taken: 11.2 μs

3.2 變量

深度學習算法經常是以計算圖的形式出現,如下圖:

 一個梯度類描述如下:

 梯度是關於y=wx+b中(w,b)的損失函數的改變率。

import torch from torch.autograd import Variable
x =torch.autograd.Variable(torch.ones(2,2),requires_grad=True) 
y
= x.mean()
y.backward() #用於計算梯度
x.grad Variable
containing:
0.2500 0.2500 0.2500 0.2500 [torch.FloatTensor of size 2x2]
x.grad_fn
Output
- None
x.data
1 1 1 1 [torch.FloatTensor of size 2x2]
y.grad_fn
<torch.autograd.function.MeanBackward at 0x7f6ee5cfc4f8>

3.3 為自己搭建的模型准備數據

def get_data():
train_X = np.asarray([3.3,4.4,5.5,6.71,6.93,4.168,9.779,6.182,7.59,2.167,
7.042,10.791,5.313,7.997,5.654,9.27,3.1])
train_Y = np.asarray([1.7,2.76,2.09,3.19,1.694,1.573,3.366,2.596,2.53,1.221,
2.827,3.465,1.65,2.904,2.42,2.94,1.3])
dtype = torch.FloatTensor
X = Variable(torch.from_numpy(train_X).type(dtype),requires_grad=False).view(17,1)
y = Variable(torch.from_numpy(train_Y).type(dtype),requires_grad=False)
return X,y

3.4 搭建可學習參數

def get_weights():
w = Variable(torch.randn(1),requires_grad = True)
b = Variable(torch.randn(1),requires_grad = True)
return w,b

3.5 神經網絡模型

    一旦我們定義了輸入與輸出,接下來要做的就是搭建神經網絡模型。比如:y=wx+b,w和b就是可學習參數。

下圖是一個擬合好的模型:

 

 圖中藍色線為擬合好的線。

模型完成

def simple_network(x):
y_pred = torch.matmul(x,w)+b
return y_pred
f = nn.Linear(17,1) # Much simpler.

3.6 損失函數

基於本文所探討的回歸問題,我們采用了均方差SSE的損失函數。torch.nn 有損失函數MSE和交叉熵損失。

def loss_fn(y,y_pred):
    loss = (y_pred-y).pow(2).sum()
    for param in [w,b]:
        if not param.grad is None: param.grad.data.zero_()  #由於梯度需要計算多次,這里要定期的對梯度值進行清零。
        loss.backward()
    return loss.data[0]

3.7 優化神經網絡

損失函數計算完loss后,要對梯度值迭代計算更新,把梯度值和學習率代入進來,產生新的w,b。

def optimize(learning_rate):
w.data -= learning_rate * w.grad.data
b.data -= learning_rate * b.grad.data

不同的優化器如:Adam,RMSProp,SGD可以在torch.optim包中找到,可以使用這些優化器來減小損失從而提高精度。

3.8 加載數據

有兩種重要類:Dataset和DataLoader

3.8.1 Dataset

原子類:

from torch.utils.data import Dataset
class DogsAndCatsDataset(Dataset):
def __init__(self,):
    pass
def __len__(self):
    pass
def __getitem__(self,idx):
    pass

添加了部分內容:

class DogsAndCatsDataset(Dataset):
def __init__(self,root_dir,size=(224,224)):
    self.files = glob(root_dir)
    self.size = size
def __len__(self):
    return len(self.files)
def __getitem__(self,idx):
    img = np.asarray(Image.open(self.files[idx]).resize(self.size))
    label = self.files[idx].split('/')[-2]
return img,label

for image,label in dogsdset:
#Apply your DL on the dataset.

3.8.2 DataLoader

dataloader = DataLoader(dogsdset,batch_size=32,num_workers=2)
for imgs , labels in dataloader:
#Apply your DL on the dataset.
pass

Pytorch有兩個有用的包:torchvision,torchtext.

 

下一篇:

       如何入門Pytorch之二:如何搭建實用神經網絡


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM