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として認識される
import torch.nn as nn
import torch
import numpy as np
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())
net2=nn.Sequential(
nn.Conv2d(3,3,3),
nn.BatchNorm2d(3),
nn.ReLU()
)
from collections import OrderedDict
net3=nn.Sequential(OrderedDict([
('conv',nn.Conv2d(3,3,3)),
('batchnorm',nn.BatchNorm2d(3)),
('activation_layer',nn.ReLU())
]))
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()
)
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))
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])
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.])
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