迁移网络任务-tacotron2时遇到backbone中的FPN架构没有nn.ModuleDict

1.系统环境

硬件环境(Ascend/GPU/CPU): GPU

MindSpore版本: mindspore=2.0

执行模式(PyNative/ Graph):不限

Python版本:3.7

操作系统平台:Linux

2. 问题描述

迁移网络任务-tacotron2时遇到backbone中的FPN架构没有nn.ModuleDict

3. 解决方案

这里没有使用resnet50+FPN作为backbone,用的是mobilenetv2的特征提取层作为backbone

Torch无法实现的源码如下:

class IntermediateLayerGetter(nn.ModuleDict):  
    """  
    模块包装器,用于从模型中返回中间层  
    它有一个很强的假设,即模块已按照它们被使用的顺序注册到模型中。  
    这意味着,如果你希望这个功能正常工作,**不要**在正向传播中重复使用相同的nn.Module两次。  
    此外,它只能查询直接分配给模型的子模块。因此,如果传入`model`,可以返回`model.feature1`,但不能返回`model.feature1.layer2`。  
    参数:  
        model (nn.Module): 我们将从中提取特征的模型  
        return_layers (Dict[name, new_name]): 一个字典,包含我们要返回激活值的模块名称,字典的键是模块的名称,值是用户指定的返回激活值的名称。  
    """  
    __annotations__ = {  
        "return_layers": Dict[str, str],  
    }  
  
    def __init__(self, model, return_layers):  
        if not set(return_layers).issubset([name for name, _ in model.named_children()]):  
            raise ValueError("return_layers不在模型中")  
  
        orig_return_layers = return_layers  
        return_layers = {str(k): str(v) for k, v in return_layers.items()}  
        layers = OrderedDict()  
  
        # 遍历模型子模块按顺序存入有序字典  
        # 只保存layer4及其之前的结构,舍去之后不用的结构  
        for name, module in model.named_children():  
            layers[name] = module  
            if name in return_layers:  
                del return_layers[name]  
            if not return_layers:  
                break  
  
        super().__init__(layers)  
        self.return_layers = orig_return_layers  
  
    def forward(self, x):  
        out = OrderedDict()  
        # 依次遍历模型的所有子模块,并进行正向传播,  
        # 收集layer1, layer2, layer3, layer4的输出  
        for name, module in self.items():  
            x = module(x)  
            if name in self.return_layers:  
                out_name = self.return_layers[name]  
                out[out_name] = x  
        return out