简介

深度学习中有时候可视化特征图是必要的,特别是对于语义分割任务,合理分析特征图也许能够发现新的idea!接下来讲解一种Pytorch框架下的可视化方法,这里采取的网络模型为Deeplabv3+,首先介绍一些背景知识和几个函数的使用方法。通常网络模型中的特征图的shape为 [ n , c , h , w ] [n,c,h,w] [n,c,h,w],分别代表batchsize, channel, height, width. 换句话说,我们需要处理的特征图实际上是四维度的Tensor,考虑到可视化特征图需要保存目标图像(二维),因此调用训练好的模型测试时应当设置batchsize为1,则可假定待可视化特征图的shape为 [ 1 , c , h , w ] [1,c,h,w] [1,c,h,w]。这里的可视化思路取决于个人,但是最常见的几个想法应该是:(1)单独拿出一个channel进行可视化;(2)在通道维度上取最大值得到一个channel进行可视化;(3)在通道维度上取平均值得到一个channel进行可视化。那么这里就需要用一些函数来对指定维度进行操作,可以对GPU上的Tensor直接操作,涉及到torch.max(),torch.mean()等函数;也可以将Tensor转到cpu上用numpy库处理,涉及到np.max(),np.mean()等函数。这里简单介绍下这些函数,建议直接查Numpy官方文档和Pytorch官方文档。

函数使用

  1. torch.max(input, dim, keepdim=False, *, out=None) -> (Tensor, LongTensor)
    Returns a namedtuple (values, indices) where values is the maximum value of each row of the input tensor in the given dimension dim. And indices is the index location of each maximum value found (argmax).If keepdim is True, the output tensors are of the same size as input except in the dimension dim where they are of size 1. Otherwise, dim is squeezed (see torch.squeeze()), resulting in the output tensors having 1 fewer dimension than input.
    文档指出:返回的是tuple,包含values和indices两项,且维度默认是会被压缩一维(可以设置不压缩)。假定待处理的特征图Tensor的shape为 [ 1 , c , h , w ] [1,c,h,w] [1,c,h,w],且该Tensor变量名为x:x_channel_max,index = torch.max(x,dim=1)即为使用方法,x_channel_max为通道维度取最大值返回的values,其shape为 [ 1 , h , w ] ( 被 压 缩 一 维 ) [1,h,w](被压缩一维) [1,h,w](被压缩一维),1为batchsize;可见dim=1指定了对1维度进行求max操作, 1 , c , h , w 1,c,h,w 1,c,h,w分别对应的维度为 0 , 1 , 2 , 3 0,1,2,3 0,1,2,3;dim=1就是在通道维度上取最大值,因此对于上图中的toch.max(a,1)也是对1维度操作,原张量a的shape为[h,w],对1维度操作就是对w维度操作,即求行最大值。
  2. torch.mean(input, dim, keepdim=False, *, out=None) → Tensor
    理解同上,返回值只有一个,不是tuple,而是指定维度上的平均值。
  3. numpy.amax(a, axis=None, out=None, keepdims=<no value>, initial=<no value>, where=<no value>)[source]
    理解同上,axis用来指定维度,与numpy.max()是等同函数,其他不再赘述。

可视化特征图


Deeplabv3+的网络结构如上图,在输入图像是 [ 3 , 513 , 513 ] [3,513,513] [3,513,513]的设置下,假定这里想可视化上图中红色虚线框住的浅绿色特征图 X X X,该特征图是ASPP模块后经过 1 × 1 1\times1 1×1卷积的输出,其shape为 [ 1 , 256 , 33 , 33 ] [1,256,33,33] [1,256,33,33]。可以在Decoder的代码中找到该特征图X,考虑到该特征图比较小,因此可以考虑上采样至 [ 1 , 256 , 513 , 513 ] [1,256,513,513] [1,256,513,513]的大小(费时间),再获取空间维度最大值(或均值);也可以在获取空间维度最大值(或均值)之后得到 [ 1 , 33 , 33 ] [1,33,33] [1,33,33],再上采样至 [ 1 , 513 , 513 ] [1,513,513] [1,513,513](时间短)。下面提供一种可视化做法(只有代码片段,仅供参考)。
(1)这是Decoder的代码片段:

    def forward(self, x, low_level_feat):low_level_feat = self.conv1(low_level_feat)low_level_feat = self.bn1(low_level_feat)low_level_feat = self.relu(low_level_feat) #这里1*1卷积得到上图天蓝色虚线框住的特征图 L   x_visualize = x #获取上图红色虚线框住的特征图 X,shape为[1,256,33,33]x_visualize = F.interpolate(x_visualize, size=(513,513), mode='bilinear', align_corners=False)#这种做法费时间 shape为[1,256,513,513]'''#这个做法省时间x_visualize,index = torch.max(x,dim = 1) #shape为[1,33,33]x_visualize = F.interpolate(x_visualize, size=(513,513), mode='bilinear', align_corners=False) #shape为[1,513,513]'''x = F.interpolate(x, size=low_level_feat.size()[2:], mode='bilinear', align_corners=False)x = torch.cat((x, low_level_feat), dim=1)x = self.last_conv(x)return x,x_visualize #返回想要可视化的特征图给输出端

