使用场景:最近在复现《Triplet Distillation for deep face recognition》的蒸馏方法,使用深度学习框架pytorch。两个网络,一个网络要固定住参数,loss不回传,参数不更新;另一个网络使用第一个网络的loss进行loss计算,进行正常的网络更新学习;
网上找到一些方法:参考:https://blog.csdn.net/AManFromEarth/article/details/81071823
#对于模型的每个权重,使其不进行反向传播,即固定参数
for param in model.parameters():
param.requires_grad = False
然后我自己就尝试了一番:
checkpoint = torch.load(pt_path)
state_dict = {k.replace("module.", ""): v for k, v in checkpoint.items()}
model.load_state_dict(state_dict)
for k, v in model.named_parameters():
print(k)
v.requires_grad = False # 固定参数
然后在优化器的位置报错:
报错位置:
self.optimizer = optim.SGD(filter(lambda p: p.requires_grad, self.model.parameters()),
# lr=conf.lr, momentum=conf.momentum)
报错形式:
ValueError: optimizing a parameter that doesn't require gradients
错误原因:根据对参考文献的理解,是因为我将所有的参数锁死了,没有参数用于回传更新出的错,所以,我直接将要进行迁移学习(蒸馏)模型的参数放入这里:
self.optimizer = optim.SGD(self.model_mobile.parameters(),
lr = conf.lr, momentum = conf.momentum)
注:self.model_mobile是需要进行迁移学习的模型;
同时在将模型参数传入gpu后,固定参数的大网络,直接使用了测试模式(self.model.eval())进行特征图提取,然后传入loss函数中,进行loss值计算;
这样就成功锁着了网络参数;
验证网络参数锁没锁住的方法,我是查看的测试集上的测试精度,(感觉不太有说服力,大家有好的方法可以推荐下)