MXNET - 如何将丢失层添加到 ResNet_v1 预训练模型
MXNET - How to add dropout layer to ResNet_v1 pretrained model
我正在尝试微调 mxnet 中的预训练模型:ResNet50_v1。
该模型没有 dropout,我想添加它以避免过度拟合并使其看起来类似于 I3D_Resnet50_v1_Kinetics400 的最后一层。
我尝试执行以下操作,但在训练时出现错误:
原始网络的最后几层(ResNet50_v1):
...
(8): GlobalAvgPool2D(size=(1, 1), stride=(1, 1), padding=(0, 0), ceil_mode=True, global_pool=True, pool_type=avg, layout=NCHW)
)
(output): Dense(2048 -> 1000, linear)
我的尝试:
classes = 2
model_name = 'ResNet50_v1'
finetune_net = get_model(model_name, pretrained=True)
with finetune_net.name_scope():
finetune_net.output = nn.Dense(2048, in_units=2048)
finetune_net.head = nn.HybridSequential()
finetune_net.head.add(nn.Dropout(0.95))
finetune_net.head.add(nn.Dense(2, in_units=2048))
finetune_net.fc = nn.Dense(2, in_units=2048)
finetune_net.output.initialize(init.Xavier(), ctx = ctx)
finetune_net.head.initialize(init.Xavier(), ctx = ctx)
finetune_net.fc.initialize(init.Xavier(), ctx = ctx)
finetune_net.collect_params().reset_ctx(ctx)
finetune_net.hybridize()
修改后网络的最后几层(ResNet50_v1):
...
(8): GlobalAvgPool2D(size=(1, 1), stride=(1, 1), padding=(0, 0), ceil_mode=True, global_pool=True, pool_type=avg, layout=NCHW)
)
(output): Dense(2048 -> 2048, linear)
(head): HybridSequential(
(0): Dropout(p = 0.95, axes=())
(1): Dense(2048 -> 2, linear)
)
(fc): Dense(2048 -> 2, linear)
)
I3D_Resnet50_v1_Kinetics400的最后一层:
...## Heading ##
(st_avg): GlobalAvgPool3D(size=(1, 1, 1), stride=(1, 1, 1), padding=(0, 0, 0), ceil_mode=True, global_pool=True, pool_type=avg, layout=NCDHW)
(head): HybridSequential(
(0): Dropout(p = 0.8, axes=())
(1): Dense(2048 -> 2, linear)
)
(fc): Dense(2048 -> 2, linear)
这是修改网络的参数的样子
Parameter resnetv10_dense1_weight (shape=(2048, 2048), dtype=float32) write
Parameter resnetv10_dense1_bias (shape=(2048,), dtype=float32) write
Parameter resnetv10_dense2_weight (shape=(2, 2048), dtype=float32) write
Parameter resnetv10_dense2_bias (shape=(2,), dtype=float32) write
Parameter resnetv10_dense3_weight (shape=(2, 2048), dtype=float32) write
Parameter resnetv10_dense3_bias (shape=(2,), dtype=float32) write
训练时出错:
/usr/local/lib/python3.7/dist-packages/mxnet/gluon/block.py:825:用户警告:参数 resnetv10_dense3_bias、resnetv10_dense3_weight、resnetv10_dense2_bias、resnetv10_dense2_weight 是不被任何计算使用。这是故意的吗?
输出 = self.forward(*args)
用户警告:上下文 gpu(0) 上参数 resnetv10_dense2_bias
的梯度自上次 step
以来尚未通过向后更新。这可能意味着您的模型中存在错误,导致它在此迭代中仅使用参数(块)的子集。如果您有意只使用一个子集,请使用 ignore_stale_grad=True 调用步骤以抑制此警告并跳过使用陈旧梯度
更新参数
dense2 和 dense3,我添加的新密集层没有更新。
dense1 已经在模型中,我只是将输出从 1000 更改为 2048。
非常感谢任何帮助,因为我很困...
由于您为模型分配了新层,因此您应该重新实现 hybrid_forward
(或 forward
)方法以将它们包含在计算中:
from mxnet.gluon import nn
from mxnet.init import Xavier
from mxnet.gluon.block import HybridBlock
class MyResNet(HybridBlock):
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.finetune_net = get_model('ResNet50_v1', pretrained=True)
self.finetune_net.output = nn.Dense(2048, in_units=2048)
self.head = nn.HybridSequential()
self.head.add(nn.Dropout(0.95))
self.head.add(nn.Dense(2, in_units=2048))
self.fc = nn.Dense(2, in_units=2048)
def hybrid_forward(self, F, x):
x = self.finetune_net(x)
x = self.head(x)
x = self.fc(x)
return x
def initialize_outputs(self):
self.finetune_net.output.initialize(init=Xavier())
self.head.initialize(init=Xavier())
self.fc.initialize(init=Xavier())
my_resnet = MyResNet()
my_resnet.initialize_outputs()
my_resnet(x)
我正在尝试微调 mxnet 中的预训练模型:ResNet50_v1。 该模型没有 dropout,我想添加它以避免过度拟合并使其看起来类似于 I3D_Resnet50_v1_Kinetics400 的最后一层。 我尝试执行以下操作,但在训练时出现错误:
原始网络的最后几层(ResNet50_v1):
...
(8): GlobalAvgPool2D(size=(1, 1), stride=(1, 1), padding=(0, 0), ceil_mode=True, global_pool=True, pool_type=avg, layout=NCHW)
)
(output): Dense(2048 -> 1000, linear)
我的尝试:
classes = 2
model_name = 'ResNet50_v1'
finetune_net = get_model(model_name, pretrained=True)
with finetune_net.name_scope():
finetune_net.output = nn.Dense(2048, in_units=2048)
finetune_net.head = nn.HybridSequential()
finetune_net.head.add(nn.Dropout(0.95))
finetune_net.head.add(nn.Dense(2, in_units=2048))
finetune_net.fc = nn.Dense(2, in_units=2048)
finetune_net.output.initialize(init.Xavier(), ctx = ctx)
finetune_net.head.initialize(init.Xavier(), ctx = ctx)
finetune_net.fc.initialize(init.Xavier(), ctx = ctx)
finetune_net.collect_params().reset_ctx(ctx)
finetune_net.hybridize()
修改后网络的最后几层(ResNet50_v1):
...
(8): GlobalAvgPool2D(size=(1, 1), stride=(1, 1), padding=(0, 0), ceil_mode=True, global_pool=True, pool_type=avg, layout=NCHW)
)
(output): Dense(2048 -> 2048, linear)
(head): HybridSequential(
(0): Dropout(p = 0.95, axes=())
(1): Dense(2048 -> 2, linear)
)
(fc): Dense(2048 -> 2, linear)
)
I3D_Resnet50_v1_Kinetics400的最后一层:
...## Heading ##
(st_avg): GlobalAvgPool3D(size=(1, 1, 1), stride=(1, 1, 1), padding=(0, 0, 0), ceil_mode=True, global_pool=True, pool_type=avg, layout=NCDHW)
(head): HybridSequential(
(0): Dropout(p = 0.8, axes=())
(1): Dense(2048 -> 2, linear)
)
(fc): Dense(2048 -> 2, linear)
这是修改网络的参数的样子
Parameter resnetv10_dense1_weight (shape=(2048, 2048), dtype=float32) write
Parameter resnetv10_dense1_bias (shape=(2048,), dtype=float32) write
Parameter resnetv10_dense2_weight (shape=(2, 2048), dtype=float32) write
Parameter resnetv10_dense2_bias (shape=(2,), dtype=float32) write
Parameter resnetv10_dense3_weight (shape=(2, 2048), dtype=float32) write
Parameter resnetv10_dense3_bias (shape=(2,), dtype=float32) write
训练时出错:
/usr/local/lib/python3.7/dist-packages/mxnet/gluon/block.py:825:用户警告:参数 resnetv10_dense3_bias、resnetv10_dense3_weight、resnetv10_dense2_bias、resnetv10_dense2_weight 是不被任何计算使用。这是故意的吗? 输出 = self.forward(*args)
用户警告:上下文 gpu(0) 上参数 resnetv10_dense2_bias
的梯度自上次 step
以来尚未通过向后更新。这可能意味着您的模型中存在错误,导致它在此迭代中仅使用参数(块)的子集。如果您有意只使用一个子集,请使用 ignore_stale_grad=True 调用步骤以抑制此警告并跳过使用陈旧梯度
dense2 和 dense3,我添加的新密集层没有更新。 dense1 已经在模型中,我只是将输出从 1000 更改为 2048。
非常感谢任何帮助,因为我很困...
由于您为模型分配了新层,因此您应该重新实现 hybrid_forward
(或 forward
)方法以将它们包含在计算中:
from mxnet.gluon import nn
from mxnet.init import Xavier
from mxnet.gluon.block import HybridBlock
class MyResNet(HybridBlock):
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.finetune_net = get_model('ResNet50_v1', pretrained=True)
self.finetune_net.output = nn.Dense(2048, in_units=2048)
self.head = nn.HybridSequential()
self.head.add(nn.Dropout(0.95))
self.head.add(nn.Dense(2, in_units=2048))
self.fc = nn.Dense(2, in_units=2048)
def hybrid_forward(self, F, x):
x = self.finetune_net(x)
x = self.head(x)
x = self.fc(x)
return x
def initialize_outputs(self):
self.finetune_net.output.initialize(init=Xavier())
self.head.initialize(init=Xavier())
self.fc.initialize(init=Xavier())
my_resnet = MyResNet()
my_resnet.initialize_outputs()
my_resnet(x)