pytorch提取神經網絡模型層結構和參數初始化


torch.nn.Module()類有一些重要屬性,我們可用其下面幾個屬性來實現對神經網絡層結構的提取:

torch.nn.Module.children()
torch.nn.Module.modules()
torch.nn.Module.named_children()
torch.nn.Module.named_moduless()

為方面說明,我們首先搭建一個簡單的神經網絡模型,后面所有的內容都是基於這個模型展開的。

 1 import torch.nn as nn
 2 
 3 class Net(nn.Module):
 4     def __init__(self):
 5         super(Net, self).__init__()                                  # input shape (1, 28, 28)
 6         self.conv1 = nn.Sequential()
 7         self.conv1.add_module('conv1', nn.Conv2d(1, 16, 5, 1, 2))    # output shape (16, 28, 28)
 8         self.conv1.add_module('ReLU1', nn.ReLU())
 9         self.conv1.add_module('pool1', nn.MaxPool2d(2))              # output shape (16, 14, 14)
10 
11         self.conv2 = nn.Sequential()
12         self.conv2.add_module('conv2', nn.Conv2d(16, 32, 5, 1, 2))   # output shape (32, 14, 14)
13         self.conv2.add_module('ReLU2', nn.ReLU())
14         self.conv2.add_module('pool2', nn.MaxPool2d(2))              # output shape (32, 7, 7)
15 
16         self.linear = nn.Linear(32 * 7 * 7, 10)
17 
18     def forward(self, x):
19         x = self.conv1(x)
20         x = self.conv2(x)
21         x = x.view(x.size(0), -1)
22         output = self.linear(x)
23         return output
24 
25 net = Net()
26 print(net)

運行結果:

 1 Net(
 2   (conv1): Sequential(
 3     (conv1): Conv2d(1, 16, kernel_size=(5, 5), stride=(1, 1), padding=(2, 2))
 4     (ReLU1): ReLU()
 5     (pool1): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
 6   )
 7   (conv2): Sequential(
 8     (conv2): Conv2d(16, 32, kernel_size=(5, 5), stride=(1, 1), padding=(2, 2))
 9     (ReLU2): ReLU()
10     (pool2): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
11   )
12   (linear): Linear(in_features=1568, out_features=10, bias=True)
13 )

torch.nn.Modules.children()

children()這個屬性返回下一級模塊的迭代器(可與下一小節中的modules()模塊對照,更容易理解)。

1 i = 1
2 for layer in net.children():
3     print('{}th layer:'.format(i))
4     print(layer)
5     i += 1

運行結果:

 1 1th layer:
 2 Sequential(
 3   (conv1): Conv2d(1, 16, kernel_size=(5, 5), stride=(1, 1), padding=(2, 2))
 4   (ReLU1): ReLU()
 5   (pool1): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
 6 )
 7 2th layer:
 8 Sequential(
 9   (conv2): Conv2d(16, 32, kernel_size=(5, 5), stride=(1, 1), padding=(2, 2))
10   (ReLU2): ReLU()
11   (pool2): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
12 )
13 3th layer:
14 Linear(in_features=1568, out_features=10, bias=True)

torch.nn.Modules.modules()

 modules()屬性返回神經網絡每一級的內容。

1 for layer in net.modules():
2     print(layer)
3     print()

運行結果:

 1 Net(
 2   (conv1): Sequential(
 3     (conv1): Conv2d(1, 16, kernel_size=(5, 5), stride=(1, 1), padding=(2, 2))
 4     (ReLU1): ReLU()
 5     (pool1): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
 6   )
 7   (conv2): Sequential(
 8     (conv2): Conv2d(16, 32, kernel_size=(5, 5), stride=(1, 1), padding=(2, 2))
 9     (ReLU2): ReLU()
10     (pool2): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
11   )
12   (linear): Linear(in_features=1568, out_features=10, bias=True)
13 )
14 
15 Sequential(
16   (conv1): Conv2d(1, 16, kernel_size=(5, 5), stride=(1, 1), padding=(2, 2))
17   (ReLU1): ReLU()
18   (pool1): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
19 )
20 
21 Conv2d(1, 16, kernel_size=(5, 5), stride=(1, 1), padding=(2, 2))
22 
23 ReLU()
24 
25 MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
26 
27 Sequential(
28   (conv2): Conv2d(16, 32, kernel_size=(5, 5), stride=(1, 1), padding=(2, 2))
29   (ReLU2): ReLU()
30   (pool2): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
31 )
32 
33 Conv2d(16, 32, kernel_size=(5, 5), stride=(1, 1), padding=(2, 2))
34 
35 ReLU()
36 
37 MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
38 
39 Linear(in_features=1568, out_features=10, bias=True)

