pytorch - 我尝试使用 pytorch children() 将 resnet 分为两部分,但它不起作用
问题描述
这是一个简单的例子。我试图将网络(Resnet50)分为两部分:head
和tail
使用children
. 从概念上讲,这应该有效,但事实并非如此。为什么?
import torch
import torch.nn as nn
from torchvision.models import resnet50
head = nn.Sequential(*list(resnet.children())[:-2])
tail = nn.Sequential(*list(resnet.children())[-2:])
x = torch.zeros(1, 3, 160, 160)
resnet(x).shape # torch.Size([1, 1000])
head(x).shape # torch.Size([1, 2048, 5, 5])
tail(head(x)).shape # Error: RuntimeError: size mismatch, m1: [2048 x 1], m2: [2048 x 1000] at /pytorch/aten/src/TH/generic/THTensorMath.cpp:136
对于信息,尾巴不过是
Sequential(
(0): AdaptiveAvgPool2d(output_size=(1, 1))
(1): Linear(in_features=2048, out_features=1000, bias=True)
)
所以我实际上知道,如果我能做到这一点。但是,为什么重塑功能 ( view
) 不在孩子们身上呢?
pool =resnet._modules['avgpool']
fc = resnet._modules['fc']
fc(pool(head(x)).view(1, -1))
解决方案
您要做的是将特征提取器与分类器分开。
我应该立即指出的是,Resnet不是一个顺序模型(顾名思义 -残差网络- 它作为残差)!
因此,将其编译为 a
nn.Sequential
将不准确。.children()
模型定义、排序显示的层与该模型功能的实际底层实现之间存在差异forward
。
您使用的展平并未在所有模型
view(1, -1)
中注册为图层。torchvision.models.resnet*
相反,它在定义中的这一行forward
执行:x = torch.flatten(x, 1)
他们可以将其注册为 as 中的一个层,以在
__init__
as实现中self.flatten = nn.Flatten()
使用。forward
x = self.flatten(x)
即便如此,与(参见第一点)
fc(pool(head(x)).view(1, -1))
完全不同。resnet(x)
推荐阅读
- node.js - Google Cloud Speech Recognition grpc 版本与 VSCode Electron 版本不兼容
- sql-server - 如何在 SQL 比较中比较脚本文件夹从 TFS 到数据库时检测 TFS 数据库 CLR 程序集文件
- python - Python3 中是否有机会创建数组数组的矩阵?
- node.js - 使用 NodeJS HTTP 服务器对 HTTPS 端点的 POST 请求是否易受攻击?
- css - 如何使用 Sass 和 BEM 编写修饰符
- firebase - 从数据库读取时权限被拒绝
- python - 如何在 Flask Python 中修复“找不到此页面”?
- html - 我正在尝试让我的 CSS 再次在本地工作
- python-3.x - readline() 导致 pyserial python 2 和 3 的兼容性
- amazon-web-services - 将 HBase 中的数据作为 RDD 直接查询到 Spark 中,还是通过 Phoenix 作为 Dataframe 查询?