了解预训练模型的内容

Understanding content of pretrained model

from torchvision import models

model = models.vgg16(pretrained=True).features
for i, module in enumerate(model.modules()):
    print('-' * 60)
    print(type(module))
    print(module)

model.modules() (modules() Returns an iterator over all modules in the network.) 中的 'module' 是什么?为什么 torch.nn.modules.container.Sequential 与单层一起存储?

输出:

------------------------------------------------------------
<class 'torch.nn.modules.container.Sequential'>
Sequential(
  (0): Conv2d(3, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
  (1): ReLU(inplace=True)
  (2): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
  (3): ReLU(inplace=True)
  (4): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
  (5): Conv2d(64, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
  (6): ReLU(inplace=True)
  (7): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
  (8): ReLU(inplace=True)
  (9): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
  (10): Conv2d(128, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
  (11): ReLU(inplace=True)
  (12): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
  (13): ReLU(inplace=True)
  (14): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
  (15): ReLU(inplace=True)
  (16): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
  (17): Conv2d(256, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
  (18): ReLU(inplace=True)
  (19): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
  (20): ReLU(inplace=True)
  (21): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
  (22): ReLU(inplace=True)
  (23): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
  (24): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
  (25): ReLU(inplace=True)
  (26): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
  (27): ReLU(inplace=True)
  (28): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
  (29): ReLU(inplace=True)
  (30): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
)
------------------------------------------------------------
<class 'torch.nn.modules.conv.Conv2d'>
Conv2d(3, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
------------------------------------------------------------
<class 'torch.nn.modules.activation.ReLU'>
ReLU(inplace=True)
------------------------------------------------------------
<class 'torch.nn.modules.conv.Conv2d'>
Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
------------------------------------------------------------
<class 'torch.nn.modules.activation.ReLU'>
ReLU(inplace=True)
------------------------------------------------------------
<class 'torch.nn.modules.pooling.MaxPool2d'>
MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
------------------------------------------------------------
<class 'torch.nn.modules.conv.Conv2d'>
Conv2d(64, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
------------------------------------------------------------
<class 'torch.nn.modules.activation.ReLU'>
ReLU(inplace=True)
------------------------------------------------------------
<class 'torch.nn.modules.conv.Conv2d'>
Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
------------------------------------------------------------
<class 'torch.nn.modules.activation.ReLU'>
ReLU(inplace=True)
------------------------------------------------------------
<class 'torch.nn.modules.pooling.MaxPool2d'>
MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
------------------------------------------------------------
<class 'torch.nn.modules.conv.Conv2d'>
Conv2d(128, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
------------------------------------------------------------
<class 'torch.nn.modules.activation.ReLU'>
ReLU(inplace=True)
------------------------------------------------------------
<class 'torch.nn.modules.conv.Conv2d'>
Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
------------------------------------------------------------
<class 'torch.nn.modules.activation.ReLU'>
ReLU(inplace=True)
------------------------------------------------------------
<class 'torch.nn.modules.conv.Conv2d'>
Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
------------------------------------------------------------
<class 'torch.nn.modules.activation.ReLU'>
ReLU(inplace=True)
------------------------------------------------------------
<class 'torch.nn.modules.pooling.MaxPool2d'>
MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
------------------------------------------------------------
<class 'torch.nn.modules.conv.Conv2d'>
Conv2d(256, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
------------------------------------------------------------
<class 'torch.nn.modules.activation.ReLU'>
ReLU(inplace=True)
------------------------------------------------------------
<class 'torch.nn.modules.conv.Conv2d'>
Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
------------------------------------------------------------
<class 'torch.nn.modules.activation.ReLU'>
ReLU(inplace=True)
------------------------------------------------------------
<class 'torch.nn.modules.conv.Conv2d'>
Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
------------------------------------------------------------
<class 'torch.nn.modules.activation.ReLU'>
ReLU(inplace=True)
------------------------------------------------------------
<class 'torch.nn.modules.pooling.MaxPool2d'>
MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
------------------------------------------------------------
<class 'torch.nn.modules.conv.Conv2d'>
Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
------------------------------------------------------------
<class 'torch.nn.modules.activation.ReLU'>
ReLU(inplace=True)
------------------------------------------------------------
<class 'torch.nn.modules.conv.Conv2d'>
Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
------------------------------------------------------------
<class 'torch.nn.modules.activation.ReLU'>
ReLU(inplace=True)
------------------------------------------------------------
<class 'torch.nn.modules.conv.Conv2d'>
Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
------------------------------------------------------------
<class 'torch.nn.modules.activation.ReLU'>
ReLU(inplace=True)
------------------------------------------------------------
<class 'torch.nn.modules.pooling.MaxPool2d'>
MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)

nn.Module.modules will return all modules contained inside the model recursively, that includes parent submodules and children submodules that they may have of their own. You can instead use nn.Module.children 获取直接子模块:

for child in module.children():
    print(child)

如果您想使用递归进行调查,您可以这样做:

def print_children(module, i=0):
    if len(list(module.modules())) == 1:
        return print(' '*i, module)
    for child in module.children():
        print_children(child, i+2)