1 问题的描述和分析
1.1 问题的描述
在同一个jupyter notebook中,实例化了一个模型A,然后又实例化了一个模型B。
我们训练的是模型B,并且在训练过程中保存了模型B的参数和对应的优化器参数。
结束训练后,退出notebook后再重新进入。实例化模型B,优化器(这里的模型B和优化器和之前训练的是一模一样的),然后载入相应的参数。
开始训练模型B,然后出现了报错。
1.2 问题的分析
在刚开始的时候,实例化了一个模型A,假设这个模型A中有10层卷积层,它们命名为:
conv2d_i (i=0, 1, 2, ..., 9)
然后又实例化了一个模型B,假设这个模型中有7层卷积层,它们命名为:
conv2d_i (i=10, 11, 12, ..., 17)
我们训练模型B时保存的优化器参数保存的是conv2d_i.w_balabala (i=10, 11, 12, ..., 17)
结束训练后,退出notebook后再重新进入。实例化模型B,其中的7层卷积层,它们命名为:
conv2d_i (i=0, 1, 2, ..., 7)
实例化优化器,然后载入相应的参数。
这时模型B的参数可以正常载入,而优化器载入的参数为conv2d_i.w_balabala (i=10, 11, 12, ..., 17)
然后训练,B模型要找优化器要参数,B模型找的是自己的层的名称对应的参数,也就是B模型要找的是conv2d_i.w_balabala (i=0, 1, 2, ..., 7),而优化器中只有命名为conv2d_i.w_balabala (i=10, 11, 12, ..., 17)的参数,所以就报错:“conv2d_0.w_balabala 应该要在优化器的参数列表中”
原话 “conv2d_0.w_0_moment1_0 should in state dict”
2解决办法
法1:在我们预训练模型B的时候,要确保这个模型B是我们开启notebook后第一个实例化的模型。然后在我们之后重新训练模型B的时候,也要确保这个模型B是开启notebook后第一个实例化的模型。
法2:如果你是已经训练了模型,现在要重新训练,那就只能修改优化器参数字典的变量的命名方式了。