PyTorch提取中间层的特征(Resnet)

     特征提取在深度学习的训练中是经常要做的事情,之前的一篇blog有写到使用pytorch提取Vgg、Resnet、Densenet三种模型下的特征,这里所述的是提取全连接层(FC层)的特征,详情可见:https://blog.youkuaiyun.com/qq_34611579/article/details/84330968

     在本文中,主要是介绍提取中间层的特征,对于特征的提取,可以先把模型的结构输出,不同的模型结构是不一样的;下面拿resnet作为示例;由于pytorch模型很多用到nn.sequential,所以对各层的特征提取要自己去修改forward函数。

# 中间层特征提取
class FeatureExtractor(nn.Module):
    def __init__(self, submodule, extracted_layers):
        super(FeatureExtractor, self).__init__()
        self.submodule = submodule
        self.extracted_layers = extracted_layers

    # 自己修改forward函数
    def forward(self, x):
        outputs = []
        for name, module in self.submodule._modules.items():
            if name is "fc": x = x.view(x.size(0), -1)
            x = module(x)
            if name in self.extracted_layers:
                outputs.append(x)
        return outputs

    这里可以看到,我们自定义了forward函数,由此可以选择在哪一层提取特征。

extract_list = ["conv1", "maxpool", "layer1", "avgpool", "fc"]
img_path = "./1_00001.jpg"
saved_path = "./1_00001.txt"
resnet = models.resnet50(pretrained=True)
# print(resnet) 可以打印看模型结构

transform = transforms.Compose([
    transforms.Resize(256),
    transforms.CenterCrop(224),
    transforms.ToTensor()]
)

img = Image.open(img_path)
img = transform(img)

x = Variable(torch.unsqueeze(img, dim=0).float(), requires_grad=False)

if use_gpu:
    x = x.cuda()
    resnet = resnet.cuda()

extract_result = FeatureExtractor(resnet, extract_list)
print(extract_result(x)[4])  # [0]:conv1  [1]:maxpool  [2]:layer1  [3]:avgpool  [4]:fc

  对于模型的结构我们可以打印出来看看,这里是采用的Resnet,此时forward函数也是针对该模型进行了修改;若比如其他的VGG,DenseNet也可以用类似的方法进行修改。

参考这里所说:https://blog.youkuaiyun.com/qq_24306353/article/details/82995320.

还有一些比如可视化,可参考:https://blog.youkuaiyun.com/xz1308579340/article/details/85622579.

源代码:https://github.com/Messi-Q/Pytorch-extract-feature/blob/master/feature_extract.py.

### PyTorch 特征提取中间过程可视化 在 PyTorch 中实现特征提取并将其中间步骤可视化的常见方式是通过钩子(hooks)。钩子允许开发者捕获神经网络中每一层的输入或输出,从而可以进一步分析这些数据。以下是具体的方法以及代码示例。 #### 使用 Hook 提取中间层输出 PyTorch 的 `register_forward_hook` 方法可以在前向传播过程中拦截特定层的输出。这使得我们可以轻松访问任何一层的激活值,并对其进行后续处理或可视化[^1]。 下面是一个简单的例子,展示了如何使用 hook 来捕捉卷积神经网络某一层的输出: ```python import torch import torchvision.models as models from torchvision import transforms from PIL import Image import matplotlib.pyplot as plt # 加载预训练模型 model = models.resnet18(pretrained=True) # 定义一个变量来存储目标层的输出 activation = {} def get_activation(name): """定义hook函数""" def hook(model, input, output): activation[name] = output.detach() return hook # 注册hook到指定层 (例如resnet的第一个conv layer) model.conv1.register_forward_hook(get_activation('conv1')) # 预处理图片 transform = transforms.Compose([ transforms.Resize((224, 224)), transforms.ToTensor(), ]) img = Image.open("example.jpg") # 替换为实际路径 img_tensor = transform(img).unsqueeze(0) # 添加批次维度 # 执行推理 output = model(img_tensor) # 可视化中间层输出 act = activation['conv1'].squeeze() # 移除多余的维度 plt.figure(figsize=(16, 32)) for i in range(6): # 显示前六个通道 ax = plt.subplot(2, 3, i + 1) ax.set_title(f'Channel {i}') plt.imshow(act[i].detach().numpy(), cmap='gray') plt.show() ``` 上述代码实现了以下功能: - **加载模型**:这里选择了 ResNet18 模型作为演示对象。 - **注册 Hook**:将自定义的 hook 函数绑定至 `conv1` 层上,在每次前向传播时自动保存其输出。 - **运行推断**:传入一张测试图像并通过整个网络完成预测。 - **绘制结果**:选取部分通道显示它们对应的特征图。 这种技术不仅限于 CNNs;对于其他类型的架构同样适用,只需调整挂钩的目标位置即可适应不同的需求[^2]。 另外值得注意的是,当涉及到更复杂的流水线作业或者多阶段的数据转换流程时,类似于 Microsoft 开源工具 DataShaper 或者 Prefect 这样的解决方案可能会提供额外的帮助[^3]。不过本案例主要聚焦于单一任务——即利用 PyTorch 实现特征映射观察器的功能。
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值