如题,在一个.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....
前面的话,大概可以理解为是命名空间造成的问题,可以这样举例:
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之类的原因
我也遇上类似问题。开始我以为是保存优化器的问题,结果后来模型权重也这样了
也遇到了
您好,这个问题我们的研发同学已经在关注了,正在定位问题,什么时候有结果会及时在这个帖子下同步的~
所以解决办法就是重启呗?
跟你一模一样的问题.....
解决了吗?
项目GitHub上也有人提了这个问题,可以去跟踪一下:https://github.com/PaddlePaddle/Paddle/issues/37968
我也遇到这个问题了 giao
就是optimizer中参数在保存的字典中的键的命名问题,初始化的时候conv2d_2.w_0_moment1_0中conv2d后面的第一个标志数字会递增,建议先把dict打印出来,print(dict.keys())看一下,如果训练了几次应该是从几百或者几千开始,新建一个字典保存修改后的字典键值对即可解决问题。![](https://ai-studio-forum.bj.bcebos.com/E450995797B9485DA696C84D526C88D4)
遇到了同样问题,仔细阅读才发现,开头原话“模型恢复训练,需要重新组网,所以我们需要重启AIStudio,运行MnistDataset数据读取和MNIST网络定义、Trainer部分代码,再执行模型恢复代码”