pytorch卷積層與池化層輸出的尺寸的計算公式詳解
要設計卷積神經網絡的結構,必須匹配層與層之間的輸入與輸出的尺寸,這就需要較好的計算輸出尺寸
先列出公式:
卷積后,池化后尺寸計算公式:
(圖像尺寸-卷積核尺寸 + 2*填充值)/步長+1
(圖像尺寸-池化窗尺寸 + 2*填充值)/步長+1
即:
卷積神將網絡的計算公式為:
N=(W-F+2P)/S+1
其中
N:輸出大小
W:輸入大小
F:卷積核大小
P:填充值的大小
S:步長大小
例Conv2d(后面給出實例來講解計算方法):
`
class torch.nn.Conv2d(in_channels, out_channels, kernel_size, stride=1, padding=0, dilation=1, groups=1, bias=True)
卷積一層的幾個參數:
in_channels=3:表示的是輸入的通道數,RGB型的通道數是3.
out_channels:表示的是輸出的通道數,設定輸出通道數(這個是可以根據自己的需要來設置的)
kernel_size=12:表示卷積核的大小是12x12的,也就是上面的 F=12
stride=4:表示的是步長為4,也就是上面的S=4
padding=2:表示的是填充值的大小為2,也就是上面的P=2
實例:
cove1d:用於文本數據,只對寬度進行卷積,對高度不進行卷積
cove2d:用於圖像數據,對寬度和高度都進行卷積
import torch
from torch.autograd import Variable
#torch.autograd提供了類和函數用來對任意標量函數進行求導。
import torch.nn as nn
import torch.nn.functional as F
class MNISTConvNet(nn.Module):
def __init__(self):
super(MNISTConvNet, self).__init__()
'''
這是對繼承自父類的屬性進行初始化。而且是用父類的初始化方法來初始化繼承的屬性。
也就是說,子類繼承了父類的所有屬性和方法,父類屬性自然會用父類方法來進行初始化。
'''
#定義網絡結構
self.conv1 = nn.Conv2d(1, 10, 5)
self.pool1 = nn.MaxPool2d(2, 2)
self.conv2 = nn.Conv2d(10, 20, 5)
self.pool2 = nn.MaxPool2d(2, 2)
self.fc1 = nn.Linear(320, 50)
self.fc2 = nn.Linear(50, 10)
def forward(self, input):
x = self.pool1(F.relu(self.conv1(input)))
x = self.pool2(F.relu(self.conv2(x))).view(320)
x = self.fc2(self.fc1(x))
return x
net = MNISTConvNet()
print(net)
input = Variable(torch.randn(1, 1, 28, 28))
out = net(input)
print(out.size())
我們在這個實例中抽出網絡結構部分:
self.conv1 = nn.Conv2d(1, 10, 5)
self.pool1 = nn.MaxPool2d(2, 2)
self.conv2 = nn.Conv2d(10, 20, 5)
self.pool2 = nn.MaxPool2d(2, 2)
self.fc1 = nn.Linear(320, 50)
self.fc2 = nn.Linear(50, 10)
def forward(self, input):
x = self.pool1(F.relu(self.conv1(input)))
x = self.pool2(F.relu(self.conv2(x))).view(320)
x = self.fc2(self.fc1(x))
網絡結構為:
conv2d--maxpool2d--conv2d--maxpool2d--fullyconnect--fullyconnect
輸入圖片大小為:input = Variable(torch.randn(1, 1, 28, 28))
即28*28的單通道圖片,即:12828
接下來,我們分層解析每一層網絡的輸入和輸出:
(1)conv2d(1,10,5)
N:輸出大小
W:輸入大小 28*28
F:卷積核大小 5*5
P:填充值的大小 0默認值
S:步長大小 1默認值
N=(W-F+2P)/S+1=(28-5 + 2*0)/1 + 1 = 24
輸出為:10*24*24
Conv2d(輸入通道數, 輸出通道數, kernel_size(長和寬)),當卷積核為方形時,只寫一個就可以,卷積核不是方形時,長和寬都要寫,如下:
self.conv1 = nn.Conv2d(2, 4, (5,2))
(2)MaxPool2d(2, 2)
MaxPool 最大池化層,池化層在卷積神經網絡中的作用在於特征融合和降維。池化也是一種類似的卷積操作,只是池化層的所有參數都是超參數,是學習不到的。maxpooling有局部不變性而且可以提取顯著特征的同時降低模型的參數,從而降低模型的過擬合。只提取了顯著特征,而舍棄了不顯著的信息,是的模型的參數減少了,從而一定程度上可以緩解過擬合的產生。
class torch.nn.MaxPool2d(kernel_size, stride=None, padding=0, dilation=1, return_indices=False, ceil_mode=False)
N:輸出大小
W:輸入大小 24*24
F:卷積核大小 5*5
P:填充值的大小 0默認值
S:步長大小 1默認值
N=(W-F+2P)/S+1=(24-2 + 2*0)/2 + 1 = 12
輸出為:10*12*12
(3)conv2d(10,20,5)
N:輸出大小
W:輸入大小 12*12
F:卷積核大小 5*5
P:填充值的大小 0默認值
S:步長大小 1默認值
N=(W-F+2P)/S+1=(12-5 + 2*0)/1 + 1 = 8
輸出為:20*8*8
(4)MaxPool2d(2, 2)
N:輸出大小
W:輸入大小 8*8
F:卷積核大小 5*5
P:填充值的大小 0默認值
S:步長大小 1默認值
N=(W-F+2P)/S+1=(8-2 + 2*0)/2 + 1 = 4
輸出為:20*4*4
(5)fully-connect Linear(320, 50)
輸入:20*4*4=320
輸出:50
(6)fully-connect Linear(50, 10)
輸入:50
輸出:10
所以,整個實例的訓練過程數據流動為:
def forward(self, input):
x = self.pool1(F.relu(self.conv1(input)))
x = self.pool2(F.relu(self.conv2(x)))
x = self.fc2(self.fc1(x))
激活函數Relu,在神經網絡中的作用是:通過加權的輸入進行非線性組合產生非線性決策邊界
簡單的來說就是增加非線性作用。
在深層卷積神經網絡中使用激活函數同樣也是增加非線性,主要是為了解決sigmoid函數帶來的梯度消失問題。