【问题标题】:Model summary in pytorchpytorch 中的模型总结
【发布时间】:2017-07-17 17:36:14
【问题描述】:

如何像 Keras 中的 model.summary() 方法一样在 PyTorch 中打印模型的摘要:

Model Summary:
____________________________________________________________________________________________________
Layer (type)                     Output Shape          Param #     Connected to                     
====================================================================================================
input_1 (InputLayer)             (None, 1, 15, 27)     0                                            
____________________________________________________________________________________________________
convolution2d_1 (Convolution2D)  (None, 8, 15, 27)     872         input_1[0][0]                    
____________________________________________________________________________________________________
maxpooling2d_1 (MaxPooling2D)    (None, 8, 7, 27)      0           convolution2d_1[0][0]            
____________________________________________________________________________________________________
flatten_1 (Flatten)              (None, 1512)          0           maxpooling2d_1[0][0]             
____________________________________________________________________________________________________
dense_1 (Dense)                  (None, 1)             1513        flatten_1[0][0]                  
====================================================================================================
Total params: 2,385
Trainable params: 2,385
Non-trainable params: 0

【问题讨论】:

  • 你见过模块上的 state_dict() 方法吗?它为您提供模型的不同参数。没有直接的汇总方法,但可以使用 state_dict() 方法形成一个
  • 所选答案现已过期,torchsummary 是更好的解决方案。
  • torchsummary 已死。请使用来自 TylerYep 的torchinfo(又名torch-summary,带破折号)github.com/TylerYep/torchinfo

标签: python pytorch


【解决方案1】:

是的,您可以使用 pytorch-summary 包获得准确的 Keras 表示。

VGG16 示例:

from torchvision import models
from torchsummary import summary

vgg = models.vgg16()
summary(vgg, (3, 224, 224))

----------------------------------------------------------------
        Layer (type)               Output Shape         Param #
================================================================
            Conv2d-1         [-1, 64, 224, 224]           1,792
              ReLU-2         [-1, 64, 224, 224]               0
            Conv2d-3         [-1, 64, 224, 224]          36,928
              ReLU-4         [-1, 64, 224, 224]               0
         MaxPool2d-5         [-1, 64, 112, 112]               0
            Conv2d-6        [-1, 128, 112, 112]          73,856
              ReLU-7        [-1, 128, 112, 112]               0
            Conv2d-8        [-1, 128, 112, 112]         147,584
              ReLU-9        [-1, 128, 112, 112]               0
        MaxPool2d-10          [-1, 128, 56, 56]               0
           Conv2d-11          [-1, 256, 56, 56]         295,168
             ReLU-12          [-1, 256, 56, 56]               0
           Conv2d-13          [-1, 256, 56, 56]         590,080
             ReLU-14          [-1, 256, 56, 56]               0
           Conv2d-15          [-1, 256, 56, 56]         590,080
             ReLU-16          [-1, 256, 56, 56]               0
        MaxPool2d-17          [-1, 256, 28, 28]               0
           Conv2d-18          [-1, 512, 28, 28]       1,180,160
             ReLU-19          [-1, 512, 28, 28]               0
           Conv2d-20          [-1, 512, 28, 28]       2,359,808
             ReLU-21          [-1, 512, 28, 28]               0
           Conv2d-22          [-1, 512, 28, 28]       2,359,808
             ReLU-23          [-1, 512, 28, 28]               0
        MaxPool2d-24          [-1, 512, 14, 14]               0
           Conv2d-25          [-1, 512, 14, 14]       2,359,808
             ReLU-26          [-1, 512, 14, 14]               0
           Conv2d-27          [-1, 512, 14, 14]       2,359,808
             ReLU-28          [-1, 512, 14, 14]               0
           Conv2d-29          [-1, 512, 14, 14]       2,359,808
             ReLU-30          [-1, 512, 14, 14]               0
        MaxPool2d-31            [-1, 512, 7, 7]               0
           Linear-32                 [-1, 4096]     102,764,544
             ReLU-33                 [-1, 4096]               0
          Dropout-34                 [-1, 4096]               0
           Linear-35                 [-1, 4096]      16,781,312
             ReLU-36                 [-1, 4096]               0
          Dropout-37                 [-1, 4096]               0
           Linear-38                 [-1, 1000]       4,097,000
