赞
踩
翻了很多博客和论坛,一般冻结参数都包括两步:
optimizer.SGD(filter(lambda p: p.requires_grad, model.parameters()), lr=1e-3)
上面就不细讲了,百度大部分都是这种。
先说下我的任务:
我有一个模型由encoder和decoder组成,在预训练时固定decoder的参数,只训练encoder的参数。然后在fine-tune的时候训练所有的参数。
问题:
按照上面的方法,在重新加载模型时会报长度不一致的错误。
ValueError: loaded state dict contains a parameter group that doesn't match the size of optimizer's group
调试了半天发现我加载的模型只保存了encoder部分的参数,但是新的模型是encoder和decoder两部分的参数。所以无法将预训练的参数加载到新的模型里。
解决方法:
只设置参数的属性是True/False,不用过滤优化器中的参数,这样长度就会一致了。
而且在预训练过程中固定的参数确实没有被更新,在fine-tune的时候所有的参数都被更新了,正好符合我们要求。
附上我调式的过程:
- for param in model.parameters():
- param.requires_grad = False
- for param in model.encoder.parameters():
- param.requires_grad = True
输出两次更新的参数,可以发现确实只有encoder更新了,decoder没有被更新。
- for param in model.parameters():
- param.requires_grad = True
同样输出两次更新的参数,可以发现decoder的参数也被更新了。over!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。