首页 Paddle框架 帖子详情
加载优化器参数文件后报错conv2d_2.w_0_moment1_0 should in state dict
收藏
快速回复
Paddle框架 问答模型训练深度学习 3477 12
加载优化器参数文件后报错conv2d_2.w_0_moment1_0 should in state dict
收藏
快速回复
Paddle框架 问答模型训练深度学习 3477 12

如题,在一个.py文件中训练模型并保存模型和优化器参数文件后,执行另一个训练方法(使用相同的模型类创建的对象,保证模型结构没有更改,也保证不存在中文路径加载错误问题),使用opt.set_state_dict(opt_dict)加载刚才保存的优化器参数文件会报错AssertionError: Optimizer set error, conv2d_2.w_0_moment1_0 should in state dict。

但是奇怪的是,如果先执行训练保存优化器参数文件,然后停止运行,然后把前面的训练部分注释掉,而直接执行加载优化器参数文件后进行训练,则一切正常。不知道是什么情况。无论是在aistudio还是本地pycharm运行都存在这个问题。

另外,这个教程页面的代码就存在这个问题:https://www.paddlepaddle.org.cn/tutorials/projectdetail/1516118

在上面的链接【10 【手写数字识别】之动转静部署】这个教程中一共有三个cell,若从头到尾执行所有cell,就会以100%的概率复现该问题。然后接着点击【代码执行器 -> 重启执行器】,重启执行器后,先执行定义网络结构的那个cell(即第一个cell),再执行加载参数文件并训练的cell(即最后一个cell),就一切正常不会报错。不知是什么原因.

另外,如果从头到尾连续执行三个cell后,再多次点击执行最后的一个cell,每次点击后观察报错信息,会发现每次报的错误不一样,具体是AssertionError: Optimizer set error, conv2d_【X】.w_0_moment1_0 should in state dict这行报错信息中【X】的位置第一次是2,接下里每次执行都会加2,分别变成4、6、8、10、12....

0
收藏
回复
全部评论(12)
时间顺序
GT
#2 回复于2021-07

前面的话,大概可以理解为是命名空间造成的问题,可以这样举例:

1. 创建了A模型,A模型中有三个Conv2D且没有设置默认name。如果实例化这部分代码,三个Linear会分别命名为conv2d_0,conv2d_1,conv2d_2,其参数W也会为conv2d_0.w_0...

2. 此时,创建B模型,只创建一个Conv2D,那么由于总的命名空间中已经有了conv2d_2,那么在B中的Conv2D就会变成conv2d_3。

显然,如果A、B为独立的模型,这样并不合适,加载优化器参数时也会由于B中没有从0开始命名而导致找不到conv2d_3。这时在内存中去掉A和B,然后重新实例化B,使B可以从0开始编排name,这样就可以解决问题。当然,这些在Notebook中可能会经常遇到,毕竟Notebook默认不释放内存,属于正常情况。

个人认为,虽然这些能解释的通,说明并非是“Bug”,但一定层面上给大家的体验也不是很好,后续我也将会把这个帖子转发给相关产品同学,感谢反馈~

 
1
回复
T
Tears
#3 回复于2021-07
GT #2
前面的话,大概可以理解为是命名空间造成的问题,可以这样举例: 1. 创建了A模型,A模型中有三个Conv2D且没有设置默认name。如果实例化这部分代码,三个Linear会分别命名为conv2d_0,conv2d_1,conv2d_2,其参数W也会为conv2d_0.w_0... 2. 此时,创建B模型,只创建一个Conv2D,那么由于总的命名空间中已经有了conv2d_2,那么在B中的Conv2D就会变成conv2d_3。 显然,如果A、B为独立的模型,这样并不合适,加载优化器参数时也会由于B中没有从0开始命名而导致找不到conv2d_3。这时在内存中去掉A和B,然后重新实例化B,使B可以从0开始编排name,这样就可以解决问题。当然,这些在Notebook中可能会经常遇到,毕竟Notebook默认不释放内存,属于正常情况。 个人认为,虽然这些能解释的通,说明并非是“Bug”,但一定层面上给大家的体验也不是很好,后续我也将会把这个帖子转发给相关产品同学,感谢反馈~  
展开

你描述的这个情况好像和我遇到的还不一样,我是只有一个模型类,比如class M(),里面只有两个卷积层conv2d_0和conv2d_1,然后我声明了两次M的对象,第二次声明用于加载第一次的优化器参数文件(先试了两次均model=M(),又试了两次声明的对象不同名(第一次model1=M(),model2=M()),我也试过第二次声明前写del model),然后在opt.step()这步均会报conv2d_2.w_0_moment1_0 should in state dict。我也试过只声明一次对象,加载优化器参数文件时候直接使用第一次的对象,此时会报不一样的错,此时会报conv2d_0.w_0_moment1_1 should in state dict。(实际上参数文件中只有conv2d_0.w_0_moment1_0、conv2d_0.w_0_moment2_0,conv2d_1.w_0_moment1_0、conv2d_1.w_0_moment2_0。但没有conv2d_2.xxxxxxxx,也没有conv2d_0.w_0_moment1_1或moment2_1)。

另外,Conv2D没有name这个属性。(其他的层大部分都有name属性)

但我感觉应该还是属于内存中存在某些同名的东西,再次加载会自动加1之类的原因

0
回复
FutureSI
#4 回复于2021-07

我也遇上类似问题。开始我以为是保存优化器的问题,结果后来模型权重也这样了

0
回复
申博未成名不易
#5 回复于2021-08

也遇到了

0
回复
小姐姐都是我的
#6 回复于2021-08

您好,这个问题我们的研发同学已经在关注了,正在定位问题,什么时候有结果会及时在这个帖子下同步的~

0
回复
luzu
#7 回复于2021-10

所以解决办法就是重启呗?

1
回复
l
lf398218282
#8 回复于2021-11

跟你一模一样的问题.....

 

0
回复
j
jackxu081
#9 回复于2021-12

解决了吗?

0
回复
DeepGeGe
#10 回复于2021-12

项目GitHub上也有人提了这个问题,可以去跟踪一下:https://github.com/PaddlePaddle/Paddle/issues/37968

0
回复
炸毛的猫
#11 回复于2022-09

我也遇到这个问题了 giao

0
回复
Yuankus
#12 回复于2022-10

就是optimizer中参数在保存的字典中的键的命名问题,初始化的时候conv2d_2.w_0_moment1_0中conv2d后面的第一个标志数字会递增,建议先把dict打印出来,print(dict.keys())看一下,如果训练了几次应该是从几百或者几千开始,新建一个字典保存修改后的字典键值对即可解决问题。

1
回复
Luosichen02
#13 回复于2023-03

遇到了同样问题,仔细阅读才发现,开头原话“模型恢复训练,需要重新组网,所以我们需要重启AIStudio,运行MnistDataset数据读取和MNIST网络定义、Trainer部分代码,再执行模型恢复代码” 

2
回复
需求/bug反馈?一键提issue告诉我们
发现bug?如果您知道修复办法,欢迎提pr直接参与建设飞桨~
在@后输入用户全名并按空格结束,可艾特全站任一用户