Task05:卷積神經網絡基礎;leNet;卷積神經網絡進階

一、卷積神經網絡基礎

本節我們介紹卷積神經網絡的基礎概念,主要是卷積層和池化層,並解釋填充、步幅、輸入通道和輸出通道的含義。

二維卷積層

本節介紹的是最常見的二維卷積層,常用於處理圖像數據。

二維互相關運算

二維互相關(cross-correlation)運算的輸入是一個二維輸入數組和一個二維核(kernel)數組,輸出也是一個二維數組,其中核數組通常稱爲卷積核或過濾器(filter)。卷積核的尺寸通常小於輸入數組,卷積核在輸入數組上滑動,在每個位置上,卷積核與該位置處的輸入子數組按元素相乘並求和,得到輸出數組中相應位置的元素。圖1展示了一個互相關運算的例子,陰影部分分別是輸入的第一個計算區域、核數組以及對應的輸出。

下面我們用corr2d函數實現二維互相關運算,它接受輸入數組X與核數組K,並輸出數組Y

import torch 
import torch.nn as nn

def corr2d(X, K):
    H, W = X.shape
    h, w = K.shape
    Y = torch.zeros(H - h + 1, W - w + 1)
    for i in range(Y.shape[0]):
        for j in range(Y.shape[1]):
            Y[i, j] = (X[i: i + h, j: j + w] * K).sum()
    return Y

構造上圖中的輸入數組X、核數組K來驗證二維互相關運算的輸出。

X = torch.tensor([[0, 1, 2], [3, 4, 5], [6, 7, 8]])
K = torch.tensor([[0, 1], [2, 3]])
Y = corr2d(X, K)
print(Y)

結果

tensor([[19., 25.],
        [37., 43.]])

二維卷積層

二維卷積層將輸入和卷積核做互相關運算,並加上一個標量偏置來得到輸出。卷積層的模型參數包括卷積核和標量偏置。

class Conv2D(nn.Module):
    def __init__(self, kernel_size):
        super(Conv2D, self).__init__()
        self.weight = nn.Parameter(torch.randn(kernel_size))
        self.bias = nn.Parameter(torch.randn(1))

    def forward(self, x):
        return corr2d(x, self.weight) + self.bias

下面我們看一個例子,我們構造一張6×86×8的圖像,中間4列爲黑(0),其餘爲白(1),希望檢測到顏色邊緣。我們的標籤是一個6×76×7的二維數組,第2列是1(從1到0的邊緣),第6列是-1(從0到1的邊緣)。

X = torch.ones(6, 8)
Y = torch.zeros(6, 7)
X[:, 2: 6] = 0
Y[:, 1] = 1
Y[:, 5] = -1
print(X)
print(Y)

結果

tensor([[1., 1., 0., 0., 0., 0., 1., 1.],
        [1., 1., 0., 0., 0., 0., 1., 1.],
        [1., 1., 0., 0., 0., 0., 1., 1.],
        [1., 1., 0., 0., 0., 0., 1., 1.],
        [1., 1., 0., 0., 0., 0., 1., 1.],
        [1., 1., 0., 0., 0., 0., 1., 1.]])
tensor([[ 0.,  1.,  0.,  0.,  0., -1.,  0.],
        [ 0.,  1.,  0.,  0.,  0., -1.,  0.],
        [ 0.,  1.,  0.,  0.,  0., -1.,  0.],
        [ 0.,  1.,  0.,  0.,  0., -1.,  0.],
        [ 0.,  1.,  0.,  0.,  0., -1.,  0.],
        [ 0.,  1.,  0.,  0.,  0., -1.,  0.]])

我們希望學習一個1×21×2卷積層,通過卷積層來檢測顏色邊緣。

conv2d = Conv2D(kernel_size=(1, 2))
step = 30
lr = 0.01
for i in range(step):
    Y_hat = conv2d(X)
    l = ((Y_hat - Y) ** 2).sum()
    l.backward()
    # 梯度下降
    conv2d.weight.data -= lr * conv2d.weight.grad
    conv2d.bias.data -= lr * conv2d.bias.grad
    
    # 梯度清零
    conv2d.weight.grad.zero_()
    conv2d.bias.grad.zero_()
    if (i + 1) % 5 == 0:
        print('Step %d, loss %.3f' % (i + 1, l.item()))
        
print(conv2d.weight.data)
print(conv2d.bias.data)

結果

