PyTorch 神經(jīng)網(wǎng)絡(luò)

  • PyTorch 神經(jīng)網(wǎng)絡(luò)

神經(jīng)網(wǎng)絡(luò)

神經(jīng)網(wǎng)絡(luò)可以通過 torch.nn 包來構(gòu)建。

現(xiàn)在對于自動梯度(autograd)有一些了解,神經(jīng)網(wǎng)絡(luò)是基于自動梯度 (autograd)來定義一些模型。一個 nn.Module 包括層和一個方法 forward(input) 它會返回輸出(output)。

例如,看一下數(shù)字圖片識別的網(wǎng)絡(luò):

image

這是一個簡單的前饋神經(jīng)網(wǎng)絡(luò),它接收輸入,讓輸入一個接著一個的通過一些層,最后給出輸出。

一個典型的神經(jīng)網(wǎng)絡(luò)訓(xùn)練過程包括以下幾點:

1.定義一個包含可訓(xùn)練參數(shù)的神經(jīng)網(wǎng)絡(luò)

2.迭代整個輸入

3.通過神經(jīng)網(wǎng)絡(luò)處理輸入

4.計算損失(loss)

5.反向傳播梯度到神經(jīng)網(wǎng)絡(luò)的參數(shù)

6.更新網(wǎng)絡(luò)的參數(shù),典型的用一個簡單的更新方法:weight = weight - learning_rate *gradient

定義神經(jīng)網(wǎng)絡(luò)


import torch
import torch.nn as nn
import torch.nn.functional as F

class Net(nn.Module):

    def __init__(self):
        super(Net, self).__init__()
        # 1 input image channel, 6 output channels, 5x5 square convolution
        # kernel
        self.conv1 = nn.Conv2d(1, 6, 5)
        self.conv2 = nn.Conv2d(6, 16, 5)
        # an affine operation: y = Wx + b
        self.fc1 = nn.Linear(16 * 5 * 5, 120)
        self.fc2 = nn.Linear(120, 84)
        self.fc3 = nn.Linear(84, 10)

    def forward(self, x):
        # Max pooling over a (2, 2) window
        x = F.max_pool2d(F.relu(self.conv1(x)), (2, 2))
        # If the size is a square you can only specify a single number
        x = F.max_pool2d(F.relu(self.conv2(x)), 2)
        x = x.view(-1, self.num_flat_features(x))
        x = F.relu(self.fc1(x))
        x = F.relu(self.fc2(x))
        x = self.fc3(x)
        return x

    def num_flat_features(self, x):
        size = x.size()[1:]  # all dimensions except the batch dimension
        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(in_features=400, out_features=120, bias=True)
  (fc2): Linear(in_features=120, out_features=84, bias=True)
  (fc3): Linear(in_features=84, out_features=10, bias=True)
)

你剛定義了一個前饋函數(shù),然后反向傳播函數(shù)被自動通過 autograd 定義了。你可以使用任何張量操作在前饋函數(shù)上。

一個模型可訓(xùn)練的參數(shù)可以通過調(diào)用 net.parameters() 返回:


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

輸出:

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

讓我們嘗試隨機生成一個 32x32 的輸入。注意:期望的輸入維度是 32x32 。為了使用這個網(wǎng)絡(luò)在 MNIST 數(shù)據(jù)及上,你需要把數(shù)據(jù)集中的圖片維度修改為 32x32。


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

輸出:


tensor([[-0.0233,  0.0159, -0.0249,  0.1413,  0.0663,  0.0297, -0.0940, -0.0135,
          0.1003, -0.0559]], grad_fn=<AddmmBackward>)

把所有參數(shù)梯度緩存器置零,用隨機的梯度來反向傳播


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

在繼續(xù)之前,讓我們復(fù)習(xí)一下所有見過的類。

torch.Tensor - A multi-dimensional array with support for autograd operations like backward(). Also holds the gradient w.r.t. the tensor. nn.Module - Neural network module. Convenient way of encapsulating parameters, with helpers for moving them to GPU, exporting, loading, etc. nn.Parameter - A kind of Tensor, that is automatically registered as a parameter when assigned as an attribute to a Module. autograd.Function - Implements forward and backward definitions of an autograd operation. Every Tensor operation, creates at least a single Function node, that connects to functions that created a Tensor and encodes its history.

