微调:若所有层的参数不冻结就表示所有特征提取的层用预训练的模型参数代替本应该的随机初始化,修改过的最后一层还是保持随机初始化,这样训练时前面大量特征层的参数和我们自己数据集上理想的参数已很接近,只需在训练过程中自动微调即可
冻结某些层方式一:遍历模型中的层的参数,冻结需要冻结的
# 查看模型一级子层个数
count = 0
for layer in resnet_18.children():
count = count + 1
print(count) # 共10个一级子层
# 迁移学习冻结部分参数
count = 0
for layer in resnet_18.children():
count = count + 1
if count < 10:
for param in layer.parameters():
param.requires_grad = False # 前9个一级子层无需参数更新
# 最后一个(第10个)调整过输出的全连接层不冻住参数
# 将需要优化的参数传入优化器,不需要传入的参数过滤掉
optimizer = torch.optim.Adam(filter(lambda p: p.requires_grad, resnet_18.parameters()), lr=LR)
冻结某些层方式二:先冻结模型的所有层参数,然后在修改模型的某一层,则修改的层的参数不会被冻结
model = torchvision.models.resnet34(pretrained=True)
# 冻结参数
for param in model.parameters():
param.requires_grad = False
model.fc = torch.nn.Sequential(
torch.nn.Linear(in_features=model.fc.in_features, out_features=classes_num)) # 修改模型最后一层(第10层)
查看模型中每层的参数冻结情况:
for k, v in model.named_parameters():
print("{}:参数需要计算梯度并更新吗?{}".format(k, v.requires_grad)) # False表示冻结了,True表示没有冻结