神经网络输出中间特征图

在进行神经网络的训练过程中,会生成不同的特征图信息,这些特征图中包含大量图像信息,如轮廓信息,细节信息等,然而,我们一般只获取最终的输出结果,至于中间的特征图则很少关注。

前两天师弟突然问起了这个问题,但我也没有头绪,后来和师弟研究了一下,大概有了一个思路。

即每个特征提取模块都会输出一个特征图,这些特征图的每个像素实际上就是一些数值,那么只需要将这些数值保存,再以图像的形式展现出来便OK了。

基于这个思路,我们来进行设计。在观测输出的特征图时,我们可以使用推理代码来进行输出,因为推理时所消耗的资源较少且推理时可以很明确我们输入的图像是什么。
至于要想实现的效果:

原图:

在这里插入图片描述

输出的特征图:

在这里插入图片描述
那么该如何进行呢?
首先是要明确你要输出哪个阶段的特征图像,博主分别选择了主干网络四个阶段的输出结果,输出的特征图大小分别为:

x的shape: torch.Size([1, 64, 200, 300])
x的shape: torch.Size([1, 128, 100, 150])
x的shape: torch.Size([1, 320, 50, 75])
x的shape: torch.Size([1, 512, 25, 38])

代码实现

在要输出特征图的模块后面讲特征图保存为numpy的格式:

sb = x.cpu().data.numpy()
np.save('matric'+str(i)+'.npy', sb)#这里的i是对应四个阶段的id

读取numpy格式数据并转换为特征图:

import numpy as np
import os
import matplotlib.pyplot as plt
import torch
import torch.nn as nn

def normalization(data):  # NORMALIZE TO [0,1]
    _range = np.max(data) - np.min(data)
    data = (data - np.min(data)) / _range  # [0,1]
    return data

def fm_vis(feats, save_dir, save_name):
    save_dir = os.path.join(save_dir, save_name)
    if not os.path.exists(save_dir):
        os.makedirs(save_dir)

    feats = normalization(feats[0].cpu().data.numpy())
    for idx in range(min(feats.shape[0], 200*300)):  # CHANNLE NUMBER
        fms = feats[idx, :, :]
        plt.imshow(fms)
        plt.savefig(os.path.join(save_dir, save_name + '_' + str(idx) + ".png"))
        
for i in range(0,4):
    s_b1 = np.load('matric'+str(i)+'.npy')
    print(s_b1)
    s_b2 = torch.from_numpy(s_b1)
    out_dir = "outputs"
    s_b = s_b2.reshape(1, 64, 200, 300)
    fm_vis(s_b, out_dir, "s_b_vis"+str(i))

最终结果:输出四个阶段的特征图,博主选了其中几张:

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
在PyTorch中,神经网络可以通过使用intermediate feature map来输出中间特征中间特征是指在网络的各个层次中生成的输出结果,这些结果可以从网络中间的某个层次获取。 要输出中间特征,我们首先需要定义一个钩子函数。钩子函数可以在网络的每个层次被激活时调用,这样我们就可以获取到中间特征。在PyTorch中,我们可以使用register_forward_hook()方法来为每个层次注册一个钩子函数。 以一个简单的卷积神经网络为例,以下是如何输出中间特征的代码片段: ``` import torch import torch.nn as nn # 定义网络 class MyNet(nn.Module): def __init__(self): super(MyNet, self).__init__() self.conv1 = nn.Conv2d(3, 64, kernel_size=3, stride=1, padding=1) self.conv2 = nn.Conv2d(64, 128, kernel_size=3, stride=1, padding=1) def forward(self, x): x = self.conv1(x) # 定义钩子函数,在此处获取中间特征 handle = x.register_forward_hook(self.hook_fn) x = self.conv2(x) handle.remove() return x # 定义钩子函数 def hook_fn(self, module, input, output): print(output.size()) # 创建网络实例 net = MyNet() # 创建输入数据 input_data = torch.randn(1, 3, 32, 32) # 前向传播,并输出中间特征 output = net(input_data) ``` 在上述代码中,我们定义了一个名为hook_fn()的钩子函数,它将在每个卷积层的计算完成时被调用。在hook_fn()中,我们可以通过output参数获取到中间特征输出大小。 通过调用register_forward_hook()方法,我们向conv1层注册了一个钩子函数。在钩子函数内部,我们打印了输出output的大小。然后我们通过调用conv2继续前向传播,最终返回网络输出结果。 总结起来,要在PyTorch中输出中间特征,我们需要定义一个钩子函数,并将其注册到需要获取中间特征的层次上。然后,通过前向传播获取网络输出,钩子函数将在每个层次的计算完成后被调用,我们可以在钩子函数中获取到中间特征输出

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

彭祥.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值