在此,我們完成了:

1.定義一個神經(jīng)網(wǎng)絡(luò)

2.處理輸入以及調(diào)用反向傳播

還剩下:

1.計算損失值

2.更新網(wǎng)絡(luò)中的權(quán)重

損失函數(shù)

一個損失函數(shù)需要一對輸入:模型輸出和目標(biāo),然后計算一個值來評估輸出距離目標(biāo)有多遠(yuǎn)。

有一些不同的損失函數(shù)在 nn 包中。一個簡單的損失函數(shù)就是 nn.MSELoss ,這計算了均方誤差。

例如:

output = net(input)
target = torch.randn(10)  # a dummy target, for example
target = target.view(1, -1)  # make it the same shape as output
criterion = nn.MSELoss()

loss = criterion(output, target)
print(loss)

輸出:

tensor(1.3389, grad_fn=<MseLossBackward>)

現(xiàn)在,如果你跟隨損失到反向傳播路徑,可以使用它的 .grad_fn 屬性,你將會看到一個這樣的計算圖:

input -> conv2d -> relu -> maxpool2d -> conv2d -> relu -> maxpool2d
      -> view -> linear -> relu -> linear -> relu -> linear
      -> MSELoss
      -> loss

所以,當(dāng)我們調(diào)用 loss.backward(),整個圖都會微分,而且所有的在圖中的requires_grad=True 的張量將會讓他們的 grad 張量累計梯度。

為了演示,我們將跟隨以下步驟來反向傳播。

print(loss.grad_fn)  # MSELoss
print(loss.grad_fn.next_functions[0][0])  # Linear
print(loss.grad_fn.next_functions[0][0].next_functions[0][0])  # ReLU

輸出:

<MseLossBackward object at 0x7fab77615278>
<AddmmBackward object at 0x7fab77615940>
<AccumulateGrad object at 0x7fab77615940>

反向傳播

為了實現(xiàn)反向傳播損失,我們所有需要做的事情僅僅是使用 loss.backward()。你需要清空現(xiàn)存的梯度,要不然帝都將會和現(xiàn)存的梯度累計到一起。

現(xiàn)在我們調(diào)用 loss.backward() ,然后看一下 con1 的偏置項在反向傳播之前和之后的變化。

net.zero_grad()     # zeroes the gradient buffers of all parameters

print('conv1.bias.grad before backward')
print(net.conv1.bias.grad)

loss.backward()

print('conv1.bias.grad after backward')
print(net.conv1.bias.grad)

輸出:

conv1.bias.grad before backward
tensor([0., 0., 0., 0., 0., 0.])
conv1.bias.grad after backward
tensor([-0.0054,  0.0011,  0.0012,  0.0148, -0.0186,  0.0087])

現(xiàn)在我們看到了,如何使用損失函數(shù)。

唯一剩下的事情就是更新神經(jīng)網(wǎng)絡(luò)的參數(shù)。

更新神經(jīng)網(wǎng)絡(luò)參數(shù):

最簡單的更新規(guī)則就是隨機梯度下降。

weight = weight - learning_rate * gradient

我們可以使用 python 來實現(xiàn)這個規(guī)則:

learning_rate = 0.01
for f in net.parameters():
    f.data.sub_(f.grad.data * learning_rate)

盡管如此,如果你是用神經(jīng)網(wǎng)絡(luò),你想使用不同的更新規(guī)則,類似于 SGD, Nesterov-SGD, Adam, RMSProp, 等。為了讓這可行,我們建立了一個小包:torch.optim 實現(xiàn)了所有的方法。使用它非常的簡單。

import torch.optim as optim

# create your optimizer
optimizer = optim.SGD(net.parameters(), lr=0.01)

# in your training loop:
optimizer.zero_grad()   # zero the gradient buffers
output = net(input)
loss = criterion(output, target)
loss.backward()
optimizer.step()    # Does the update

下載 Python 源代碼:

neural_networks_tutorial.py

下載 Jupyter 源代碼:

neural_networks_tutorial.ipynb

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容