yolov5图像识别,yolov5图像分类
本文主要介绍yolov5特征图的可视化。本文通过示例代码介绍了yolov5特性图的可视化方法,非常详细的为您介绍。有需要的朋友可以参考一下。
00-1010前言1、效果图2、使用步骤1、使用方法2、注意事项总结及参考。
目录
最近写论文需要观察中间特征层的特征图。我用了yolov5的代码库,找不到好的轮子,所以咨询了很多,只找到了这个。不过我觉得作者的文笔太复杂了(我之前是这个作者的小粉丝)。参考了github作者yolov5给出的问题建议后,自己写了一个轮子,没有复杂的步骤,借助torchvision中的transforms将张量转化为PIL。希望能给大家带来一些帮助。
前言
我们先上下效果图,因为深层的特征多达1024个。这里只打印了8*8的特征图,用plt.subplot在一张图上显示了64张特征图,原图是我在百度上随便搜的猫:
这是yolov5x.pt检测过程中,第一个C3模块可视化后的第一张64张特征图片:
也可以设置为灰度图像,后续代码中会给出。
可以看出,不同特征图提取的特征几乎都不一样,有的侧重于边缘,有的侧重于整体。当然,这只是第一张C3专题地图。与深层特征相比,浅层特征大部分是完整的,而深层特征较小,是提取的小特征。当然,这些特征图也是相互关联的,网络结构是一个整体。
在yolov5的帮助下,作者在问题中说:
顺便说一句,在我看来,一个单一的特征图可能是一组肤浅的信息,因为你正在看一个二维空间切片,但没有恰当地观察整个特征空间的关系(像卷积那样)。
我想这是一个类比,你可以单独查看彩色图像的R、G、B层,而将它们放在一起查看有助于获得完整的图像。
单个特征图可能是一组肤浅的信息,因为您正在查看2d空间切片,但是您没有正确地观察特征空间中的关系(如卷积那样)。
下面是我自己的理解。通过特征图的可视化,我可以进一步了解卷积做了什么。如果有想进一步交流的朋友,欢迎私信一起讨论学习。
一、效果图
二、使用步骤
方法很简单,只需在utils中添加以下函数general.py或plots.py即可:
将matplotlib.pyplot作为plt导入
从torchvision导入转换
定义特征可视化(特征,模型类型,模型id,特征数量=64):
features:需要可视化的特征地图
model_type:特征映射的类型
model_id:特征映射的id
feature_num:您需要的可视化量
save_dir=features/
如果不是os.path.exists(保存目录):
os.makedirs(s
ave_dir)
# print(features.shape)
# block by channel dimension
blocks = torch.chunk(features, features.shape[1], dim=1)
# # size of feature
# size = features.shape[2], features.shape[3]
plt.figure()
for i in range(feature_num):
torch.squeeze(blocks[i])
feature = transforms.ToPILImage()(blocks[i].squeeze())
# print(feature)
ax = plt.subplot(int(math.sqrt(feature_num)), int(math.sqrt(feature_num)), i+1)
ax.set_xticks([])
ax.set_yticks([])
plt.imshow(feature)
# gray feature
# plt.imshow(feature, cmap=gray)
# plt.show()
plt.savefig(save_dir + {}_{}_feature_map_{}.png
.format(model_type.split(.)[2], model_id, feature_num), dpi=300)
接着在models中的yolo.py中的这个地方:
def forward_once(self, x, profile=False):y, dt = [], [] # outputs
for m in self.model:
if m.f != -1: # if not from previous layer
x = y[m.f] if isinstance(m.f, int) else [x if j == -1 else y[j] for j in m.f] # from earlier layers
if profile:
o = thop.profile(m, inputs=(x,), verbose=False)[0] / 1E9 * 2 if thop else 0 # FLOPS
t = time_synchronized()
for _ in range(10):
_ = m(x)
dt.append((time_synchronized() - t) * 100)
print(%10.1f%10.0f%10.1fms %-40s % (o, m.np, dt[-1], m.type))
x = m(x) # run
y.append(x if m.i in self.save else None) # save output
# add in here
if profile:
print(%.1fms total % sum(dt))
return x
添加如下代码:
feature_vis = Trueif m.type == models.common.C3 and feature_vis:
print(m.type, m.i)
feature_visualization(x, m.type, m.i)
添加在yolo.py后,无论是在detect.py还是在train.py中都会进行可视化特征图。
然而训练的过程中并不一定需要一直可视化特征图,feature_vis参数是用来控制是否保存可视化特征图的,保存的特征图会存在features文件夹中。如果想看其它层的特征只需要修改m.type或是用m.i来进行判断是否可视化特征图。m.type对应的是yaml文件中的module,即yolov5的基础模块,例如c3,conv,spp等等,而m.i则更好理解,即是模块的id,通常就是顺序,如果你尝试修改过配置文件,那么你肯定知道是什么。
如果不明白,多使用print函数,用list.len()和tensor.size去查看列表长度和张量维度,打印出来你就知道了。
这里有一个点我很迷惑,不知道有没有大佬可以告诉我原因,就是我并没有找到yolo.py和detect.py之间的关联,detect.py中使用的是:
model = attempt_load(weights, map_location=device)
而并没有使用yolo.py中的Model函数,但是运行detect.py同样可以可视化特征图,不是很懂pytorch代码中的这个机制,希望有大佬可以指教一下,代码还是有些菜。
2.注意事项
注意1:在yolo.py的开头importfeature_visualization:
from utils.general import feature_visualization
注意2:yolov5无论是在detect还是在train的过程中,都会先对模型进行Summary,即验证你的模型的层数,参数以及是否有梯度,这个过程也会保存特征图,但是不要担心,因为你保存的特征图名字是相同的,会被覆盖,如果你打印的出来log就会看到整个模型跑了两次:
Model Summary: 476 layers, 87730285 parameters, 0 gradients
注意3:建议训练完成的网络使用detect.py来进行验证特征图。
当然在yolo.py里面也可以将'__main__'中的:
model = Model(opt.cfg).to(device)
替换为:
model = attempt_load(opt.weights, map_location=device)
同样可以跑通(把detect.py中的opt.weights复制过来)。在yolo.py中打开Profile,将随机生成的图片换成自己的图片,就可以正常的进行验证。
总结
周末摸鱼时间写了这个(也不算摸鱼,下周该写论文初稿了orz),希望给大家带来帮助,如果有疑问或者错误,在评论区或者私信联系我,之后我会把这个提交一个pr到yolov5的官方仓库里(之前提交了一个visdrone.yaml的配置文件,幸被采用了,参考的就是这个作者的代码,感谢!),就到这里,最后上一个spp结构的特征图输出,希望和大家一起讨论。
以上。
参考
pytorch特征图可视化
pytorch 提取卷积神经网络的特征图可视化
深度学习笔记~卷积网络中特征图的可视化
自用代码 YOLOv5 特征图可视化代码
将tensor张量转换成图片格式并保存
Pytorch中Tensor与各种图像格式的相互转化
到此这篇关于yolov5特征图可视化的文章就介绍到这了,更多相关yolov5可视化内容请搜索盛行IT软件开发工作室以前的文章或继续浏览下面的相关文章希望大家以后多多支持盛行IT软件开发工作室!
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。