You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 03:15:48