Python类继承后模型打印未显示roi_head的原因及解决方法
问题背景
我在同一文件夹下有5个Python类文件,结构如下:
Folder -main.py -main_class.py -sub_of_first.py -sub_of_second.py -sub_of_third.py
各文件代码
main.py(调用MainClass)
def main(): model = MainClass(backbone, )
main_class.py(MainClass继承FirstClass)
from .sub_of_first import FirstClass class MainClass(FirstClass): """Implementation of Fast R-CNN""" def __init__(self, backbone, roi_head, train_cfg, test_cfg, neck=None, pretrained=None, init_cfg=None): super(MainClass, self).__init__( backbone=backbone, neck=neck, roi_head=roi_head, train_cfg=train_cfg, test_cfg=test_cfg, pretrained=pretrained, init_cfg=init_cfg) def method1(self): test=1
sub_of_first.py(FirstClass定义)
from .base import BaseDetector from .sub_of_second import FirstSubClass from .sub_of_third import SecondSubClass import warnings class FirstClass(BaseDetector): """Base class for two-stage detectors. Two-stage detectors typically consisting of a region proposal network and a task-specific regression head. """ def __init__(self, backbone, neck=None, rpn_head=None, roi_head=None, train_cfg=None, test_cfg=None, pretrained=None, init_cfg=None): super(FirstClass, self).__init__(init_cfg) if pretrained: warnings.warn('DeprecationWarning: pretrained is deprecated, ' 'please use "init_cfg" instead') backbone.pretrained = pretrained args = backbone.copy() args.pop('type') self.backbone = FirstSubClass(args) self.roi_head = SecondSubClass(bbox_ext, bbox_head, train_cfg, test_cfg)
sub_of_second.py(FirstSubClass定义)
import torch.nn as nn class FirstSubClass(nn.Module): def __init__(self,): super().__init__() def somemethod(self): test=1
sub_of_third.py(SecondSubClass定义)
class SecondSubClass(StandardRoIHead): def __init__(self, bbox_ext, bbox_head, train_cfg, test_cfg): super(SecondSubClass, self).__init__( bbox_roi_extractor=bbox_ext, bbox_head=bbox_head, train_cfg=train_cfg, test_cfg=test_cfg) def someothersmethod(self): test=1
问题现象
在main.py中打印model时,输出仅显示backbone,无roi_head:
MainClass( (backbone): FirstSubClass( ) )
但调试时打印model.roi_head能获取到对应实例:
p model.roi_head <Folder.SecondSubClass object at 0x7fd1dc88f210>
疑问解答
1. 为什么SecondSubClass未显示在MainClass的打印结构中?
PyTorch的nn.Module打印逻辑(__repr__方法)只识别注册为子模块的对象——也就是通过self.add_module()添加,或直接赋值的nn.Module子类实例(会自动注册)。
你的self.roi_head虽然是实例,但如果StandardRoIHead(SecondSubClass的父类)没正确继承nn.Module,或者BaseDetector(FirstClass的父类)的__repr__被重写后只遍历特定属性(比如仅处理backbone),就会导致roi_head不被纳入打印结构。
2. 如何让roi_head出现在模型打印结构里?
- 先确认
StandardRoIHead是否继承自nn.Module,如果没有,修改为class StandardRoIHead(nn.Module):。 - 若
StandardRoIHead已是nn.Module子类,可在FirstClass的__init__中显式注册roi_head,替代直接赋值:# 替换sub_of_first.py中self.roi_head的赋值代码 self.roi_head = self.add_module('roi_head', SecondSubClass(bbox_ext, bbox_head, train_cfg, test_cfg)) - 检查
BaseDetector的__repr__方法,若被重写,需确保遍历所有注册的子模块,而非仅筛选特定属性。
3. 为什么backbone可以显示而roi_head不行?
self.backbone赋值的是FirstSubClass实例,该类直接继承nn.Module,赋值时会被PyTorch自动注册为子模块,因此打印时会被包含。
而self.roi_head对应的SecondSubClass继承自StandardRoIHead,如果StandardRoIHead不是nn.Module子类,或内部未完成模块注册,那么self.roi_head只是普通Python对象,不会被PyTorch的模块打印机制识别,自然不会出现在输出结构中。
内容的提问来源于stack exchange,提问作者batuman
相关产品推荐
相关产品推荐

