卷積層設置及輸出大小計算


參考自:https://blog.csdn.net/sinat_42239797/article/details/90646935

1.卷積神經網絡的結構

卷積神經網絡(CNN)由輸入層、卷積層、激活函數、池化層、全連接層組成,

即INPUT(輸入層)-CONV(卷積層)-RELU(激活函數)-POOL(池化層)-FC(全連接層)

在這里插入圖片描述

2.卷積神經網絡的計算

計算公式為:

\[N = (W-F+2P)/S+1 \]

其中:

  • N:輸出大小
  • W:輸入大小
  • F:卷積核大小
  • P:填充值大小
  • S:步長大小

比如:

nn.Conv2d(in_channels=3,out_channels=96,kernel_size=11,stride=4,padding=2)

卷積一層的幾個參數:

  • in_channels=3:表示輸入的通道數。由於是RGB類型,所以通道數為3
  • out_channels=96:表示輸出的通道數,設定輸出通道數的96(可以根據自己的需要來設置)
  • kernel_size=12:表示卷積核的大小是12x12的,也就是上面的F=12
  • stride=4:表示步長為4,也就是S=4
  • padding=2:表示填充值的大小為2,也就是P=2

3.以AlexNet為例進行詳解

AlexNet網絡結構圖如下圖所示:

img

可以看出該網絡有8層:5個卷積層,3個全連接層。

卷積神經網絡的設置包括卷積層的設置以及正反向傳播的設置
卷積層的設置代碼如下:

self.conv1 = torch.nn.Sequential(   #input_size = 227*227*3
        torch.nn.Conv2d(in_channels=3,out_channels=96,kernel_size=11,stride=4,padding=0),
        torch.nn.ReLU(),
        torch.nn.MaxPool2d(kernel_size=3, stride=2) #output_size = 27*27*96
    )
self.conv2 = torch.nn.Sequential(   #input_size = 27*27*96
        torch.nn.Conv2d(96, 256, 5, 1, 2),
        torch.nn.ReLU(),
        torch.nn.MaxPool2d(3, 2)    #output_size = 13*13*256
    )
self.conv3 = torch.nn.Sequential(   #input_size = 13*13*256
        torch.nn.Conv2d(256, 384, 3, 1, 1),
        torch.nn.ReLU(),    #output_size = 13*13*384
    )
self.conv4 = torch.nn.Sequential(   #input_size = 13*13*384
        torch.nn.Conv2d(384, 384, 3, 1, 1),
        torch.nn.ReLU(),    #output_size = 13*13*384
    )
self.conv5 = torch.nn.Sequential(   #input_size = 13*13*384
        torch.nn.Conv2d(384, 256, 3, 1, 1),
        torch.nn.ReLU(),
        torch.nn.MaxPool2d(3, 2)    #output_size = 6*6*256
    )

self.dense = torch.nn.Sequential(
    torch.nn.Linear(9216, 4096),
    torch.nn.ReLU(),
    torch.nn.Dropout(0.5),
    torch.nn.Linear(4096, 4096),
    torch.nn.ReLU(),
    torch.nn.Dropout(0.5),
    torch.nn.Linear(4096, 50)
)

卷積一層

self.conv1 = torch.nn.Sequential(   #input_size = 227*227*3
            torch.nn.Conv2d(in_channels=3,out_channels=96,kernel_size=11,stride=4,padding=0),
            torch.nn.ReLU(),
            torch.nn.MaxPool2d(kernel_size=3, stride=2) #output_size = 27*27*96
        )

可以看到輸入為227x227x3,也就是說size為227x227,通道數為3,為RGB圖像。

torch.nn.Conv2d(in_channels=3,out_channels=96,kernel_size=11,stride=4,padding=0)

可以計算得到輸出結果為:\(N = (227-11+2\times0)/4+1=55\),即卷積后的尺寸是55x55x96的。

注:其中的96是48x2=96看圖第一層是有上下兩個部分,每個部分是寬是48,所有一共是96個卷積核。

torch.nn.ReLU()

使用激活函數ReLU,在神經元中的作用的:通過加權的輸入進行非線性組合產生非線性決策邊界。簡單的來說就是增加非線性作用。

在深層卷積神經網絡中使用激活函數同樣也是增加非線性,主要是為了解決sigmoid函數帶來的梯度消失問題。

 torch.nn.MaxPool2d(kernel_size=3, stride=2) #output_size = 27*27*96

MaxPool 最大池化層,池化層在卷積神經網絡中的作用在於特征融合和降維。池化也是一種類似的卷積操作,只是池化層的所有參數都是超參數,是學習不到的。

