假设我有一个简单的神经网络设计为:
lin0 = nn.Linear(2, 2)
lin1 = nn.Linear(2, 2)
lin2 = nn.Linear(2, 2)
我的目标是冻结第二层,保持第一层和第三层的权重更新。
我已经尝试过做
x = lin0(x)
with torch.no_grad():
x = lin1(x)
x = lin2(x)
在转发函数中,应该冻结“lin1”的所有参数。然而,我想知道反向传播是否仍然到达第一层,如果是的话,它如何更新权重。是吗?
我实际上尝试了两件事:
就像你说的,在训练时不希望更改参数的一层上使用 torch.no_grad()
将layer.required_grad设置为False
在第一种情况下,第 0 层和第 1 层的参数值没有更改。然而,在第二种情况下,参数并没有仅针对第 1 层更改——就像您想要的那样。我认为当我们使用 torch.no_grad() 时,整个模型在更新参数时就停止了。
P.S:我只是使用 pytorch 中提供的 .parameter() 函数跟踪每个层参数的值。自己尝试一下然后告诉我!
第一例:
型号:
class model(torch.nn.Module):
def __init__(self):
super(model,self).__init__()
self.lin0 = nn.Linear(1,2)
self.lin1 = nn.Linear(2,2)
self.lin2 = nn.Linear(2,10)
def forward(self,x):
x = self.lin0(x)
with torch.no_grad():
x = self.lin1(x)
x = self.lin2(x)
return x
model = model()
第二个实例:
class model(torch.nn.Module):
def __init__(self):
super(model,self).__init__()
self.lin0 = nn.Linear(1,2)
self.lin1 = nn.Linear(2,2)
self.lin2 = nn.Linear(2,10)
def forward(self,x):
x = self.lin0(x)
x = self.lin1(x)
x = self.lin2(x)
return x
model = model()
model.lin1.weight.requires_grad = False
model.lin1.bias.requires_grad = False