(原)CNN中的卷積、1x1卷積及在pytorch中的驗證


轉載請注明處處:

http://www.cnblogs.com/darkknightzh/p/9017854.html

參考網址:

https://pytorch.org/docs/stable/nn.html?highlight=conv2d#torch.nn.Conv2d

https://www.cnblogs.com/chuantingSDU/p/8120065.html

https://blog.csdn.net/chaolei3/article/details/79374563

1x1卷積

https://blog.csdn.net/u014114990/article/details/50767786

https://www.quora.com/How-are-1x1-convolutions-used-for-dimensionality-reduction

https://www.reddit.com/r/MachineLearning/comments/3oln72/1x1_convolutions_why_use_them/?st=is9xc9jn&sh=7b774d4d

 

理解錯誤的地方敬請諒解。

1.  卷積

才發現一直理解錯了CNN中的卷積操作。

假設輸入輸出大小不變,輸入是N*Cin*H*W,輸出是N*Co*H*W。其中N為batchsize。卷積核的大小是k*k。實際上共有Cin*Co個k*k的卷積核,總共的參數是Cin*k*k*Co(無bias)或者Cin*k*k*Co+Co(有bias)。

pytorch中給出了conv2d的計算公式

https://pytorch.org/docs/stable/nn.html?highlight=conv2d#torch.nn.Conv2d):

$out({{N}_{i}},C{{o}_{j}})=bias(C{{o}_{j}})+\sum\limits_{k=0}^{Cin-1}{weight(C{{o}_{j}},k)*input({{N}_{i}},k)}$

其中weight即為卷積核,上式中輸出的batch中的第Ni個特征圖的第Coj個特征,即為輸入的第Ni個特征圖的第k個特征,和第Coj個卷積核中的第k個核進行卷積(cross-correlation)。

如下圖所示,對於某個輸入特征圖,其某局域分別於Co個卷積核進行卷積,得到對應的特征Coi,而后將這些特征拼接起來,得到最終的特征圖。實際上每個卷積核都是k*k*Cin的大小。

經過上面的卷積,就可以將輸入的不同的通道的信息融合了(權重不同,類似於加權融合)。

如果輸出Co數量大於輸入Cin數量,輸出特征數量就多於輸入特征。否則輸出就少於輸入特征數量。

2.  1*1卷積

上面的卷積理解了,1*1卷積就好理解了。

1*1主要用於降維或者升維(看Cin和Co哪個更大),其核大小為1*1。

實際上卷積核的數量為Cin*1*1*Co=Cin*Co(無bias)或者Cin*Co+Co(有bias)。

計算時,通道方向上每個卷積核將輸入按照通道進行加權,得到對應的輸出特征,之后將這些特征拼接起來,即可得到最終的特征圖。

3.  pytorch中的驗證

代碼:

 1 from __future__ import print_function
 2 from __future__ import division
 3 
 4 import torch.nn as nn
 5 import numpy as np
 6 
 7 class testNet(nn.Module):
 8     def __init__(self):
 9         super(testNet, self).__init__()
10         self.conv1 = nn.Conv2d(in_channels=3, out_channels=10, kernel_size=5, stride=1, padding=1, bias=True)
11 
12     def forward(self, x):
13         x = self.conv1(x)
14         return x
15 
16 def get_total_params(model):
17     model_parameters = filter(lambda p: p.requires_grad, model.parameters())
18     num_params = sum([np.prod(p.size()) for p in model_parameters])
19     return num_params
20 
21 def main():
22     net = testNet()
23     print(get_total_params(net))
24 
25 if __name__ == '__main__':
26     main()

上面代碼中get_total_params用於得到模型總共的參數。

當kernel_size=5,bias=True時,參數共計760個:3*5*5*10+10=760。

當kernel_size=5,bias=False時,參數共計750個:3*5*5*10=750。

 

當kernel_size=1,bias=True時,參數共計40個:3*1*1*10+10=40。

當kernel_size=1,bias=False時,參數共計30個:3*1*1*10=30。

 


免責聲明!

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



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