自己做网站要钱么,沈阳计算机培训短期速成班,直播视频软件哪个好,建设厅五大员证书查询网站文章目录 前言一、特征图可视化1.1 V7.0的小bug 二、可视化指定层三、合并通道可视化总结 前言
对于特征图可视化感兴趣可以参考我的另一篇记录#xff1a;六行代码实现#xff1a;特征图提取与特征图可视化#xff0c;可以实现分类网络的特征图可视化
最近忙论文#xf… 文章目录 前言一、特征图可视化1.1 V7.0的小bug 二、可视化指定层三、合并通道可视化总结 前言
对于特征图可视化感兴趣可以参考我的另一篇记录六行代码实现特征图提取与特征图可视化可以实现分类网络的特征图可视化
最近忙论文想在yolov5上面做一些改进看源码看了一段时间动手改改代码做一些改进所以做个一系列改进的记录。 一、特征图可视化
yolov5最近的版本提供了特征图可视化的功能在使用detect.py进行推理时在命令行参数传入--visualize即可。
python detect.py --weights best.pt --conf 0.5 --source ../dog.png --visualize传入visualize参数后会可视化所有层的特征图文件默认保存在runs/detect/exp 文件夹下 1.1 V7.0的小bug 我给官方提了个issue回复应该是源码出错了不应该把visualize赋值给save_dir 针对这个可视化的代码其实有个疑问可视化的代码是在models/yolo.py文件下调用的下面是调用特征图可视化的代码在类BaseModel中定义了模型的前向传播过程这里的visualize参数是一个bool类型用于判断是否要可视化特征图但是在可视化函数feature_visualization(x, m.type, m.i, save_dirvisualize)却把visualize传给了save_dirsave_dir应该是特征图的保存路径而不是bool所以这里其实应该做一个更改否则会报错。
这里可以选择不传入save_dir特征图会默认保存到runs/detect/exp 路径下否则可以传入指定路径比如 save_dirPath(../feature_map)
......
# models/yolo.py文件class BaseModel(nn.Module):# YOLOv5 base modeldef forward(self, x, profileFalse, visualizeFalse):return self._forward_once(x, profile, visualize) # single-scale inference, traindef _forward_once(self, x, profileFalse, visualizeFalse):y, dt [], [] # outputsfor m in self.model:if m.f ! -1: # if not from previous layerx y[m.f] if isinstance(m.f, int) else [x if j -1 else y[j] for j in m.f] # from earlier layersif profile:self._profile_one_layer(m, x, dt)x m(x) # runy.append(x if m.i in self.save else None) # save output这里的visualize是一个bool类型但是却传给了save_dirsave_dir应该是特征图的保存路径所以这里其实应该做一个更改否则会报错if visualize:# 更改前 # feature_visualization(x, m.type, m.i, save_dirvisualize)#更改后 feature_visualization(x, m.type, m.i)return x
......yolov5 这里是针对单个通道进行可视化默认最多可视化32个通道参考GitHub的相关issue可以自行修改feature_visualization的各个参数 # utils/plots.pydef feature_visualization(x, module_type, stage, n32, save_dirPath(runs/detect/exp)):x: 输入即可视化的Tensormodule_type: Module type 用于命名区分各层特征图stage: Module stage within model 用于命名区分各层特征图n: Maximum number of feature maps to plot 可视化的通道个数通道数太多不可能全部可视化save_dir: Directory to save results 特征图的保存路径if Detect not in module_type:batch, channels, height, width x.shape # batch, channels, height, widthif height 1 and width 1:# 文件的命名格式 层名层的索引 f save_dir / fstage{stage}_{module_type.split(.)[-1]}_features.png # filename# 按通道数拆分Tensor# 进行逐通道的可视化blocks torch.chunk(x[0].cpu(), channels, dim0) # select batch index 0, block by channelsn min(n, channels) # number of plotsfig, ax plt.subplots(math.ceil(n / 8), 8, tight_layoutTrue) # 8 rows x n/8 colsax ax.ravel()plt.subplots_adjust(wspace0.05, hspace0.05)for i in range(n):ax[i].imshow(blocks[i].squeeze()) # cmapgrayax[i].axis(off)LOGGER.info(fSaving {f}... ({n}/{channels}))plt.savefig(f, dpi300, bbox_inchestight)plt.close()np.save(str(f.with_suffix(.npy)), x[0].cpu().numpy()) # npy save二、可视化指定层
如果不想可视化所有的特征层比如只需要可视化第一个卷积层的输出那么只需要修改判断条件即可 将 if visualize: 修改为 if m.type models.common.Conv and m.i 0:
# models/yolo.py文件class BaseModel(nn.Module):# YOLOv5 base modeldef forward(self, x, profileFalse, visualizeFalse):return self._forward_once(x, profile, visualize) # single-scale inference, traindef _forward_once(self, x, profileFalse, visualizeFalse):y, dt [], [] # outputsfor m in self.model:if m.f ! -1: # if not from previous layerx y[m.f] if isinstance(m.f, int) else [x if j -1 else y[j] for j in m.f] # from earlier layersif profile:self._profile_one_layer(m, x, dt)x m(x) # runy.append(x if m.i in self.save else None) # save output可视化指定层只需要更改一下判断条件即可将 if visualize:修改为 if m.type models.common.Conv and m.i 0:# 修改前# if visualize:# 修改后if m.type models.common.Conv and m.i 0:feature_visualization(x, m.type, m.i)return x
......m.type 表示模块名称m.i表示层的索引即第几层因为有重名的层需要索引加以区分 m.type的命名以 models.common. 模块名比如可视化SPPF就是 models.common.SPPF m.i 即每个层对应得索引SPPF对应得索引是9
三、合并通道可视化
如果不想分通道可视化可以直接可视化整个Tensor。把下面得函数定义加入到utils/plots.py文件下
def feature_visualization_all(x, module_type, stage, save_dirPath(runs/detect/exp)):x: Features to be visualizedmodule_type: Module typestage: Module stage within modeln: Maximum number of feature maps to plotsave_dir: Directory to save resultsif Detect not in module_type:batch, channels, height, width x.shape # batch, channels, height, widthif height 1 and width 1:f save_dir / fstage{stage}_{module_type.split(.)[-1]}_features.png # filenameimg x[0].cpu().transpose(0, 1).sum(1).detach().numpy()plt.imsave(f, img)LOGGER.info(fSaving {f}...)随后在models/yolo.py文件下导入并调用
from models.common import * # noqa
from models.experimental import * # noqa
from utils.autoanchor import check_anchor_order
from utils.general import LOGGER, check_version, check_yaml, make_divisible, print_args# 导入feature_visualization_all
from utils.plots import feature_visualization, feature_visualization_all
from utils.torch_utils import (fuse_conv_and_bn, initialize_weights, model_info, profile, scale_img, select_device, time_sync)......class BaseModel(nn.Module):# YOLOv5 base modeldef forward(self, x, profileFalse, visualizeFalse):return self._forward_once(x, profile, visualize) # single-scale inference, traindef _forward_once(self, x, profileFalse, visualizeFalse):y, dt [], [] # outputsfor m in self.model:if m.f ! -1: # if not from previous layerx y[m.f] if isinstance(m.f, int) else [x if j -1 else y[j] for j in m.f] # from earlier layersif profile:self._profile_one_layer(m, x, dt)x m(x) # runy.append(x if m.i in self.save else None) # save output# 修改后if m.type models.common.Conv and m.i 0:feature_visualization_all(x, m.type, m.i)return x......
原图及检测效果 合并通道特征图可视化
总结
对于特征图可视化感兴趣可以参考我的另一篇记录六行代码实现特征图提取与特征图可视化可以实现分类网络得特征图可视化