requires_grad=False
如果您想冻结部分模型并训练其余部分,可以将要冻结的参数的requires_grad 设置为False。
例如,如果你只想保持 VGG16 的卷积部分固定:
model = torchvision.models.vgg16(pretrained=True)
for param in model.features.parameters():
param.requires_grad = False
通过将requires_grad 标志切换为False,将不会保存任何中间缓冲区,直到计算到达某个操作的输入之一需要梯度的点。
torch.no_grad()
使用上下文管理器torch.no_grad 是实现该目标的另一种方法:在no_grad 上下文中,所有计算结果都将具有requires_grad=False,即使输入具有requires_grad=True。请注意,您将无法将渐变反向传播到no_grad 之前的图层。例如:
x = torch.randn(2, 2)
x.requires_grad = True
lin0 = nn.Linear(2, 2)
lin1 = nn.Linear(2, 2)
lin2 = nn.Linear(2, 2)
x1 = lin0(x)
with torch.no_grad():
x2 = lin1(x1)
x3 = lin2(x2)
x3.sum().backward()
print(lin0.weight.grad, lin1.weight.grad, lin2.weight.grad)
输出:
(None, None, tensor([[-1.4481, -1.1789],
[-1.4481, -1.1789]]))
这里 lin1.weight.requires_grad 是 True,但没有计算梯度,因为操作是在 no_grad 上下文中完成的。
model.eval()
如果您的目标不是微调,而是将模型设置为推理模式,最方便的方法是使用torch.no_grad 上下文管理器。在这种情况下,您还必须将模型设置为 评估 模式,这是通过在 nn.Module 上调用 eval() 来实现的,例如:
model = torchvision.models.vgg16(pretrained=True)
model.eval()
此操作将层的属性self.training 设置为False,实际上这将改变Dropout 或BatchNorm 等操作的行为,这些操作在训练和测试时的行为必须不同。