Step 5, loss 4.569
Step 10, loss 0.949
Step 15, loss 0.228
Step 20, loss 0.060
Step 25, loss 0.016
Step 30, loss 0.004
tensor([[ 1.0161, -1.0177]])
tensor([0.0009])

互相關運算與卷積運算

卷積層得名於卷積運算,但卷積層中用到的並非卷積運算而是互相關運算。我們將核數組上下翻轉、左右翻轉,再與輸入數組做互相關運算,這一過程就是卷積運算。由於卷積層的核數組是可學習的,所以使用互相關運算與使用卷積運算並無本質區別。

特徵圖與感受野

二維卷積層輸出的二維數組可以看作是輸入在空間維度(寬和高)上某一級的表徵,也叫特徵圖(feature map)。影響元素xx的前向計算的所有可能輸入區域(可能大於輸入的實際尺寸)叫做xx的感受野(receptive field)。

以圖1爲例,輸入中陰影部分的四個元素是輸出中陰影部分元素的感受野。我們將圖中形狀爲2×22×2的輸出記爲Y,將Y與另一個形狀爲2×22×2的核數組做互相關運算,輸出單個元素zz。那麼,zz在YY上的感受野包括YY的全部四個元素,在輸入上的感受野包括其中全部9個元素。可見,我們可以通過更深的卷積神經網絡使特徵圖中單個元素的感受野變得更加廣闊,從而捕捉輸入上更大尺寸的特徵。

填充和步幅

我們介紹卷積層的兩個超參數,即填充和步幅,它們可以對給定形狀的輸入和卷積核改變輸出形狀。

填充

填充(padding)是指在輸入高和寬的兩側填充元素(通常是0元素),圖2裏我們在原輸入高和寬的兩側分別添加了值爲0的元素。

步幅

在互相關運算中,卷積核在輸入數組上滑動,每次滑動的行數與列數即是步幅(stride)。此前我們使用的步幅都是1,圖3展示了在高上步幅爲3、在寬上步幅爲2的二維互相關運算。

多輸入通道和多輸出通道

之前的輸入和輸出都是二維數組,但真實數據的維度經常更高。例如,彩色圖像在高和寬2個維度外還有RGB(紅、綠、藍)3個顏色通道。假設彩色圖像的高和寬分別是hh和ww(像素),那麼它可以表示爲一個3×h×w的多維數組,我們將大小爲3的這一維稱爲通道(channel)維。

多輸入通道

卷積層的輸入可以包含多個通道,圖4展示了一個含2個輸入通道的二維互相關計算的例子。

1×1卷積核可在不改變高寬的情況下,調整通道數。1×1卷積核不識別高和寬維度上相鄰元素構成的模式,其主要計算髮生在通道維上。假設我們將通道維當作特徵維,將高和寬維度上的元素當成數據樣本,那麼1×1卷積層的作用與全連接層等價。

X = torch.rand(4, 2, 3, 5)
print(X.shape)

conv2d = nn.Conv2d(in_channels=2, out_channels=3, kernel_size=(3, 5), stride=1, padding=(1, 2))
Y = conv2d(X)
print('Y.shape: ', Y.shape)
print('weight.shape: ', conv2d.weight.shape)
print('bias.shape: ', conv2d.bias.shape)

結果

torch.Size([4, 2, 3, 5])
Y.shape:  torch.Size([4, 3, 3, 5])
weight.shape:  torch.Size([3, 2, 3, 5])
bias.shape:  torch.Size([3])

池化

二維池化層

池化層主要用於緩解卷積層對位置的過度敏感性。同卷積層一樣,池化層每次對輸入數據的一個固定形狀窗口(又稱池化窗口)中的元素計算輸出,池化層直接計算池化窗口內元素的最大值或者平均值,該運算也分別叫做最大池化或平均池化。圖6展示了池化窗口形狀爲2×22×2的最大池化。

二維平均池化的工作原理與二維最大池化類似,但將最大運算符替換成平均運算符。池化窗口形狀爲p×q的池化層稱爲p×qp×q池化層,其中的池化運算叫作p×qp×q池化。

池化層也可以在輸入的高和寬兩側填充並調整窗口的移動步幅來改變輸出形狀。池化層填充和步幅與卷積層填充和步幅的工作機制一樣。

在處理多通道輸入數據時,池化層對每個輸入通道分別池化,但不會像卷積層那樣將各通道的結果按通道相加。這意味着池化層的輸出通道數與輸入通道數相等。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

發佈了116 篇原創文章 · 獲贊 96 · 訪問量 7萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章