python - 如何获取 Pytorch 中每一层的前驱节点?
问题描述
我可以从 pytorch 中得到模型的摘要,就像 keras 一样:
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
resnet = models.resnet18().to(device)
summary(resnet , (3, 224, 224))
结果如下:
----------------------------------------------------------------
Layer (type) Output Shape Param #
================================================================
Conv2d-1 [-1, 64, 112, 112] 9,408
BatchNorm2d-2 [-1, 64, 112, 112] 128
ReLU-3 [-1, 64, 112, 112] 0
MaxPool2d-4 [-1, 64, 56, 56] 0
Conv2d-5 [-1, 64, 56, 56] 36,864
BatchNorm2d-6 [-1, 64, 56, 56] 128
ReLU-7 [-1, 64, 56, 56] 0
Conv2d-8 [-1, 64, 56, 56] 36,864
BatchNorm2d-9 [-1, 64, 56, 56] 128
ReLU-10 [-1, 64, 56, 56] 0
BasicBlock-11 [-1, 64, 56, 56] 0
Conv2d-12 [-1, 64, 56, 56] 36,864
BatchNorm2d-13 [-1, 64, 56, 56] 128
ReLU-14 [-1, 64, 56, 56] 0
Conv2d-15 [-1, 64, 56, 56] 36,864
BatchNorm2d-16 [-1, 64, 56, 56] 128
ReLU-17 [-1, 64, 56, 56] 0
BasicBlock-18 [-1, 64, 56, 56] 0
Conv2d-19 [-1, 128, 28, 28] 73,728
BatchNorm2d-20 [-1, 128, 28, 28] 256
ReLU-21 [-1, 128, 28, 28] 0
Conv2d-22 [-1, 128, 28, 28] 147,456
BatchNorm2d-23 [-1, 128, 28, 28] 256
Conv2d-24 [-1, 128, 28, 28] 8,192
BatchNorm2d-25 [-1, 128, 28, 28] 256
ReLU-26 [-1, 128, 28, 28] 0
BasicBlock-27 [-1, 128, 28, 28] 0
Conv2d-28 [-1, 128, 28, 28] 147,456
BatchNorm2d-29 [-1, 128, 28, 28] 256
ReLU-30 [-1, 128, 28, 28] 0
Conv2d-31 [-1, 128, 28, 28] 147,456
BatchNorm2d-32 [-1, 128, 28, 28] 256
ReLU-33 [-1, 128, 28, 28] 0
BasicBlock-34 [-1, 128, 28, 28] 0
Conv2d-35 [-1, 256, 14, 14] 294,912
BatchNorm2d-36 [-1, 256, 14, 14] 512
ReLU-37 [-1, 256, 14, 14] 0
Conv2d-38 [-1, 256, 14, 14] 589,824
BatchNorm2d-39 [-1, 256, 14, 14] 512
Conv2d-40 [-1, 256, 14, 14] 32,768
BatchNorm2d-41 [-1, 256, 14, 14] 512
ReLU-42 [-1, 256, 14, 14] 0
BasicBlock-43 [-1, 256, 14, 14] 0
Conv2d-44 [-1, 256, 14, 14] 589,824
BatchNorm2d-45 [-1, 256, 14, 14] 512
ReLU-46 [-1, 256, 14, 14] 0
Conv2d-47 [-1, 256, 14, 14] 589,824
BatchNorm2d-48 [-1, 256, 14, 14] 512
ReLU-49 [-1, 256, 14, 14] 0
BasicBlock-50 [-1, 256, 14, 14] 0
Conv2d-51 [-1, 512, 7, 7] 1,179,648
BatchNorm2d-52 [-1, 512, 7, 7] 1,024
ReLU-53 [-1, 512, 7, 7] 0
Conv2d-54 [-1, 512, 7, 7] 2,359,296
BatchNorm2d-55 [-1, 512, 7, 7] 1,024
Conv2d-56 [-1, 512, 7, 7] 131,072
BatchNorm2d-57 [-1, 512, 7, 7] 1,024
ReLU-58 [-1, 512, 7, 7] 0
BasicBlock-59 [-1, 512, 7, 7] 0
Conv2d-60 [-1, 512, 7, 7] 2,359,296
BatchNorm2d-61 [-1, 512, 7, 7] 1,024
ReLU-62 [-1, 512, 7, 7] 0
Conv2d-63 [-1, 512, 7, 7] 2,359,296
BatchNorm2d-64 [-1, 512, 7, 7] 1,024
ReLU-65 [-1, 512, 7, 7] 0
BasicBlock-66 [-1, 512, 7, 7] 0
AvgPool2d-67 [-1, 512, 1, 1] 0
Linear-68 [-1, 1000] 513,000
================================================================
但是在 keras 中,我能够得到每一层的前驱节点。
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]
====================================================================================================
如何获取pytorch中每一层的前驱节点?我查看了 OrderDict,它没有关于前驱节点的信息。如何获取pytorch中每一层前驱节点的信息?
解决方案
你是对的 - PyTorch 使用动态计算图,因此本身没有子/祖先的概念。例如,Inception3
模型是通过声明一堆子模块来创建的,然后通过一个长长的手工编码方法执行,该方法只是以某种方式以某种顺序使用它们。
这允许使用任意流控制,在这种情况下,您将很难判断哪一层是给定层的子层——这取决于数据输入。
然而,对于某些特殊情况,这是可能的。例如,VGG
模型是使用 构建的nn.Sequantial
,它是按顺序应用于其输入的模块列表。如果你有这样的模型
model = nn.Sequential(nn.Linear(30, 40), nn.Linear(40, 20), nn.Linear(20, 30))
你知道第二Linear
层(model[1]
)的祖先是model[0]
,它的孩子是model[2]
。
在未经训练的人看来,Inception 模型似乎可以在很大程度上以nn.Sequantial
容器的形式实现,这将为您提供预期的功能。话虽这么说,它们不是(至少不在torchvision
模型动物园中),所以除了手动之外,你没有办法获得它。
推荐阅读
- javascript - 使用 JavaScript 附加 HTML+RDFa
- php - Json 解码返回 null。怎么了?
- javascript - “严格模式不支持 const 声明”语法错误
- python-3.x - Keras 在每个 epoch 中占用无限增加的内存量
- bash - 为什么 Vs Code 在集成终端中不突出显示颜色?
- amazon-web-services - 将 AWS EC2 快照从 S3 移动到 Glacier
- r - ifelse returning NAs when condition is true
- symfony - 如何在复杂情况下创建数据库/实体
- python - 数据框中的错误输出:分别复制每一行的计算
- spring-boot - Spring Boot 如何通过 PID 解析????使用 log4j2