有没有办法修改GluonCV预训练对象检测模型的各层

时间:2019-08-24 07:22:47

标签: python deep-learning object-detection mxnet

早上好,StackOverflow。

我正在寻找将GluonCV预训练模型的卷积层替换为可变形的卷积层,以用于物体检测。具体来说,我正在寻找替换用于对象检测模型特征提取的CNN内部的卷积层。我的目标是更换更快的RCNN和SSD检测模型。

我尝试了以下代码段:

def replace_conv2D(net):
    for key, layer in net._children.items():
        if isinstance(layer, gluon.nn.Conv2D):
            new_conv = gluon.nn.Conv2D(
                channels=layer._channels // 2,
                kernel_size=layer._kwargs['kernel'],
                strides=layer._kwargs['stride'],
                padding=layer._kwargs['pad'],
                in_channels=layer._in_channels // 2)
            with net.name_scope():
                net.register_child(new_conv, key)
            new_conv.initialize(mx.init.Xavier())
        else:
            replace_conv2D(layer)
net = gluon.model_zoo.vision.get_model("resnet18_v1", pretrained=True)
replace_conv2D(net)

并尝试验证使用以下方法替换了模型的卷积层:

def replace_conv2D(net):
    for key, layer in net._children.items():
        print(f"{key}:{layer}")

但是我无法验证我的对象检测模型是否替换了其卷积层。我只能验证它是否适用于图像分类模型

它适用于基本的resnet50模型(图像分类)

之前(ResNet:50)

ResNetV1(
  (features): HybridSequential(
    (0): Conv2D(3 -> 64, kernel_size=(7, 7), stride=(2, 2), padding=(3, 3), bias=False)
    (1): BatchNorm(axis=1, eps=1e-05, momentum=0.9, fix_gamma=False, use_global_stats=False, in_channels=64)
) 

之后(ResNet50)

ResNetV1(
  (features): HybridSequential(
    (0): DeformableConvolution(None -> 64, kernel_size=(7, 7), stride=(2, 2), padding=(3, 3))
    (1): BatchNorm(axis=1, eps=1e-05, momentum=0.9, fix_gamma=False, use_global_stats=False, in_channels=64)
)

但是对于SSD_resnet50模型(对象检测):

我遇到以下输出作为第一层:

features FeatureExpander(
<Symbol group [ssd2_resnetv10_stage3_activation5, ssd2_resnetv10_stage4_activation2, ssd2_expand_reu0, ssd2_expand_reu1, ssd2_expand_reu2, ssd2_expand_reu3]> : 1 -> 6
)

方法运行后,我没有观察到任何变化:

features FeatureExpander(
<Symbol group [ssd2_resnetv10_stage3_activation5, ssd2_resnetv10_stage4_activation2, ssd2_expand_reu0, ssd2_expand_reu1, ssd2_expand_reu2, ssd2_expand_reu3]> : 1 -> 6
)

1 个答案:

答案 0 :(得分:1)

我通过执行以下步骤解决了该问题:

  1. 将GluonCV的Github Repo中的SSD模型的源代码复制到其自身中 课程文件
  2. 修改类文件以合并所需的更改(在我的情况下将某些卷积替换为可变形卷积)以创建修改后的版本
  3. 加载原始 SSD模型,然后将原始模型的参数保存为'transfer.params'
  4. 创建我的修改后的 SSD模型,然后使用allow_missing = True&ignore_extra = True
  5. 加载“ transfer.params”(原始模型的权重)

修改后的结果模型将具有经过预训练的权重,其中层的名称相匹配,但可以根据需要修改的层除外。

可以扩展这些步骤,以根据需要修改主干网络。