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 ().