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

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

      • 一、GAM/Grad_GAM可视化
      • 二、特征图可视化

一、GAM/Grad_GAM可视化

GAM/Grad_GAM即为热力图,可以很直观的看到模型关注的重点区域,如图所示。这种可视化方法有很多帖子可参考,因此不再赘述,放上大佬改好的开源代码链接https://github.com/IDayday/YOLOv4_CAM。
深度学习模型特征可视化(以yolov4为例)_第1张图片
对于YOLOv4的GAM可视化作者源码,同学在使用过程中出现了一些BUG,现在进行一下说明,帮助大家避坑。
源码使用方法如下:
1、在yolo_cam.py里面将model_path、classes_path、path改为自己的训练好的模型权重、目标类别、输入图片路径(相对位置)
2、直接运行或调试yolo_cam.py
同学在使用过程中出现的报错如下:
深度学习模型特征可视化(以yolov4为例)_第2张图片
这是因为对张量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

可视化完成后,如需要对特征图进行拼接,可参考我的上一篇博客https://blog.csdn.net/weixin_44944382/article/details/123829981?spm=1001.2014.3001.5501,最终效果如下:
原图深度学习模型特征可视化(以yolov4为例)_第3张图片
(416,416,32),32通道,所以一共由32张图片拼接而成。
深度学习模型特征可视化(以yolov4为例)_第4张图片
(208,208,64)
深度学习模型特征可视化(以yolov4为例)_第5张图片
(104,104,128)
深度学习模型特征可视化(以yolov4为例)_第6张图片

你可能感兴趣的:(深度学习相关,python,深度学习)