nn.ModuleList는 여러개의 구성요소를 하나의 리스트로 담는 역할을 하는데, 일반 list와의 차이가 뭔지 궁금했다

modules = []
for rate in atrous_rates:
  **modules** += [ASPPConv(in_channels, in_channels//2, rate, 3, nn.ReLU())]

**self.convlist** = nn.ModuleList(modules)

nn.ModuleList 는 파이썬 list의 속성을 가지고 있어 forward 메소드 정의에서도 큰 차이가 없다

def forward(self, x):
    conv_results = []
    **for conv in self.convlist**:
        conv_results += [conv(x)]
    output = torch.cat(conv_results, dim=1)
    output = self.project(output)
    return output

차이가 나는 부분은 이렇게 확인할 수 있다

class WAB(nn.Module):
    def __init__(self, in_channels, out_channels, atrous_rates:List[int]):
        super(WAB, self).__init__()
        modules = []
        for rate in atrous_rates:
            modules += [ASPPConv(in_channels, in_channels//2, rate, 3, nn.ReLU())]
        **self.convmodulelist** = nn.ModuleList(modules)
        **self.convlist** = modules
        self.project = nn.Sequential(
            nn.Conv2d(len(self.convlist) * (in_channels//2), out_channels, 1, bias=False),
            nn.BatchNorm2d(out_channels),
            nn.ReLU(),
        ) # 원래 WAB는 project에서는 그냥 conv만 있음
            
    def forward(self, x):
        conv_results = []
        for conv in self.convlist:
            conv_results += [conv(x)]
        output = torch.cat(conv_results, dim=1)
        output = self.project(output)
        return output

self.convmodulelist는 ModuleList로 구성된 네트워크이고

self.convlist는 리스트로 구성된 네트워크이다

if __name__ == '__main__':
    Network = WAB(256, 256, [1, 2, 3, 4])
    for name, param in Network.named_parameters():
        print(f"param name: {name} , shape: {param.shape}")

이렇게 확인해보면

Untitled

convlist에 대한 내용은 보이지 않는다

즉, optimizer 호출시 model.parameters()로 모델의 파라미터를 전달하는데, 일반 list로 구성된 파라미터들이라면 전달되지 않을 것이기 때문에 훈련되지 않고, state_dict()로 저장시에도 일반 파이썬 리스트로 구성된 모듈들은 저장되지 않는다