1. 程式人生 > >PyTorch教程之Neural Networks

PyTorch教程之Neural Networks

進行 print 數據 圖像 使用 數字圖像 -1 idt work

我們可以通過torch.nn package構建神經網絡。

現在我們已經了解了autograd,nn基於autograd來定義模型並對他們有所區分。

一個 nn.Module模塊由如下部分構成:若幹層,以及返回output的forward(input)方法。

例如,這張圖描述了進行數字圖像分類的神經網絡:

技術分享

這是一個簡單的前饋( feed-forward)網絡,讀入input內容,每層接受前一級的輸入,並輸出到下一級,直到給出outpu結果。

一個經典神經網絡的訓練程序如下:

1.定義具有可學習參數(或權重)的神經網絡

2.遍歷iinput數據集

3.通過神經網絡對input進行處理得到output結果

4.計算損失(ouput離正確值有多遠)

5.將梯度返回到神經網絡的參數中

6.更新神經網絡的權重,通常使用一個簡單的更新規則:

weight = weight - learning_rate * gradient

一、如何在pytorch中定義神經網絡

定義神經網絡:

import torch
from torch.autograd import Variable
import torch.nn as nn
import torch.nn.functional as F

class Net(nn.Module):
    # 定義Net的初始化函數,本函數定義了神經網絡的基本結構
def __init__(self): # 繼承父類的初始化方法,即先運行nn.Module的初始化函數 super(Net,self).__init__() # 定義卷積層:輸入1通道(灰度圖)的圖片,輸出6張特征圖,卷積核5x5 self.conv1 = nn.Conv2d(1,6,(5,5)) # 定義卷積層:輸入6張特征圖,輸出16張特征圖,卷積核5x5 self.conv2 = nn.Conv2d(6,16,5) # 定義全連接層:線性連接(y = Wx + b),16*5*5個節點連接到120個節點上
self.fc1 = nn.Linear(16*5*5,120) # 定義全連接層:線性連接(y = Wx + b),120個節點連接到84個節點上 self.fc2 = nn.Linear(120,84) # 定義全連接層:線性連接(y = Wx + b),84個節點連接到10個節點上 self.fc3 = nn.Linear(84,10) # 定義向前傳播函數,並自動生成向後傳播函數(autograd) def forward(self,x): # 輸入x->conv1->relu->2x2窗口的最大池化->更新到x x = F.max_pool2d(F.relu(self.conv1(x)),(2,2)) # 如果大小是一個正方形,可以只指定一個數字 x = F.max_pool2d(F.relu(self.conv2(x)),2) # view函數將張量x變形成一維向量形式,總特征數不變,為全連接層做準備 x = x.view(-1,self.num_flat_features(x)) # 輸入x->fc1->relu,更新到x x = F.relu(self.fc1(x)) # 輸入x->fc2->relu,更新到x x = F.relu(self.fc2(x)) # 輸入x->fc3,更新到x x = self.fc3(x) return x # 計算張量x的總特征量 def num_flat_features(selfself,x): # 由於默認批量輸入,第零維度的batch剔除 size = x.size()[1:] num_features = 1 for s in size: num_features *= s return num_features net = Net() print(net)

輸出結果:

Net (
  (conv1): Conv2d(1, 6, kernel_size=(5, 5), stride=(1, 1))
  (conv2): Conv2d(6, 16, kernel_size=(5, 5), stride=(1, 1))
  (fc1): Linear (400 -> 120)
  (fc2): Linear (120 -> 84)
  (fc3): Linear (84 -> 10)
)

通過net.parameters()可以得到可學習的參數:

params = list(net.parameters())
print(len(params))
print(params[0].size())  # conv1‘s .weight

輸出結果:

10
torch.Size([6, 1, 5, 5])

我們模擬一下單向傳播,其中input和output均為autograd.Variable:

input = Variable(torch.randn(1, 1, 32, 32))
out = net(input)
print(out)

輸出結果:

Variable containing:
-0.0618 -0.0648 -0.0350  0.0443  0.0633 -0.0414  0.0317 -0.1100 -0.0569 -0.0636
[torch.FloatTensor of size 1x10]

對所有參數的梯度緩沖區歸零並設置隨機梯度反向傳播:

net.zero_grad()
out.backward(torch.randn(1, 10))

整個torch.nn包只接受那種小批量樣本的數據,而無法接受單個樣本。 例如,nn.Conv2d能夠構建一個四維的Tensor:nSamples x nChannels x Height x Width。

如果需要對單個樣本進行操作,使用input.unsqueeze(0)來加一個假維度就可以了。

我們回顧一下目前出現過的概念:

torch.Tensor - 一個多維數組
autograd.Variable - 改變Tensor並且記錄下來歷史操作過程。和Tensor擁有相同的API,以及backward()的一些API。同時包含著和Tensor 相關的梯度。
nn.Module - 神經網絡模塊。便捷的數據封裝,能夠將運算移往GPU,還包括一些輸入輸出的東西。
nn.Parameter - 一種變量(Variable),當將任何值賦予Module時自動註冊為一個參數。
autograd.Function - 實現了使用自動求導方法的前饋和後饋的定義。每個Variable的操作都會生成至少一個獨立的Function節點,與生成了Variable的函數相連之後記錄下歷史操作過程。

二、Loss Function

PyTorch教程之Neural Networks