(2)这是主函数测试时代码片段:

       output,x_visualize = self.model(image) #测试时,获取网络模型返回的想要可视化的特征图x_visualize = x_visualize.cpu().numpy() #用Numpy处理返回的[1,256,513,513]特征图x_visualize = np.max(x_visualize,axis=1).reshape(513,513) #shape为[513,513],二维x_visualize = (((x_visualize - np.min(x_visualize))/(np.max(x_visualize)-np.min(x_visualize)))*255).astype(np.uint8) #归一化并映射到0-255的整数,方便伪彩色化savedir =  '/home/mfx/xmf/Seg/pytorch-deeplab-xception-master/run/pascal/deeplab-resnet/'        if not os.path.exists(savedir+'val_pred_temp'):os.mkdir(savedir+'val_pred_temp')   x_visualize = cv2.applyColorMap(x_visualize, cv2.COLORMAP_JET)  # 伪彩色处理   cv2.imwrite(savedir+'val_pred_temp/'+str(i)+'.jpg',x_visualize) #保存可视化图像

可视化效果如下,第一幅是原图(需要被裁剪),第二幅是groundtruth,第三幅是特征图X

如果采取的是np.mean()函数,则效果为如下。对比np.max()函数的效果可以发现,np.max()得到的特征图边界更加明显,而np.mean()函数得到的特征图边界较为模糊,但语义上的类别一致性似乎更好。

同理:如果想可视化网络结构图中天蓝色虚线框住的特征图 L ,其shape为[1,48,129,129],只需稍稍修改Decoder的代码片段为:

    def forward(self, x, low_level_feat):low_level_feat = self.conv1(low_level_feat)low_level_feat = self.bn1(low_level_feat)low_level_feat = self.relu(low_level_feat) #这里1*1卷积得到上图天蓝色虚线框住的特征图 L   x_visualize = low_level_feat #获取上图天蓝色虚线框住的特征图 L,shape为[1,48,129,129]x_visualize = F.interpolate(x_visualize, size=(513,513), mode='bilinear', align_corners=False)#这种做法费时间 shape为[1,48,513,513]'''#这个做法省时间x_visualize,index = torch.max(low_level_feat,dim = 1) #shape为[1,129,129]x_visualize = F.interpolate(x_visualize, size=(513,513), mode='bilinear', align_corners=False) #shape为[1,513,513]'''x = F.interpolate(x, size=low_level_feat.size()[2:], mode='bilinear', align_corners=False)x = torch.cat((x, low_level_feat), dim=1)x = self.last_conv(x)return x,x_visualize #返回想要可视化的特征图给输出端


可以看出,low_level_feat对应的低层次高分辨率特征图果然是细节信息较大,但是却不具备语义信息,所以语义分割网络才会融合低层次和高层次特征,但是可以发现低层次特征存在着大量噪声(无用信息),如同文献描述一样。

总结

可视化特征图的策略有很多,根据自己的思路进行合理的分析说不定会带来新的想法。文献中经常提到,语义分割中的高层次特征图分辨率低,但语义性强;而低层次特征图分辨率高,细节丰富。通过以上的Pytorch可视化特征图,更深一步理解了语义分割任务。

补充

考虑到大家想问完整的代码,这里重新组织了下。feats即为自己想可视化的特征,传入feature_vis()函数即可。

import torch
import torch.nn.functional as F
import cv2
def feature_vis(feats): # feaats形状: [b,c,h,w]output_shape = (512,1024) # 输出形状channel_mean = torch.mean(feats,dim=1,keepdim=True) # channel_max,_ = torch.max(feats,dim=1,keepdim=True)channel_mean = F.interpolate(channel_mean, size=output_shape, mode='bilinear', align_corners=False)channel_mean = channel_mean.squeeze(0).squeeze(0).cpu().numpy() # 四维压缩为二维channel_mean = (((channel_mean - np.min(channel_mean))/(np.max(channel_mean)-np.min(channel_mean)))*255).astype(np.uint8)savedir = '/home/mfx/xmf/mmsegmentation-master/work_dirs/'if not os.path.exists(savedir+'feature_vis'): os.makedirs(savedir+'feature_vis') channel_mean = cv2.applyColorMap(channel_mean, cv2.COLORMAP_JET)cv2.imwrite(savedir+'feature_vis/'+ '0.png',channel_mean)

