网上的方法:
将不更新的参数的requires_grad
设置为False
,同时不将该参数传入optimizer
1.将不更新的参数的requires_grad
设置为False
# 冻结fc1层的参数 \
for name, param in model.named_parameters():
if "fc1" in name:
param.requires_grad = F
2.只将更新的模型参数传入optimizer
# 定义一个fliter,只传入requires_grad=True的模型参数
optimizer = optim.SGD(filter(lambda p : p.requires_grad, model.parameters()), lr=1e-2)
需不需要torch.no_grad() 的问题:
torch.no_grad() 的上下文中执行某些操作时,PyTorch 不会为这些操作自动计算梯度,以节省计算资源。
当我们将需要固定的参数的 requires_grad 属性设置为 False 时,这些参数在计算梯度时就不会被更新,这时不需要使用 torch.no_grad()。
with torch.no_grad() 很容易导致反向传播的时候 某些层 无法计算梯度,导致RuntimeError: element 0 of tensors does not require grad and does not have a grad_fn错误。
所以 with torch.no_grad()尽量放在网络前面层,不用放在最后面的层,固定fc2,梯度会导致无法传播到fc1,导致报错。
转自:[Pytorch函数].requires_grad固定部分参数进行网络训练-优快云博客:
还是报错:
找到了这个说法:
参与loss计算的所有参数都要有梯度才行。
我的loss输入的一部分with torch no_grad了,导致报错,改为这一部分只传入x.data,当成一个常数参与loss的计算中就可以。
除此之外,似乎还可以把这一部分.detach(),让梯度断掉就行。