從上面的運行結果可以看出來,modules()模塊以迭代器的形式返回神經網絡逐級的內容。

torch.nn.Modules.named_children()和torch.nn.Modules.named_modules()

named_children()和named_modules()這兩個模塊不僅返回模塊的迭代器,而且還會返回網絡層的名字。

1 for layer in net.named_modules():
2     print(layer)

運行結果:

 1 ('', Net(
 2   (conv1): Sequential(
 3     (conv1): Conv2d(1, 16, kernel_size=(5, 5), stride=(1, 1), padding=(2, 2))
 4     (ReLU1): ReLU()
 5     (pool1): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
 6   )
 7   (conv2): Sequential(
 8     (conv2): Conv2d(16, 32, kernel_size=(5, 5), stride=(1, 1), padding=(2, 2))
 9     (ReLU2): ReLU()
10     (pool2): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
11   )
12   (linear): Linear(in_features=1568, out_features=10, bias=True)
13 ))
14 ('conv1', Sequential(
15   (conv1): Conv2d(1, 16, kernel_size=(5, 5), stride=(1, 1), padding=(2, 2))
16   (ReLU1): ReLU()
17   (pool1): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
18 ))
19 ('conv1.conv1', Conv2d(1, 16, kernel_size=(5, 5), stride=(1, 1), padding=(2, 2)))
20 ('conv1.ReLU1', ReLU())
21 ('conv1.pool1', MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False))
22 ('conv2', Sequential(
23   (conv2): Conv2d(16, 32, kernel_size=(5, 5), stride=(1, 1), padding=(2, 2))
24   (ReLU2): ReLU()
25   (pool2): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
26 ))
27 ('conv2.conv2', Conv2d(16, 32, kernel_size=(5, 5), stride=(1, 1), padding=(2, 2)))
28 ('conv2.ReLU2', ReLU())
29 ('conv2.pool2', MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False))
30 ('linear', Linear(in_features=1568, out_features=10, bias=True))

只提取模型中的卷積層

如果希望只提取卷積層,可以這樣操作:

1 conv_net = nn.Sequential()
2 for layer in net.named_modules():
3     if isinstance(layer[1], nn.Conv2d):
4         conv_net.add_module(layer[0][:5], layer[1])    # layer[1] is the net layer, layer[0] is its name.
5 print(conv_net)

運行結果:

Sequential(
  (conv1): Conv2d(1, 16, kernel_size=(5, 5), stride=(1, 1), padding=(2, 2))
  (conv2): Conv2d(16, 32, kernel_size=(5, 5), stride=(1, 1), padding=(2, 2))
)

參數初始化

參數初始化需用到torch.nn.init,下面幾個函數比較常用,截圖摘自PyTorch中文文檔

在神經網絡中,模型參數就是weights和bias,weights和bias在PyTorch中是Variable,所以我們只需取出weights的data屬性,並填充數值就可以了。比如對卷積層進行參數初始化:

1 for m in net.modules():
2     if isinstance(m, nn.Conv2d):
3         nn.init.normal(m.weight.data)
4         # nn.init.xavier_normal(m.weight.data)
5         # nn.init.kaiming_normal(m.weight.data)
6     elif isinstance(m, nn.Linear):
7         m.weight.data.normal_()
8     m.bias.data.fill_(0)

 

參考文獻:

深度學習之PyTorch第四章,廖星宇.

 


免責聲明!

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



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