Pytorch可视化语义分割特征图相关推荐

  1. 如何用PyTorch进行语义分割?

    木易 发自 凹非寺  量子位 报道 | 公众号 QbitAI 很久没给大家带来教程资源啦. 正值PyTorch 1.7更新,那么我们这次便给大家带来一个PyTorch简单实用的教程资源:用PyTorc ...

  2. 如何用PyTorch进行语义分割?一个教程教会你|资源

    木易 发自 凹非寺  量子位 报道 | 公众号 QbitAI 很久没给大家带来教程资源啦. 正值PyTorch 1.7更新,那么我们这次便给大家带来一个PyTorch简单实用的教程资源:用PyTorc ...

  3. python实现语义分割_如何用PyTorch进行语义分割?一文搞定

    很久没给大家带来教程资源啦. 正值PyTorch 1.7更新,那么我们这次便给大家带来一个PyTorch简单实用的教程资源:用PyTorch进行语义分割. 图源:stanford 该教程是基于2020 ...

  4. pytorch 归一化_用PyTorch进行语义分割

    点击上方"机器学习与生成对抗网络",关注"星标" 获取有趣.好玩的前沿干货! 木易 发自 凹非寺  量子位 报道 | 公众号 QbitAI 很久没给大家带来教程 ...

  5. pytorch中使用TensorBoard进行可视化Loss及特征图

    pytorch中使用TensorBoard进行可视化Loss及特征图 安装导入TensorBoard 安装TensorBoard pip install tensorboard 导入TensorBoa ...

  6. FEANet——基于 RGBT的实时语义分割特征增强注意力网络

    Overview Title:FEANet: Feature-Enhanced Attention Network for RGB-Thermal Real-time Semantic Segment ...

  7. 使用PyTorch进行语义分割

    本篇文章使用进行pytorch进行语义分割的实验. 1.什么是语义分割? 语义分割是一项图像分析任务,我们将图像中的每个像素分类为对应的类. 这类似于我们人类在默认情况下一直在做的事情.每当我们看到某 ...

  8. 三个优秀的PyTorch实现语义分割框架

    向AI转型的程序员都关注了这个号???????????? 机器学习AI算法工程   公众号:datayx 使用的VOC数据集链接开放在文章中,预训练模型已上传Github,环境我使用Colab pro ...

  9. 【深度学习】语义分割-综述(卷积)

    这里写目录标题 0.笔记参考 1. 目的 2. 困难点 3. 数据集及评价指标 3.1数据集 3.2评价指标 4.实现架构 5. 模型发展 5.1基于全卷积的对称语义分割模型 5.1.1FCN(201 ...

最新文章

  1. sts引入lombok_Spring Boot中lombok的安装与使用详解
  2. C# HttpWebResponse WebClient 基础连接已经关闭: 发送时发生错误.
  3. 数据库备份策略 分布式_管理优秀的分布式数据团队的4种基本策略
  4. interface接口_Java程序设计--接口interface(笔记)
  5. 20款优秀的可以替代桌面软件的Web应用(转载自JavaEye)
  6. java程序设计从方法学角度描述_(特价书)Java程序设计:从方法学角度描述
  7. Java编程思想目录
  8. 设计FMEA步骤四:失效分析
  9. 员工考勤软件用哪款比较好啊?快看这4款实用考勤软件
  10. PetaLinux 添加启动后自动执行脚本
  11. SQL——数据各项操作代码实现
  12. 计算机基础内容相关的论文,有关于计算机基础论文范文
  13. 2022-2028全球独立水疗浴缸行业调研及趋势分析报告
  14. tp6使用workman实现定时任务
  15. 华为p8 root android6,华为P8root工具
  16. 解释程序与解释程序的缺点,图解——解释程序与编译程序的区别
  17. [UNR #3]百鸽笼
  18. 微软2007日语输入法
  19. WebRTC RTCP PS Feedback
  20. 赛门铁克拆分后蜕变:未来不只是“防病毒”

热门文章

  1. 微软的服务器流量计费,微软修改Windows 10更新策略 即使按流量计费也自动更新...
  2. 圈点iCloud,看晚到的苹果探索云服务
  3. 名帖260 文徵明 行书《杂咏诗卷-自作诗十首》
  4. 从0到9四位数组合用c语言,0到9的四位数密码有多少种排列方式
  5. 循环嵌套问题:为什么大循环在内,小循环在外可以提高程序的运行效率
  6. 公司新来的阿里P7大牛,只用十分钟就教会了我实现高层次的复用
  7. 5G与物联网卫星的融合通信及应用
  8. 华为运营商级路由器配置示例 | L3VdPdNdv4 over SRv6 BE ECMP
  9. 【CodeForces】988E·Divisibility by 25
  10. 计算机网络在音乐软件的应用,软网推荐:简单音乐软件 不凡播放管理