================================================================
Total params: 138,357,544
Trainable params: 138,357,544
Non-trainable params: 0
----------------------------------------------------------------
Input size (MB): 0.57
Forward/backward pass size (MB): 218.59
Params size (MB): 527.79
Estimated Total Size (MB): 746.96
----------------------------------------------------------------

【讨论】:

  • 找到了解决方案。 summary(model.cuda(), (INPUT_SHAPE)) 工作。
  • 大家好。我是新手,但我怎么知道模型所需的输入形状? 3、224、224 对所有这些都是真的吗?
  • @adikshit,它是网络输入的尺寸,在这种情况下,它是来自 ImageNet 数据集的 224x224 RGB 图像,因此是 (3, 224, 224)。更一般地,对于 2D 输入,形状为 (C, H, W),其中 C = 通道,H = 高度和 W = 宽度,对于 1D 输入,形状为 (C, L),其中 C = 通道,L =长度。
  • 这个包的更新版本可以在https://github.com/TylerYep/torch-summary找到,它的用法相同,但pip安装不同。
  • torchsummary 已死。请使用来自 TylerYep 的torchinfo
【解决方案2】:

虽然您不会像在 Keras 的 model.summary 中那样获得关于模型的详细信息,但只需打印模型即可让您对所涉及的不同层及其规格有所了解。

例如:

from torchvision import models
model = models.vgg16()
print(model)

这种情况下的输出如下:

