zoukankan      html  css  js  c++  java
  • 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第四章,廖星宇.

  • 相关阅读:
    sqlplus时报Linux-x86_64 Error: 13: Permission denied
    thrift之TTransport层的缓存传输类TBufferedTransport和缓冲基类TBufferBase
    Java实现 蓝桥杯 算法提高 新建Microsoft world文档
    Java实现 蓝桥杯 算法提高 新建Microsoft world文档
    Java实现 蓝桥杯 算法提高 快乐司机
    Java实现 蓝桥杯 算法提高 快乐司机
    Java实现 蓝桥杯 算法提高 队列操作
    Java实现 蓝桥杯 算法提高 队列操作
    Java实现 蓝桥杯 算法提高 文本加密
    Java实现 蓝桥杯 算法提高 合并石子
  • 原文地址:https://www.cnblogs.com/picassooo/p/13462924.html
Copyright © 2011-2022 走看看