先看Pytorch中的卷積
class torch.nn.Conv2d(in_channels, out_channels, kernel_size, stride=1, padding=0, dilation=1, groups=1, bias=True)
二維卷積層, 輸入的尺度是(N, C_in,H,W),輸出尺度(N,C_out,H_out,W_out)的計算方式

這里比較奇怪的是這個卷積層居然沒有定義input shape,輸入尺寸明明是:(N, C_in, H,W),但是定義中卻只需要輸入in_channel的size,就能完成卷積,那是不是說這樣任意size的image都可以進行卷積呢?
然后我進行了下面這樣的實驗:
importtorch
importtorch.nn as nn
importtorch.nn.functional as F
classNet(nn.Module):
def__init__(self):
super(Net, self).__init__()
# 輸入圖像channel:1;輸出channel:6;5x5卷積核
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)
defforward(self, x):
# 2x2 Max pooling
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)
returnx
defnum_flat_features(self, x):
size =x.size()[1:] # 除去批大小維度的其余維度
num_features =1
fors insize:
num_features *=s
returnnum_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)
)
官網Tutorial 說:這個網絡(LeNet)的期待輸入是32x32,我就比較奇怪他又沒有設置Input shape或者Tensorflow里的Input層,怎么就知道(H,W) =(32, 32)。
輸入:
input = torch.randn(1, 1, 32, 32)
output = Net(input)
沒問題,但是
input = torch.randn(1, 1, 64, 64)
output = Net(input)
出現:mismatch Error
我們看一下卷積模型部分。
input:(1, 1, 32, 32) --> conv1(1, 6, 5) --> (1, 6, 28, 28) --> max_pool1(2, 2) --> (1, 6, 14, 14) --> conv2(6, 16, 5) -->(1, 16, 10, 10) --> max_pool2(2, 2) --> (1, 16, 5, 5)
然后是將其作為一個全連接網絡的輸入。Linear相當於tensorflow 中的Dense。所以當你的輸入尺寸不為(32, 32)時,卷積得到最終feature map shape就不是(None, 16, 5, 5),而我們的第一個Linear層的輸入為(None, 16 * 5 * 5),故會出現mismatch Error。
之所以會有這樣一個問題還是因為keras model 必須提定義Input shape,而pytorch更像是一個流程化操作,具體看官網吧。
補充知識:pytorch 卷積 分組卷積 及其深度卷積
先來看看pytorch二維卷積的操作API

現在繼續講講幾個卷積是如何操作的。
一. 普通卷積
torch.nn.Conv2d(in_channels, out_channels, kernel_size, stride=1, padding=0, dilation=1, groups=1, bias=True)
普通卷積時group默認為1 dilation=1(這里先暫時不討論dilation)其余都正常的話,比如輸入為Nx in_channel x high x width
輸出為N x out_channel x high xwidth .還是來具體的數字吧,輸入為64通道的特征圖,輸出為32通道的特征圖,要想得到32通道的特征圖就必須得有32種不同的卷積核。
也就是上面傳入的參數out_channel。繼續說說具體是怎么的得到的,對於每一種卷積核會和64種不同的特征圖依次進行卷積,比如卷積核大小是3x3大小的,由於卷積權值共享,所以對於輸入的一張特征圖卷積時,只有3x3個參數,同一張特征圖上進行滑窗卷積操作時參數是一樣的,剛才說的第一種卷積核和輸入的第一個特征圖卷積完后再繼續和后面的第2,3,........64個不同的特征圖依次卷積(一種卷積核對於輸入特征圖來說,同一特征圖上面卷積,參數一樣,對於不同的特征圖上卷積不一樣),最后的參數是3x3x64。
此時輸出才為一個特征圖,因為現在才只使用了一種卷積核。一種核分別在局部小窗口里面和64個特征圖卷積應該得到64個數,最后將64個數相加就可以得到一個數了,也就是輸出一個特征圖上對應於那個窗口的值,依次滑窗就可以得到完整的特征圖了。
前面將了這么多才使用一種卷積核,那么現在依次類推使用32種不同的卷積核就可以得到輸出的32通道的特征圖。最終參數為64x3x3x32.
二.分組卷積
參數group=1時,就是和普通的卷積一樣。現在假如group=4,前提是輸入特征圖和輸出特征圖必須是4的倍數。現在來看看是如何操作的。in_channel64分成4組,out_inchannel(也就是32種核)也分成4組,依次對應上面的普通卷方式,最終將每組輸出的8個特征圖依次concat起來,就是結果的out_channel
三. 深度卷積depthwise
此時group=in_channle,也就是對每一個輸入的特征圖分別用不同的卷積核卷積。out_channel必須是in_channel 的整數倍。

3.1 當k=1時,out_channel=in_channel ,每一個卷積核分別和每一個輸入的通道進行卷積,最后在concat起來。參數總量為3x3x64。如果此時卷積完之后接着一個64個1x1大小的卷積核。就是谷歌公司於2017年的CVPR中在論文”Xception: deep learning with depthwise separable convolutions”中提出的結構。如下圖

上圖是將1x1放在depthwise前面,其實原理都一樣。最終參數的個數是64x1x1+64x3x3。參數要小於普通的卷積方法64x3x3x64
3.2 當k是大於1的整數時,比如k=2

此時每一個輸入的特征圖對應k個卷積核,生成k特征圖,最終生成的特征圖個數就是k×in_channel .
以上這篇Pytorch 卷積中的 Input Shape用法就是小編分享給大家的全部內容了,希望能給大家一個參考,也希望大家多多支持。