前言
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.
下一篇: