1 問題
定義好一個VGG11網(wǎng)絡(luò)模型后,我們需要驗證一下我們的模型是否按需求準確無誤的寫出,這時可以用torchinfo庫中的summary來打印一下模型各層的參數(shù)狀況。這時發(fā)現(xiàn)表中有一個param以及在經(jīng)過兩個卷積后參數(shù)量(param)沒變,出于想知道每層的param是怎么計算出來,于是對此進行探究。
2 方法
1、網(wǎng)絡(luò)中的參數(shù)量(param)是什么?
param代表每一層需要訓(xùn)練的參數(shù)個數(shù),在全連接層是突觸權(quán)重的個數(shù),在卷積層是卷積核的參數(shù)的個數(shù)。
2、網(wǎng)絡(luò)中的參數(shù)量(param)的計算。
卷積層計算公式:Conv2d_param=(卷積核尺寸*輸入圖像通道+1)*卷積核數(shù)目
池化層:池化層不需要參數(shù)。
全連接計算公式:Fc_param=(輸入數(shù)據(jù)維度+1)*神經(jīng)元個數(shù)
3、解釋一下圖表中vgg網(wǎng)絡(luò)的結(jié)構(gòu)和組成。vgg11的網(wǎng)絡(luò)結(jié)構(gòu)即表中的第一列:
conv3-64→maxpool→conv3-128→maxpool→conv3-256→conv3-256→maxpool→conv3-512→conv3-512→maxpool→conv3-512→conv3-512→maxpool→FC-4096→FC-4096→FC-1000→softmax。4、代碼展示
import torch from torch import nn from torchinfo import summary class MyNet(nn.Module): #定義哪些層 def __init__(self) : super().__init__() #(1)conv3-64 self.conv1 = nn.Conv2d( in_channels=1, #輸入圖像通道數(shù) out_channels=64,#卷積產(chǎn)生的通道數(shù)(卷積核個數(shù)) kernel_size=3,#卷積核尺寸 stride=1, padding=1 #不改變特征圖大小 ) self.max_pool_1 = nn.MaxPool2d(2) #(2)conv3-128 self.conv2 = nn.Conv2d( in_channels=64, out_channels=128, kernel_size=3, stride=1, padding=1 ) self.max_pool_2 = nn.MaxPool2d(2) #(3)conv3-256 self.conv3 = nn.Conv2d( in_channels=128, out_channels=256, kernel_size=3, stride=1, padding=1 ) self.conv4 = nn.Conv2d( in_channels=256, out_channels=256, kernel_size=3, stride=1, padding=1 ) self.max_pool_3 = nn.MaxPool2d(2) #(4)conv3-512 self.conv5 = nn.Conv2d( in_channels=256, out_channels=512, kernel_size=3, stride=1, padding=1 ) self.conv6 = nn.Conv2d( in_channels=512, out_channels=512, kernel_size=3, stride=1, padding=1 ) self.max_pool_4 = nn.MaxPool2d(2) #(5)conv3-512 self.conv7 = nn.Conv2d( in_channels=512, out_channels=512, kernel_size=3, stride=1, padding=1 ) self.conv8 = nn.Conv2d( in_channels=512, out_channels=512, kernel_size=3, stride=1, padding=1 ) self.max_pool_5 = nn.MaxPool2d(2) self.fc1 = nn.Linear(in_features=7*7*512,out_features=4096) self.fc2 = nn.Linear(in_features=4096,out_features=4096) self.fc3 = nn.Linear(in_features=4096,out_features=1000) #計算流向 def forward(self,x): x = self.conv1(x) x = self.max_pool_1(x) x = self.conv2(x) x = self.max_pool_2(x) x = self.conv3(x) x = self.conv4(x) x = self.max_pool_3(x) x = self.conv5(x) x = self.conv6(x) x = self.max_pool_4(x) x = self.conv7(x) x = self.conv8(x) x = self.max_pool_5(x) x = torch.flatten(x,1) #[B,C,H,W]從C開始flatten,B不用flatten,所以要加1 x = self.fc1(x) x = self.fc2(x) out = self.fc3(x) return out if __name__ == '__main__': x = torch.rand(128,1,224,224) net = MyNet() out = net(x) #print(out.shape) summary(net, (12,1,224,224)) |
圖片中紅色方塊計算過程:
1:相關(guān)代碼及計算過程(卷積層)
self.conv7 = nn.Conv2d( in_channels=512, out_channels=512, kernel_size=3, stride=1, padding=1 ) |
Conv2d_param= (3*3*512+1)*512=2,359,808(Conv2d-12代碼同,故param同)
2:相關(guān)代碼及計算過程
self.fc3 = nn.Linear(in_features=4096,out_features=1000) |
Fc_fc_param=(4096+1)*1000=4,097,000
3 結(jié)語
以上為一般情況下參數(shù)量計算方法,當(dāng)然還有很多細節(jié)與很多其他情況下的計算方法沒有介紹,主要用來形容模型的大小程度,針對不同batch_size下param的不同,可以用于參考來選擇更合適的batch_size。
聯(lián)系客服