栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

mmdetection里进行特征图可视化

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

mmdetection里进行特征图可视化

文章目录
    • @[TOC](文章目录)
  • 前言
  • 1.特征可视化
  • 2.为了在mmdetection使用可视化
  • 效果图
前言

    在mmdetection里实现简单的特征可视化代码,不是像Grad-CAM算法那样对分类或检测直接通过反向传播值进行可视化的,而是就特征层里的最大像数值,我们认为是重要的,将其可视化出来。一般测试的时候用,能够可视化模型的预测效果。训练阶段可以看看,但没太大效果。

1.特征可视化

这个代码结果是将检测的时候特征层,对应像素值大的给可视化出来,附加在原图上。也可以不resize到原图大小,看对应的特征图整个像素的分布。

def draw_feature_map1(features, img_path, save_dir = './work_dirs/feature_map/',name = None):
    '''
    :param features: 特征层。可以是单层,也可以是一个多层的列表
    :param img_path: 测试图像的文件路径
    :param save_dir: 保存生成图像的文件夹
    :return:
    '''
    img = cv2.imread(img_path)      #读取文件路径
    i=0
    if isinstance(features,torch.Tensor):   # 如果是单层
        features = [features]       # 转为列表
    for featuremap in features:     # 循环遍历
        heatmap = featuremap_2_heatmap1(featuremap)	#主要是这个,就是取特征层整个的求和然后平均,归一化
        heatmap = cv2.resize(heatmap, (img.shape[1], img.shape[0]))  # 将热力图的大小调整为与原始图像相同
        heatmap0 = np.uint8(255 * heatmap)  # 将热力图转换为RGB格式,0-255,heatmap0显示红色为关注区域,如果用heatmap则蓝色是关注区域
        heatmap = cv2.applyColorMap(heatmap0, cv2.COLORMAP_JET)  # 将热力图应用于原始图像
        superimposed_img = heatmap * 0.4 + img  # 这里的0.4是热力图强度因子
        plt.imshow(heatmap0)  # ,cmap='gray' ,这里展示下可视化的像素值
        # plt.imshow(superimposed_img)  # ,cmap='gray'
        plt.close()	#关掉展示的图片
        # 下面是用opencv查看图片的
        # cv2.imshow("1",superimposed_img)
        # cv2.waitKey(0)     #这里通过安键盘取消显示继续运行。
        # cv2.destroyAllWindows()
        if not os.path.exists(save_dir):
            os.makedirs(save_dir)
        cv2.imwrite(os.path.join(save_dir, name + str(i) + '.png'), superimposed_img) #superimposed_img:保存的是叠加在原图上的图,也可以保存过程中其他的自己看看
        print(os.path.join(save_dir, name + str(i) + '.png'))
        i = i + 1
def featuremap_2_heatmap1(feature_map):
    assert isinstance(feature_map, torch.Tensor)
    feature_map = feature_map.detach()
    # heatmap = feature_map[:,0,:,:]*0    #
    heatmap = feature_map[:1, 0, :, :] * 0 #取一张图片,初始化为0
    for c in range(feature_map.shape[1]):   # 按通道
        heatmap+=feature_map[:1,c,:,:]      # 像素值相加[1,H,W]
    heatmap = heatmap.cpu().numpy()    #因为数据原来是在GPU上的
    heatmap = np.mean(heatmap, axis=0) #计算像素点的平均值,会下降一维度[H,W]

    heatmap = np.maximum(heatmap, 0)  #返回大于0的数[H,W]
    heatmap /= np.max(heatmap)      #/最大值来设置透明度0-1,[H,W]
    #heatmaps.append(heatmap)

    return heatmap
2.为了在mmdetection使用可视化

1.创建自己的一个检测框架方便专门用来进行可视化singlestage_heatmap.py
这里,只需要将原来的SingleStageDetector(mmdet/models/detectors/singlestage.py)里的代码复制,再对里面的训练和测试的整个流程里进行修改,添加个获取到的图片的全部信息的字典(img_metas)就行。如果熟悉的话,自己根据可视化的代码可以自己修改相应的代码

    def forward_train(self,
                      img,
                      img_metas,
                      gt_bboxes,
                      gt_labels,
                      gt_bboxes_ignore=None):
        """
        Args:
            img (Tensor): Input images of shape (N, C, H, W).
                Typically these should be mean centered and std scaled.
            img_metas (list[dict]): A List of image info dict where each dict
                has: 'img_shape', 'scale_factor', 'flip', and may also contain
                'filename', 'ori_shape', 'pad_shape', and 'img_norm_cfg'.
                For details on the values of these keys see
                :class:`mmdet.datasets.pipelines.Collect`.
            gt_bboxes (list[Tensor]): Each item are the truth boxes for each
                image in [tl_x, tl_y, br_x, br_y] format.
            gt_labels (list[Tensor]): Class indices corresponding to each box
            gt_bboxes_ignore (None | list[Tensor]): Specify which bounding
                boxes can be ignored when computing the loss.

        Returns:
            dict[str, Tensor]: A dictionary of loss components.
        """
        super(SingleStageDetectorHp, self).forward_train(img, img_metas)
        x = self.extract_feat(img,img_metas)    #修改
        losses = self.bbox_head.forward_train(x, img_metas, gt_bboxes,
                                              gt_labels, gt_bboxes_ignore)
        return losses

    def simple_test(self, img, img_metas, rescale=False):
        """Test function without test-time augmentation.

        Args:
            img (torch.Tensor): Images with shape (N, C, H, W).
            img_metas (list[dict]): List of image information.
            rescale (bool, optional): Whether to rescale the results.
                Defaults to False.

        Returns:
            list[list[np.ndarray]]: BBox results of each image and classes.
                The outer list corresponds to each image. The inner list
                corresponds to each class.
        """
        feat = self.extract_feat(img,img_metas)   #FPN的输出
        results_list = self.bbox_head.simple_test(
            feat, img_metas, rescale=rescale) 
        bbox_results = [
            bbox2result(det_bboxes, det_labels, self.bbox_head.num_classes)
            for det_bboxes, det_labels in results_list  #就是将LABEL值与预测的det_bboxes进行匹配
        ]
        return bbox_results

2.经过backbone后,可视化输出的特征层

    def extract_feat(self, img,img_metas):
        """Directly extract features from the backbone+neck."""
        imgpath = img_metas[0]['filename']  # 主要是要图片的原始路径 
        x = self.backbone(img)
        from tools.feature_visualization import draw_feature_map1,feature_map_channel
        draw_feature_map1(x,imgpath,name='inputs_') #特征层,图片路径,保存的文件名
        feature_map_channel(x,imgpath,name='chanel_')
        if self.with_neck:
            x = self.neck(x,imgpath)
        return x

3.在相应的检测器整体框架流程里,导入自己的检测框架
比如在ATSS里

效果图

测试时的可视化resnet50,最后两层

原图:

倒数第二层

最后一层

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/993771.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号