這里的最大池化操作:將2x2尺寸內的所有像素值取最大值作為輸出通道的像素值。

輸出大小的計算和卷積層的計算過程一樣:\(N=(W-F+2P)/S+1=(55-3+2\times0)/2+1=27\)

則輸出為27x27x96

卷積二層

self.conv2 = torch.nn.Sequential(   #input_size = 27*27*96
    torch.nn.Conv2d(96, 256, 5, 1, 2),
    torch.nn.ReLU(),
    torch.nn.MaxPool2d(3, 2)    #output_size = 13*13*256
)

可以看到卷積2層的輸入為96x27x27的,也就是上一層的輸出,從這里也就知道,上一層的輸出為下一層的輸入。

卷積2層的計算過程和卷積1層的計算過程是一樣的,具體不詳細描述
卷積2層最終輸出為13x13x256,本層的神經元數目為27x27x256 =186642個
卷積3層最終輸出為13x13x384,本層的神精元數目為13x13x384 =64896個
卷積4層最終輸出為13x13x384,本層的神精元數目為13x13x384 = 64896個
卷積5層最終輸出為6x6x256,本層的神精元數目為6x6x256=9216個

全連接層

全連接層的作用主要是負責邏輯推斷,所有的參數都必須學習得到。

self.dense = torch.nn.Sequential(
        torch.nn.Linear(9216, 4096),
        torch.nn.ReLU(),
        torch.nn.Dropout(0.5),
        torch.nn.Linear(4096, 4096),
        torch.nn.ReLU(),
        torch.nn.Dropout(0.5),
        torch.nn.Linear(4096, 50)
    )

由結構圖可以看到有3層全連接層

第一層全連接層(第六層)

作用:

  1. 鏈接卷積層的輸出
  2. 去除空間信息(通道數),將三維矩陣轉變為向量。

其操作可以看成是輸入圖像為\(W\times H\times C\),卷積核的尺寸為\(W\times H\times C\),這樣卷積后的尺寸為\(1\times 1\times 1\),這樣整個圖像變成了一個數,一共有K個數(第一層全連接層后的神經元數)。

第六層輸入數據的尺寸是6x6x256,采用6x6x256尺寸的濾波器對第六層的輸入數據進行卷積運算;每個6x6x256尺寸的濾波器對第六層的輸入數據進行卷積運算生成一個運算結果,通過一個神經元輸出這個運算結果;共有4096個6x6x256尺寸的濾波器對輸入數據進行卷積,通過4096個神經元的輸出運算結果;然后通過ReLU激活函數以及dropout運算輸出4096個本層的輸出結果值。

第二層全連接層(第七層)

第6層輸出的4096個數據與第7層的4096個神經元進行全連接,然后經由ReLU和Dropout進行處理后生成4096個數據。

第三層全連接層(第八層)

第7層輸入的4096個數據與第8層的50個神經元進行全連接,經過訓練后輸出被訓練的數值。

正向傳播的順序設置

def forward(self, x):   #正向傳播過程
    conv1_out = self.conv1(x)
    conv2_out = self.conv2(conv1_out)
    conv3_out = self.conv3(conv2_out)
    conv4_out = self.conv4(conv3_out)
    conv5_out = self.conv5(conv4_out)
    '''
    x.view(x.size(0), -1)的用法:
	在CNN中,因為卷積或者池化之后需要連接全連接層,所以需要把多維度的tensor展平成一維,因此用它來實現(其實就是將多維數據展平為一維數據方便后面的全連接層處理)
    '''
    res = conv5_out.view(conv5_out.size(0), -1)
    out = self.dense(res)
    return out

常見的卷積層設置問題

  1. 為什么是cove2d?

    cove1d:用於文本數據,只對寬度進行卷積,對高度不進行卷積
    cove2d:用於圖像數據,對寬度和高度都進行卷積

  2. 為什么卷積核大小5x5寫一個5?

    Conv2d(輸入通道數, 輸出通道數, kernel_size(長和寬)),當卷積核為方形時,只寫一個就可以
    卷積核不是方形時,長和寬都要寫:

    self.conv1 = nn.Conv2d(3, 6, (5,3))
    
  3. 池化層的作用

    maxpooling有局部不變性而且可以提取顯著特征的同時降低模型的參數,從而降低模型的過擬合。
    因為只是提取了顯著特征,而舍棄了不顯著的信息,使得模型的參數減少了,從而一定程度上可以緩解過擬合的產生。


免責聲明!

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



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