当前位置:   article > 正文

深度学习模型特征可视化(以yolov4为例)_深度学习特征可视化

深度学习特征可视化

一般来说,深度学习模型中的特征可视化分为两种:GAM/Grad_GAM、特征图可视化。

一、GAM/Grad_GAM可视化

GAM/Grad_GAM即为热力图,可以很直观的看到模型关注的重点区域,如图所示。这种可视化方法有很多帖子可参考,因此不再赘述,放上大佬改好的开源代码链接https://github.com/IDayday/YOLOv4_CAM
这里为特征图不同感受野对应的CAM热力图,由于我需要检测的物体是二轮车,可以看到模型的注意力集中在二轮车区域附近
对于YOLOv4的GAM可视化作者源码,同学在使用过程中出现了一些BUG,现在进行一下说明,帮助大家避坑。
源码使用方法如下:
1、在yolo_cam.py里面将model_path、classes_path、path改为自己的训练好的模型权重、目标类别、输入图片路径(相对位置)
2、直接运行或调试yolo_cam.py
同学在使用过程中出现的报错如下:
在这里插入图片描述
这是因为对张量f进行reshape操作时出现了维度不匹配的情况。让我们从第221行代码进行分析,首先通过赋值过的path读取图片,将图片存入image中,然后调用detect_image()函数,将图片输入进行检测后,将检测结果返回到output_list这个张量中,output_list是一个存了3个tensor的列表,其shape为[[1,507,6],[1,2028,6],[1,8112,6]]。报错的第223行代码通过枚举函数和for语句将output_list中的tensor和对应索引依次取出,进行reshape后加入ret列表中。这里取出第一个tensor处理时就出现了报错,其shape为[1,507,6],总的维度数量为1x507x6=3042。而此时reshape函数中的参数为(1,3,13,13,10),总的维度数量为1x3x13x13x10=5070,总的维度数量不等,所以报错。
解决方案: 将224行ret.append(f.reshape(1,3,stride[i],stride[i],10))中的10改为6,将156行def show_CAM(image_path, feature_maps, class_id, all_ids=10, show_one_layer=True):函数定义处的 all_ids改为6。最后将230行show_CAM(path, ret, 1)中的1改为想要可视化类别的索引即可,但是要注意这里的索引值从0开始,并且不能超过classes.txt的维度大小。比如classes.txt中只有1个类别,索引设为了1,必然报错(应设置为0)。

二、特征图可视化

特征图可视化需要对特征图进行通道分离,将tensor展开后以图片的形式保存。为直观展示效果,从YOLOv4主干网络CSPdarknet53中分别提取shape为(416,416,32)、(208,208,64)、(104,104,128)的特征进行可视化。在CSPDarkNet类中的forward(self, x)函数进行修改,调用模型即可,使用前要先在项目目录下分别创建名为“new_feature_picture0”、“new_feature_picture1”、“new_feature_picture2”的文件夹,代码如下:

def forward(self, x):
    x = self.conv1(x)
    out0 = x
    x = self.stages[0](x)
    out1 = x
    x = self.stages[1](x)
    out2 = x
    out3 = self.stages[2](x)
    out4 = self.stages[3](out3)
    out5 = self.stages[4](out4)
    #-----------------------------------特征可视化---------------------------------#
    image0s = out0
    image1s = out1
    image2s = out2
    #--------通道分离tensor,并可视化每个维度的特征图-------#
    #先清空文件夹中的内容
    shutil.rmtree('new_feature_picture0/')
    os.mkdir('new_feature_picture0/')

    image0s=torch.split(image0s,1,dim=0)   #dim=0是通道的索引,代表image0的第一个通道。'1'表示分离成单个维度,此处分离后image0为装有单通道tensor的元组。  
    k=0
    for image0 in image0s:   
        q=0
        image0=torch.split(image0,1,dim=1)
        for i in image0:
            t='backbone-32-416-416-picture'+str(k)+'-channel-'+str(q)+'.jpg'
            save_image(i,os.path.join('new_feature_picture0',t))
            q=q+1

            # feature_map_sum = sum(ele for ele in image0)
            # save_image(feature_map_sum,os.path.join('new_feature_picture0','feature_map_sum'+'_'+str(k)+'.png'))
        k=k+1        

    #--------通道分离tensor,并可视化每个维度的特征图-------#
    #先清空文件夹中的内容
    shutil.rmtree('new_feature_picture1/')
    os.mkdir('new_feature_picture1/')   

    image1s=torch.split(image1s,1,dim=0)   #dim=0是通道的索引,代表image0的第一个通道。'1'表示分离成单个维度,此处分离后image0为装有单通道tensor的元组。  
    k=0
    for image1 in image1s:   
        q=0
        image1=torch.split(image1,1,dim=1)
        for i in image1:
            t='backbone-64-208-208-picture'+str(k)+'-channel-'+str(q)+'.jpg'
            save_image(i,os.path.join('new_feature_picture1',t))
            q=q+1

            # feature_map_sum = sum(ele for ele in image1)
            # save_image(feature_map_sum,os.path.join('new_feature_picture1','feature_map_sum'+'_'+str(k)+'.png'))
        k=k+1

    #--------通道分离tensor,并可视化每个维度的特征图-------#
    #先清空文件夹中的内容
    shutil.rmtree('new_feature_picture2/')
    os.mkdir('new_feature_picture2/')     
        
    image2s=torch.split(image2s,1,dim=0)   #dim=0是通道的索引,代表image0的第一个通道。'1'表示分离成单个维度,此处分离后image0为装有单通道tensor的元组。  
    k=0
    for image2 in image2s:   
        q=0
        image2=torch.split(image2,1,dim=1)
        for i in image2:
            t='backbone-128-104-104-picture'+str(k)+'-channel-'+str(q)+'.jpg'
            save_image(i,os.path.join('new_feature_picture2',t))
            q=q+1

            # feature_map_sum = sum(ele for ele in image2)
            # save_image(feature_map_sum,os.path.join('new_feature_picture2','feature_map_sum'+'_'+str(k)+'.png'))
        k=k+1
    return out3, out4, out5
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71

可视化完成后,如需要对特征图进行拼接,可参考我的上一篇博客https://blog.csdn.net/weixin_44944382/article/details/123829981?spm=1001.2014.3001.5501,最终效果如下:
原图
(416,416,32),32通道,所以一共由32张图片拼接而成。

(208,208,64)

(104,104,128)

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/2023面试高手/article/detail/133051
推荐阅读
相关标签
  

闽ICP备14008679号