PyTorchでリストとループを使用して人工ニューラルネットワークレイヤーを定義する方法
説明
階層を多く積み上げる必要がある場合や、頻繁にニューラルネットワークの構造を変える必要があるなど、人工ニューラルネットワークの定義を自動化したい場合があるだろう。そのような時、次のようなfor文を使って定義したいと思うことがあるだろう。
class Model(nn.Module):
def __init__(self):
super(Model, self).__init__()
fc_ = [nn.Linear(n,n) for i in range(m)]
def forward(self, x):
for i in range(m):
x = fc_[m](x)
x = F.relu(x)
return x
しかし、このようにPythonリストでニューラルネットワークを定義すると、各nn.Linear
レイヤのパラメーターを認識できなくなる。その結果、パラメーターがオプティマイザに適切に渡されず、オプティマイザを定義する際に、次のようなエラーが発生する。
ValueError: optimizer got an empty parameter list
したがって、レイヤーのリストを利用してニューラルネットワークを構成したい場合は、nn.ModuleList()
を通じて__init__()
でインスタンス属性(self.
)として定義する必要がある。このように定義すると、通常のリストと同様にインデックス指定、スライス、加算などが可能になる。
次に、リストを利用してニューラルネットワークの各レイヤーとforwardを定義し、 重みを初期化する コードである。
コード1
class fx_Net(nn.Module):
def __init__(self):
super(fx_Net, self).__init__()
fc_ = [nn.Linear(n,n) for i in range(m)]
self.linears = nn.ModuleList(fc_)
for m in self.linears:
torch.nn.init.zeros_(m.weight.data)
def forward(self, x):
for i in range(m):
x = self.linears[m](x)
x = F.relu(x)
return f
環境
- OS: Windows10
- Version: Python 3.9.2, torch 1.8.1+cu111