pytorch提取某一层输出,pytorch提取中间层特征
这篇文章主要给大家分享了框架获取中间层输出的3种方法,文章内容介绍详细,需要的小伙伴可以参考一下,希望对你的学习或工作有所帮助
目录
【1】方法一:获取nn .连续的的中间层输出【2】方法二:中间层吸气器【3】方法三:钩子
【1】方法一:获取nn.Sequential的中间层输出
进口火炬
将torch.nn作为神经网络导入
型号=nn .顺序(
nn .Conv2d(3,9,1,1,0,bias=False),
nn .BatchNorm2d(9),
nn .ReLU(inplace=True),
nn .AdaptiveAvgPool2d((1,1)),
)
# 假如想要获得线性单元的输出
x=torch.rand([2,3,224,224])
适用于范围内的我(镜头(型号)):
x=模型[i](x)
如果我==2:
ReLu_out=x
print(ReLu_out.shape:\n\t ,ReLu_out.shape)
print(x.shape:\n\t ,x.shape)
结果:
ReLu_out.shape:
火炬。大小([2,9,224,224])
十。形状:
火炬。大小([2,9,1,1])
【2】方法二:IntermediateLayerGetter
从集合导入订单直接
进口火炬
从火炬进口神经网络
类中间层getter(nn .模块指令):
从模型返回中间层的模块包装
它强烈假设这些模块已经被注册
按照它们被使用的相同顺序。
这意味着一个人应该**不* *重用同一个nn .组件
如果你想成功的话,就要两次。
此外,它只能查询直接
分配给模型。因此,如果"模型"通过,"模型.特征1"可以
被返回,但不是模型.特征1 .图层2 .
参数:
型号(nn .模块):模型,我们将在该模型上提取特征
一个包含名字的字典
模块的激活将作为
字典的关键字,字典的值是名字
返回的激活(用户可以指定)。
def __init__(自身,模型,返回_层):
如果没有设置(return_layers).issubset([name for name,_ in model。具名_子女()]):
提高价值
or("return_layers are not present in model")
orig_return_layers = return_layers
return_layers = {k: v for k, v in return_layers.items()}
layers = OrderedDict()
for name, module in model.named_children():
layers[name] = module
if name in return_layers:
del return_layers[name]
if not return_layers:
break
super(IntermediateLayerGetter, self).__init__(layers)
self.return_layers = orig_return_layers
def forward(self, x):
out = OrderedDict()
for name, module in self.named_children():
x = module(x)
if name in self.return_layers:
out_name = self.return_layers[name]
out[out_name] = x
return out
# examplem = torchvision.models.resnet18(pretrained=True)
# extract layer1 and layer3, giving as names `feat1` and feat2`
new_m = torchvision.models._utils.IntermediateLayerGetter(m,{layer1: feat1, layer3: feat2})
out = new_m(torch.rand(1, 3, 224, 224))
print([(k, v.shape) for k, v in out.items()])
# [(feat1, torch.Size([1, 64, 56, 56])), (feat2, torch.Size([1, 256, 14, 14]))]
作用:
在定义它的时候注明作用的模型(如下例中的m)和要返回的layer(如下例中的layer1,layer3),得到new_m。
使用时喂输入变量,返回的就是对应的layer
。
举例:
m = torchvision.models.resnet18(pretrained=True)# extract layer1 and layer3, giving as names `feat1` and feat2`
new_m = torchvision.models._utils.IntermediateLayerGetter(m,{layer1: feat1, layer3: feat2})
out = new_m(torch.rand(1, 3, 224, 224))
print([(k, v.shape) for k, v in out.items()])
输出结果:
[('feat1', torch.Size([1, 64, 56, 56])), ('feat2', torch.Size([1, 256, 14, 14]))]
【3】方法三:钩子
class TestForHook(nn.Module):def __init__(self):
super().__init__()
self.linear_1 = nn.Linear(in_features=2, out_features=2)
self.linear_2 = nn.Linear(in_features=2, out_features=1)
self.relu = nn.ReLU()
self.relu6 = nn.ReLU6()
self.initialize()
def forward(self, x):
linear_1 = self.linear_1(x)
linear_2 = self.linear_2(linear_1)
relu = self.relu(linear_2)
relu_6 = self.relu6(relu)
layers_in = (x, linear_1, linear_2)
layers_out = (linear_1, linear_2, relu)
return relu_6, layers_in, layers_out
features_in_hook = []
features_out_hook = []
def hook(module, fea_in, fea_out):
features_in_hook.append(fea_in)
features_out_hook.append(fea_out)
return None
net = TestForHook()
第一种写法,按照类型勾,但如果有重复类型的layer比较复杂
net_chilren = net.children()for child in net_chilren:
if not isinstance(child, nn.ReLU6):
child.register_forward_hook(hook=hook)
推荐下面我改的这种写法,因为我自己的网络中,在Sequential
中有很多层,
这种方式可以直接先print(net)
一下,找出自己所需要那个layer
的名称,按名称勾出来
layer_name = relu_6for (name, module) in net.named_modules():
if name == layer_name:
module.register_forward_hook(hook=hook)
print(features_in_hook) # 勾的是指定层的输入
print(features_out_hook) # 勾的是指定层的输出
到此这篇关于分享Pytorch获取中间层输出的3种方法的文章就介绍到这了,更多相关Pytorch获取中间层输出方法内容请搜索盛行IT软件开发工作室以前的文章或继续浏览下面的相关文章希望大家以后多多支持盛行IT软件开发工作室!
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。