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