VGG (
  (features): Sequential (
    (0): Conv2d(3, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    (1): ReLU (inplace)
    (2): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    (3): ReLU (inplace)
    (4): MaxPool2d (size=(2, 2), stride=(2, 2), dilation=(1, 1))
    (5): Conv2d(64, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    (6): ReLU (inplace)
    (7): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    (8): ReLU (inplace)
    (9): MaxPool2d (size=(2, 2), stride=(2, 2), dilation=(1, 1))
    (10): Conv2d(128, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    (11): ReLU (inplace)
    (12): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    (13): ReLU (inplace)
    (14): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    (15): ReLU (inplace)
    (16): MaxPool2d (size=(2, 2), stride=(2, 2), dilation=(1, 1))
    (17): Conv2d(256, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    (18): ReLU (inplace)
    (19): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    (20): ReLU (inplace)
    (21): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    (22): ReLU (inplace)
    (23): MaxPool2d (size=(2, 2), stride=(2, 2), dilation=(1, 1))
    (24): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    (25): ReLU (inplace)
    (26): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    (27): ReLU (inplace)
    (28): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    (29): ReLU (inplace)
    (30): MaxPool2d (size=(2, 2), stride=(2, 2), dilation=(1, 1))
  )
  (classifier): Sequential (
    (0): Dropout (p = 0.5)
    (1): Linear (25088 -> 4096)
    (2): ReLU (inplace)
    (3): Dropout (p = 0.5)
    (4): Linear (4096 -> 4096)
    (5): ReLU (inplace)
    (6): Linear (4096 -> 1000)
  )
)

现在您可以如Kashyap 所述,使用state_dict 方法获取不同层的权重。但是使用这个层列表可能会提供更多方向,即创建一个辅助函数来获得类似 Keras 的模型摘要!希望这会有所帮助!

【讨论】:

    【解决方案3】:

    为了使用torchsummary类型:

    from torchsummary import summary
    

    如果没有,请先安装。

    pip install torchsummary 
    

    然后你可以尝试一下,但由于某种原因它不起作用,除非我将模型设置为 cuda alexnet.cuda:

    from torchsummary import summary
    help(summary)
    import torchvision.models as models
    alexnet = models.alexnet(pretrained=False)
    alexnet.cuda()
    summary(alexnet, (3, 224, 224))
    print(alexnet)
    

    summary 必须采用输入大小,并且批量大小设置为 -1,表示我们提供的任何批量大小。

    如果我们设置summary(alexnet, (3, 224, 224), 32),这意味着使用bs=32

    summary(model, input_size, batch_size=-1, device='cuda')
    

    输出:

    Help on function summary in module torchsummary.torchsummary:
    
    summary(model, input_size, batch_size=-1, device='cuda')
    
    ----------------------------------------------------------------
            Layer (type)               Output Shape         Param #
    ================================================================
                Conv2d-1           [32, 64, 55, 55]          23,296
                  ReLU-2           [32, 64, 55, 55]               0
             MaxPool2d-3           [32, 64, 27, 27]               0
                Conv2d-4          [32, 192, 27, 27]         307,392
                  ReLU-5          [32, 192, 27, 27]               0
             MaxPool2d-6          [32, 192, 13, 13]               0
                Conv2d-7          [32, 384, 13, 13]         663,936
                  ReLU-8          [32, 384, 13, 13]               0
                Conv2d-9          [32, 256, 13, 13]         884,992
                 ReLU-10          [32, 256, 13, 13]               0
               Conv2d-11          [32, 256, 13, 13]         590,080
                 ReLU-12          [32, 256, 13, 13]               0
            MaxPool2d-13            [32, 256, 6, 6]               0
    AdaptiveAvgPool2d-14            [32, 256, 6, 6]               0
              Dropout-15                 [32, 9216]               0
               Linear-16                 [32, 4096]      37,752,832
                 ReLU-17                 [32, 4096]               0
              Dropout-18                 [32, 4096]               0
               Linear-19                 [32, 4096]      16,781,312
                 ReLU-20                 [32, 4096]               0
               Linear-21                 [32, 1000]       4,097,000
    ================================================================
    Total params: 61,100,840
    Trainable params: 61,100,840
    Non-trainable params: 0
    ----------------------------------------------------------------
    Input size (MB): 18.38
    Forward/backward pass size (MB): 268.12
    Params size (MB): 233.08
    Estimated Total Size (MB): 519.58
    ----------------------------------------------------------------
    AlexNet(
      (features): Sequential(
        (0): Conv2d(3, 64, kernel_size=(11, 11), stride=(4, 4), padding=(2, 2))
        (1): ReLU(inplace)
        (2): MaxPool2d(kernel_size=3, stride=2, padding=0, dilation=1, ceil_mode=False)
        (3): Conv2d(64, 192, kernel_size=(5, 5), stride=(1, 1), padding=(2, 2))
        (4): ReLU(inplace)
        (5): MaxPool2d(kernel_size=3, stride=2, padding=0, dilation=1, ceil_mode=False)
        (6): Conv2d(192, 384, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
        (7): ReLU(inplace)
        (8): Conv2d(384, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
        (9): ReLU(inplace)
        (10): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
        (11): ReLU(inplace)
        (12): MaxPool2d(kernel_size=3, stride=2, padding=0, dilation=1, ceil_mode=False)
      )
      (avgpool): AdaptiveAvgPool2d(output_size=(6, 6))
      (classifier): Sequential(
        (0): Dropout(p=0.5)
        (1): Linear(in_features=9216, out_features=4096, bias=True)
        (2): ReLU(inplace)
        (3): Dropout(p=0.5)
        (4): Linear(in_features=4096, out_features=4096, bias=True)
        (5): ReLU(inplace)
        (6): Linear(in_features=4096, out_features=1000, bias=True)
      )
    )
    

    【讨论】:

    • torchsummary 现在称为 torchinfo
    【解决方案4】:

    这将显示模型的权重和参数(但不显示输出形状)。

    from torch.nn.modules.module import _addindent
    import torch
    import numpy as np
    def torch_summarize(model, show_weights=True, show_parameters=True):
        """Summarizes torch model by showing trainable parameters and weights."""
        tmpstr = model.__class__.__name__ + ' (\n'
        for key, module in model._modules.items():
            # if it contains layers let call it recursively to get params and weights
            if type(module) in [
                torch.nn.modules.container.Container,
                torch.nn.modules.container.Sequential
            ]:
                modstr = torch_summarize(module)
            else:
                modstr = module.__repr__()
            modstr = _addindent(modstr, 2)
    
            params = sum([np.prod(p.size()) for p in module.parameters()])
            weights = tuple([tuple(p.size()) for p in module.parameters()])
    
            tmpstr += '  (' + key + '): ' + modstr 
            if show_weights:
                tmpstr += ', weights={}'.format(weights)
            if show_parameters:
                tmpstr +=  ', parameters={}'.format(params)
            tmpstr += '\n'   
    
        tmpstr = tmpstr + ')'
        return tmpstr
    
    # Test
    import torchvision.models as models
    model = models.alexnet()
    print(torch_summarize(model))
    
    # # Output
    # AlexNet (
    #   (features): Sequential (
    #     (0): Conv2d(3, 64, kernel_size=(11, 11), stride=(4, 4), padding=(2, 2)), weights=((64, 3, 11, 11), (64,)), parameters=23296
    #     (1): ReLU (inplace), weights=(), parameters=0
    #     (2): MaxPool2d (size=(3, 3), stride=(2, 2), dilation=(1, 1)), weights=(), parameters=0
    #     (3): Conv2d(64, 192, kernel_size=(5, 5), stride=(1, 1), padding=(2, 2)), weights=((192, 64, 5, 5), (192,)), parameters=307392
    #     (4): ReLU (inplace), weights=(), parameters=0
    #     (5): MaxPool2d (size=(3, 3), stride=(2, 2), dilation=(1, 1)), weights=(), parameters=0
    #     (6): Conv2d(192, 384, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)), weights=((384, 192, 3, 3), (384,)), parameters=663936
    #     (7): ReLU (inplace), weights=(), parameters=0
    #     (8): Conv2d(384, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)), weights=((256, 384, 3, 3), (256,)), parameters=884992
    #     (9): ReLU (inplace), weights=(), parameters=0
    #     (10): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)), weights=((256, 256, 3, 3), (256,)), parameters=590080
    #     (11): ReLU (inplace), weights=(), parameters=0
    #     (12): MaxPool2d (size=(3, 3), stride=(2, 2), dilation=(1, 1)), weights=(), parameters=0
    #   ), weights=((64, 3, 11, 11), (64,), (192, 64, 5, 5), (192,), (384, 192, 3, 3), (384,), (256, 384, 3, 3), (256,), (256, 256, 3, 3), (256,)), parameters=2469696
    #   (classifier): Sequential (
    #     (0): Dropout (p = 0.5), weights=(), parameters=0
    #     (1): Linear (9216 -> 4096), weights=((4096, 9216), (4096,)), parameters=37752832
    #     (2): ReLU (inplace), weights=(), parameters=0
    #     (3): Dropout (p = 0.5), weights=(), parameters=0
    #     (4): Linear (4096 -> 4096), weights=((4096, 4096), (4096,)), parameters=16781312
    #     (5): ReLU (inplace), weights=(), parameters=0
    #     (6): Linear (4096 -> 1000), weights=((1000, 4096), (1000,)), parameters=4097000
    #   ), weights=((4096, 9216), (4096,), (4096, 4096), (4096,), (1000, 4096), (1000,)), parameters=58631144
    # )
    

    编辑:isaykatsman 有一个 pytorch PR 可以添加一个 model.summary(),这与 keras https://github.com/pytorch/pytorch/pull/3043/files 完全一样

    【讨论】:

    • 该 PR 已关闭。
    【解决方案5】:

    torchinfo(以前的 torchsummary)包产生与 Keras 类似的输出1(对于给定的输入形状):2

    from torchinfo import summary
    
    model = ConvNet()
    batch_size = 16
    summary(model, input_size=(batch_size, 1, 28, 28))
    
    ==========================================================================================
    Layer (type:depth-idx)                   Output Shape              Param #
    ==========================================================================================
    ├─Conv2d (conv1): 1-1                    [5, 10, 24, 24]           260
    ├─Conv2d (conv2): 1-2                    [5, 20, 8, 8]             5,020
    ├─Dropout2d (conv2_drop): 1-3            [5, 20, 8, 8]             --
    ├─Linear (fc1): 1-4                      [5, 50]                   16,050
    ├─Linear (fc2): 1-5                      [5, 10]                   510
    ==========================================================================================
    Total params: 21,840
    Trainable params: 21,840
    Non-trainable params: 0
    Total mult-adds (M): 7.69
    ==========================================================================================
    Input size (MB): 0.05
    Forward/backward pass size (MB): 0.91
    Params size (MB): 0.09
    Estimated Total Size (MB): 1.05
    ==========================================================================================
    

    注意事项:

    1. Torchinfo 提供的信息与 PyTorch 中 print(your_model) 提供的信息相辅相成,类似于 Tensorflow 的 model.summary()...

    2. 与 Keras 不同,PyTorch 有一个 dynamic computational graph,它可以适应多个调用中的任何兼容输入形状,例如任何足够大的图像尺寸(对于完全卷积网络)。

      因此,它不能为每一层呈现固有一组输入/输出形状,因为这些形状是依赖于输入的,以及为什么在上述包中您必须指定输入尺寸。

    【讨论】:

    • > summary(model, input_size=(batch_size, 1, 28, 28) 这一行是否缺少右括号?
    • @evanrmurphy 是的,感谢您接受!
    【解决方案6】:

    最容易记住(不如 Keras 漂亮):

    print(model)
    

    这也有效:

    repr(model)
    

    如果你只想要参数的数量:

    sum([param.nelement() for param in model.parameters()])
    

    发件人:Is there similar pytorch function as model.summary() as keras? (forum.PyTorch.org)

    【讨论】:

    • 现在可以通过model.num_parameters()简单获取参数个数
    【解决方案7】:

    你可以使用

    from torchsummary import summary
    

    您可以指定设备

    device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
    

    您可以创建一个网络,如果您使用的是 MNIST 数据集,那么以下命令将起作用并显示摘要

    model = Network().to(device)
    summary(model,(1,28,28))
    

    【讨论】:

    【解决方案8】:

    Keras like 使用 torchsummary 进行模型摘要:

    from torchsummary import summary
    summary(model, input_size=(3, 224, 224))
    

    【讨论】:

    • 这与上面建议使用 torchsummary 的三 (3) 个旧答案有何不同?
    • torchsummary 已死。请使用来自 TylerYep 的torchinfo
    【解决方案9】:

    为模型类定义一个对象后,简单地打印模型

    class RNN(nn.Module):
        def __init__(self, input_dim, embedding_dim, hidden_dim, output_dim):
            super().__init__()
    
            self.embedding = nn.Embedding(input_dim, embedding_dim)
            self.rnn = nn.RNN(embedding_dim, hidden_dim)
            self.fc = nn.Linear(hidden_dim, output_dim)
        def forward():
            ...
    
    model = RNN(input_dim, embedding_dim, hidden_dim, output_dim)
    print(model)
    

    【讨论】:

      【解决方案10】:

      summary(my_model, (3, 224, 224), device = 'cpu') 将解决问题。

      【讨论】:

      • 这不起作用。 summary 既不是 PyTorch 也不是 Python 函数。
      • from torchinfo import summary
      猜你喜欢
      • 1970-01-01
      • 2022-11-17
      • 2021-04-10
      • 2020-06-14
      • 2018-08-18
      • 1970-01-01
      • 1970-01-01
      • 2021-12-04
      相关资源
      最近更新 更多