在我的例子中,我希望在cfg/training/yolov7.yaml
中的以下代码中提取并可视化层102、103、104中的特征输出。
# yolov7 head
head:
[[-1, 1, SPPCSPC, [512]], # 51
[-1, 1, Conv, [256, 1, 1]],
[-1, 1, nn.Upsample, [None, 2, 'nearest']],
[37, 1, Conv, [256, 1, 1]], # route backbone P4
[[-1, -2], 1, Concat, [1]],
[-1, 1, Conv, [256, 1, 1]],
[-2, 1, Conv, [256, 1, 1]],
[-1, 1, Conv, [128, 3, 1]],
[-1, 1, Conv, [128, 3, 1]],
[-1, 1, Conv, [128, 3, 1]],
[-1, 1, Conv, [128, 3, 1]],
[[-1, -2, -3, -4, -5, -6], 1, Concat, [1]],
[-1, 1, Conv, [256, 1, 1]], # 63
[-1, 1, Conv, [128, 1, 1]],
[-1, 1, nn.Upsample, [None, 2, 'nearest']],
[24, 1, Conv, [128, 1, 1]], # route backbone P3
[[-1, -2], 1, Concat, [1]],
[-1, 1, Conv, [128, 1, 1]],
[-2, 1, Conv, [128, 1, 1]],
[-1, 1, Conv, [64, 3, 1]],
[-1, 1, Conv, [64, 3, 1]],
[-1, 1, Conv, [64, 3, 1]],
[-1, 1, Conv, [64, 3, 1]],
[[-1, -2, -3, -4, -5, -6], 1, Concat, [1]],
[-1, 1, Conv, [128, 1, 1]], # 75
[-1, 1, MP, []],
[-1, 1, Conv, [128, 1, 1]],
[-3, 1, Conv, [128, 1, 1]],
[-1, 1, Conv, [128, 3, 2]],
[[-1, -3, 63], 1, Concat, [1]],
[-1, 1, Conv, [256, 1, 1]],
[-2, 1, Conv, [256, 1, 1]],
[-1, 1, Conv, [128, 3, 1]],
[-1, 1, Conv, [128, 3, 1]],
[-1, 1, Conv, [128, 3, 1]],
[-1, 1, Conv, [128, 3, 1]],
[[-1, -2, -3, -4, -5, -6], 1, Concat, [1]],
[-1, 1, Conv, [256, 1, 1]], # 88
[-1, 1, MP, []],
[-1, 1, Conv, [256, 1, 1]],
[-3, 1, Conv, [256, 1, 1]],
[-1, 1, Conv, [256, 3, 2]],
[[-1, -3, 51], 1, Concat, [1]],
[-1, 1, Conv, [512, 1, 1]],
[-2, 1, Conv, [512, 1, 1]],
[-1, 1, Conv, [256, 3, 1]],
[-1, 1, Conv, [256, 3, 1]],
[-1, 1, Conv, [256, 3, 1]],
[-1, 1, Conv, [256, 3, 1]],
[[-1, -2, -3, -4, -5, -6], 1, Concat, [1]],
[-1, 1, Conv, [512, 1, 1]], # 101
[75, 1, RepConv, [256, 3, 1]], #extract
[88, 1, RepConv, [512, 3, 1]], #extract
[101, 1, RepConv, [1024, 3, 1]], #extract
[[102,103,104], 1, IDetect, [nc, anchors]], # Detect(P3, P4, P5)
]
然而,我希望能够采取任何层的特点,如果可能的话,因为我可能需要层的特点,而不是这一个。
我该怎么做呢?
我尝试从models/yolo.py
中的Model
类中提取并可视化https://github.com/ultralytics/yolov5/issues/3089,但无法确定要编辑哪些代码以及如何编辑。我尝试对IDetect
类执行相同操作,但也无法确定。
1条答案
按热度按时间0yg35tkg1#
你可以注册一个forward hook到相关的层。根据pytorch documentation,“每次forward()计算完输出后都会调用这个hook。”
从本质上讲,forward hook函数修改了一个全局作用域的变量,这个变量在层
forward
调用终止后仍然存在,你可以将层forward
调用的输出(通过forward hook函数)存储在这个变量中,然后你可以在以后引用它。(明确地说,我相信注册forward钩子会隐式地将
nn.module
更改为全局作用域,这样在函数调用终止后,该值会持续存在。更多信息请参见pytorch文档。)在任何情况下,前向钩子函数都需要以下函数签名:
举个简单的例子:
外部函数本身返回一个函数,因为
register_module_forward_hook
的输入是一个具有上述签名的函数。然后我们可以添加forward钩子到任何模块:
因此,总的来说,您的代码将类似于:
请注意,因为使用前向钩子向
module
“添加全局状态”,pytorch文档建议仅将此特性临时用于调试目的,而不是持久解决方案。对于长期解决方案,您可以修改主模型架构的forward
通道,以将这些值存储为中间输出,并在结束时返回所有这些值。