Pytorch sequentialとModuleList学習

20328 ワード

Pytorch Sequential()ModuleList()学習


Sequential()


1.モデルの作成
import torch.nn as nn
import torch
import numpy as np

1つ目の方法:nn.Sequential()オブジェクトadd_module(レイヤ名、レイヤclassのインスタンス)
net1=nn.Sequential()
net1.add_module('conv',nn.Conv2d(3,3,3))
net1.add_module('batchnorm',nn.BatchNorm2d(3))
net1.add_module('activation_layer',nn.ReLU())

第2の方法:nn.Sequential(複数層classの例)
net2=nn.Sequential(
    nn.Conv2d(3,3,3),
    nn.BatchNorm2d(3),
    nn.ReLU()
    )


第三の方法:nn.Sequential(OrderedDict([レイヤ名、レイヤclassのインスタンス]))
from collections import OrderedDict
net3=nn.Sequential(OrderedDict([
    ('conv',nn.Conv2d(3,3,3)),
    ('batchnorm',nn.BatchNorm2d(3)),
    ('activation_layer',nn.ReLU())
]))

2.モデルの表示
print(net1)
Sequential(
  (conv): Conv2d(3, 3, kernel_size=(3, 3), stride=(1, 1))
  (batchnorm): BatchNorm2d(3, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
  (activation_layer): ReLU()
)
print(net2)
Sequential(
  (0): Conv2d(3, 3, kernel_size=(3, 3), stride=(1, 1))
  (1): BatchNorm2d(3, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
  (2): ReLU()
)
print(net3)
Sequential(
  (conv): Conv2d(3, 3, kernel_size=(3, 3), stride=(1, 1))
  (batchnorm): BatchNorm2d(3, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
  (activation_layer): ReLU()
)

3.サブモジュールオブジェクトの抽出
net1.conv
Conv2d(3, 3, kernel_size=(3, 3), stride=(1, 1))
BatchNorm2d(3, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
net2[0]
Conv2d(3, 3, kernel_size=(3, 3), stride=(1, 1))
net3.conv
Conv2d(3, 3, kernel_size=(3, 3), stride=(1, 1))

4.モデルの呼び出し
直接ネットワークにデータを入力するか、上のModuleサブオブジェクトを使用して入力データを別々に入力できます.
a=torch.rand(1,3,4,4)
output1=net1(a)
output1.shape
torch.Size([1, 3, 2, 2])
output1=net2(a)
output1.shape
torch.Size([1, 3, 2, 2])
output1=net3(a)
output1.shape
torch.Size([1, 3, 2, 2])
output1=net3.conv(a)
output1.shape
torch.Size([1, 3, 2, 2])

5.各層パラメータの表示
for name,parm in net1.named_parameters():
    print(name,parm)
conv.weight Parameter containing:
tensor([[[[ 0.1248, -0.1676, -0.0221],
          [-0.1005,  0.1782,  0.1286],
          [ 0.1199,  0.1207, -0.1452]],

         [[-0.1085,  0.0304,  0.0343],
          [-0.0180,  0.1129,  0.1154],
          [-0.0113,  0.0513, -0.0662]],

         [[-0.0264, -0.0293,  0.1318],
          [ 0.1089,  0.0927, -0.0658],
          [-0.1722,  0.0948,  0.1745]]],


        [[[ 0.1377,  0.1561,  0.0465],
          [-0.1419, -0.1055, -0.0563],
          [ 0.0818,  0.1034, -0.1776]],

         [[ 0.0144, -0.0388, -0.0545],
          [ 0.1214,  0.1893, -0.1189],
          [ 0.0596, -0.0839, -0.1748]],

         [[ 0.1665,  0.0308, -0.1102],
          [ 0.0777, -0.1707,  0.0012],
          [ 0.1142, -0.0522, -0.0888]]],


        [[[-0.0491, -0.1448, -0.0026],
          [ 0.0584, -0.1670,  0.1772],
          [-0.0135, -0.1363, -0.1036]],

         [[ 0.1768, -0.1662,  0.1386],
          [ 0.1426, -0.1009, -0.0828],
          [ 0.1675,  0.0223, -0.1242]],

         [[-0.1465,  0.0104,  0.1871],
          [-0.1870, -0.1127, -0.1707],
          [ 0.1605, -0.1369,  0.1509]]]])
conv.bias Parameter containing:
tensor(1.00000e-02 *
       [ 4.3432,  9.0630,  6.4161])
batchnorm.weight Parameter containing:
tensor([ 0.1980,  0.8656,  0.5977])
batchnorm.bias Parameter containing:
tensor([ 0.,  0.,  0.])

ModuleList()


ModuleListはModuleのサブクラスであり、Moduleで使用すると自動的にサブModuleとして認識される
  • モデル
  • を構築
    modellist=nn.ModuleList([nn.Linear(3,4),nn.ReLU(),nn.Linear(4,2)])
    
    print(modellist)
    
    ModuleList(
      (0): Linear(in_features=3, out_features=4, bias=True)
      (1): ReLU()
      (2): Linear(in_features=4, out_features=2, bias=True)
    )
    
  • モデル入力
  • input=torch.rand(1,3)
    input
    
    tensor([[ 0.5325,  0.4064,  0.4870]])
    
    for model in modellist:
        input=model(input)
    print(input)
    
    tensor([[ 0.5814, -0.0939]])
    

    次の使用方法でエラーを報告します.
    output=modellist(input)
    
    ---------------------------------------------------------------------------
    NotImplementedError                       Traceback (most recent call last)
    <ipython-input-44-1418d0eaf845> in <module>
    ----> 1 output=modellist(input)
    
    ~/anaconda3/lib/python3.6/site-packages/torch/nn/modules/module.py in __call__(self, *input, **kwargs)
        489             result = self._slow_forward(*input, **kwargs)
        490         else:
    --> 491             result = self.forward(*input, **kwargs)
        492         for hook in self._forward_hooks.values():
        493             hook_result = hook(self, input, result)
    
    ~/anaconda3/lib/python3.6/site-packages/torch/nn/modules/module.py in forward(self, *input)
         81             registered hooks while the latter silently ignores them.
         82         """
    ---> 83         raise NotImplementedError
         84 
         85     def register_buffer(self, name, tensor):
    
    NotImplementedError: 
    

    ModuleListはlistと類似しており、モデルではforward関数が自動的に実装されていません.
    class MyModule(nn.Module):
        def __init__(self):
            super(MyModule, self).__init__()
            self.list = [nn.Linear(3, 4), nn.ReLU()]
            self.module_list = nn.ModuleList([nn.Conv2d(3, 3, 3), nn.ReLU()])
        def forward(self):
            pass
    model = MyModule()
    print(model)
    
    MyModule(
      (module_list): ModuleList(
        (0): Conv2d(3, 3, kernel_size=(3, 3), stride=(1, 1))
        (1): ReLU()
      )
    )
    
    for name, parm in model.named_parameters():
        print(name,parm.size())
    

    MyModule( (module_list): ModuleList( ​ (0): Conv2d(3, 3, kernel_size=(3, 3), stride=(1, 1)) ​ (1): ReLU() ) )
    module_list.0.weight torch.Size([3, 3, 3, 3])
    module_list.0.bias torch.Size([3])
    

    module_list.0.weight torch.Size([3, 3, 3, 3]) module_list.0.bias torch.Size([3])
    リストのサブmoduleはプライマリmoduleによって識別されず、ModuleListのサブmoduleはプライマリmoduleによって識別される.これはlistでサブmoduleを保存すると、プライマリmoduleのパラメータに追加されていないため、パラメータを調整できないことを意味します.
    結論:Sequentialを直接利用してネットワークを構築することはforward関数を定義する必要がなく、ModuleListを利用する際にforward関数を構築する必要があり、自分のモデルを構築するためによく使われるModuleList関数を構築してサブモデルを構築し、forward関数を構築して順方向伝播を実現することができる.
    参照先:
    https://www.cnblogs.com/hellcat/p/8477195.html