L’ús i la diferència de nn.ModuleList i nn.Sequential a Pytorch

Usage Difference Nn



https://zhuanlan.zhihu.com/p/64990232

Recentment, en definir una xarxa multitarea, dubtava de l’ús de nn.ModuleList i nn.Sequential. Explorem l’ús i la diferència entre tots dos.



1. El paper de nn.ModuleList
Primer explorem el paper de nn.ModuleList i definim una xarxa simple que només contingui connexions completes. Quan no utilitzeu ModuleList i només utilitzeu la llista per definir les capes de la xarxa:



import torch import torch.nn as nn class testNet(nn.Module): def __init__(self): super(testNet, self).__init__() self.combine = [] self.combine.append(nn.Linear(100,50)) self.combine.append(nn.Linear(50,25)) net = testNet() print(net)

Podeu veure que el resultat no mostra la informació de la capa completament connectada afegida. Si canvieu a fer servir ModuleList:



import torch import torch.nn as nn class testNet(nn.Module): def __init__(self): super(testNet, self).__init__() self.combine = nn.ModuleList() self.combine.append(nn.Linear(100,50)) self.combine.append(nn.Linear(50,25)) net = testNet() print(net)

Es pot veure que pytorch pot reconèixer automàticament els paràmetres a nn.ModuleList quan es defineix, però no per a llistes normals. Si utilitzeu Seqüencial, podeu obtenir el mateix efecte que ModuleList.

La diferència entre nn.ModuleList i nn.Sequential
Si doneu una entrada a la xarxa definida anteriorment, comproveu la sortida:

import torch import torch.nn as nn class testNet(nn.Module): def __init__(self): super(testNet, self).__init__() self.combine = nn.ModuleList() self.combine.append(nn.Linear(100,50)) self.combine.append(nn.Linear(50,25)) testnet = testNet() input_x = torch.ones(100) output_x = testnet(input_x) print(output_x)

Notificarem un error NotImplementedError:



Això es deu al fet que el mètode forward () no està implementat. Si el mètode forward () es completa de la següent manera:

import torch import torch.nn as nn class testNet(nn.Module): def __init__(self): super(testNet, self).__init__() self.combine = nn.ModuleList() self.combine.append(nn.Linear(100,50)) self.combine.append(nn.Linear(50,25)) #Complete forward() def forward(self, x): x = self.combine(x) return x testnet = testNet() input_x = torch.ones(100) output_x = testnet(input_x) print(output_x)

S'ha trobat que NotImplementedError encara s'informarà. Això es deu al fet que nn.ModuleList és una seqüència no ordenada. No implementa el mètode forward (). No podem implementar forward () trucant directament a x = self.combine (x). Si voleu implementar el mètode ModuleList, heu de definir forward () de la manera següent:

import torch import torch.nn as nn class testNet(nn.Module): def __init__(self): super(testNet, self).__init__() self.combine = nn.ModuleList() self.combine.append(nn.Linear(100,50)) self.combine.append(nn.Linear(50,25)) #Redefine forward() method def forward(self, x): x = self.combine[0](x) x = self.combine[1](x) return x testnet = testNet() input_x = torch.ones(100) output_x = testnet(input_x) print(output_x)

He obtingut el resultat correcte. Si es substitueix per nn. Definició seqüencial:

import torch import torch.nn as nn class testNet(nn.Module): def __init__(self): super(testNet, self).__init__() self.combine = nn.Sequential( nn.Linear(100,50), nn.Linear(50,25), ) def forward(self, x): x = self.combine(x) return x testnet = testNet() input_x = torch.ones(100) output_x = testnet(input_x) print(output_x)

Cada capa de la xarxa definida per nn.Sequential es mostrarà en cascada segons l'ordre definit, de manera que cal assegurar-se que l'entrada i sortida de cada capa estan connectades. I nn.Sequential implementa el mètode farward (), de manera que forward es pot implementar directament de manera similar a x = self.combine (x).

El nn.ModuleList no té requisits d’ordre i no implementa el mètode forward ().

Aquesta és la diferència entre tots dos.

Enllaç original: https://blog.csdn.net/watermelon1123/article/details/89954224