有没有办法修改 GluonCV 预训练对象检测模型的层
Is there a way to modify the layers of a GluonCV pretrained object detection model
你好,Whosebug。
我希望用可变形的卷积层替换用于对象检测的 GluonCV 预训练模型的卷积层。具体来说,我希望替换 CNN 中用于对象检测模型特征提取的卷积层。我的目标是替换 Faster 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
)
我通过执行以下步骤解决了这个问题:
- 从 GluonCV 的 Github Repo 复制 SSD 模型的源代码到自己的
class 文件
- 修改 class 文件以合并所需的更改(在我的例子中用可变形卷积替换某些卷积)以创建我的修改版本
- 加载原始 SSD模型,然后将原始模型的参数保存为'transfer.params'
- 创建我的 修改后的 SSD 模型,然后加载 'transfer.params'(这是 原始 模型的权重)allow_missing=真 & ignore_extra = 真
生成的修改后的模型将具有预先训练的权重,其中层的名称匹配,但根据需要修改的层除外。
可以扩展这些步骤以根据需要修改 backbone 网络。
你好,Whosebug。
我希望用可变形的卷积层替换用于对象检测的 GluonCV 预训练模型的卷积层。具体来说,我希望替换 CNN 中用于对象检测模型特征提取的卷积层。我的目标是替换 Faster 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
)
我通过执行以下步骤解决了这个问题:
- 从 GluonCV 的 Github Repo 复制 SSD 模型的源代码到自己的 class 文件
- 修改 class 文件以合并所需的更改(在我的例子中用可变形卷积替换某些卷积)以创建我的修改版本
- 加载原始 SSD模型,然后将原始模型的参数保存为'transfer.params'
- 创建我的 修改后的 SSD 模型,然后加载 'transfer.params'(这是 原始 模型的权重)allow_missing=真 & ignore_extra = 真
生成的修改后的模型将具有预先训练的权重,其中层的名称匹配,但根据需要修改的层除外。
可以扩展这些步骤以根据需要修改 backbone 网络。