pytorch如何设置.requires_grad False
pytorch how to set .requires_grad False
我想冻结我的一些模型。遵循官方文档:
with torch.no_grad():
linear = nn.Linear(1, 1)
linear.eval()
print(linear.weight.requires_grad)
但它打印 True
而不是 False
。如果我想将模型设置为评估模式,我应该怎么做?
这是方法;
linear = nn.Linear(1,1)
for param in linear.parameters():
param.requires_grad = False
with torch.no_grad():
linear.eval()
print(linear.weight.requires_grad)
输出:错误
要完成@Salih_Karagoz的回答,您还有 torch.set_grad_enabled()
context (further documentation here),它可以用来在 train/eval 模式之间轻松切换:
linear = nn.Linear(1,1)
is_train = False
for param in linear.parameters():
param.requires_grad = is_train
with torch.set_grad_enabled(is_train):
linear.eval()
print(linear.weight.requires_grad)
requires_grad=假
如果您想冻结模型的一部分并训练其余部分,您可以将要冻结的参数中的 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
为真,但未计算梯度,因为操作是在 no_grad
上下文中完成的。
model.eval()
如果您的目标不是微调,而是将模型设置为推理模式,最方便的方法是使用 torch.no_grad
上下文管理器。在这种情况下,您还必须将模型设置为 evaluation 模式,这是通过在 nn.Module
上调用 eval()
来实现的,例如:
model = torchvision.models.vgg16(pretrained=True)
model.eval()
此操作将层的属性 self.training
设置为 False
,实际上这将更改必须表现不同的 Dropout
或 BatchNorm
等操作的行为在训练和测试时间。
这 tutorial 可能会有所帮助。
简而言之,我认为这个问题的好方法可能是:
linear = nn.Linear(1,1)
for param in linear.parameters():
param.requires_grad = False
linear.eval()
print(linear.weight.requires_grad)
不错。诀窍是检查当你定义一个Linear layar时,默认情况下参数会有requires_grad=True
,因为我们想学习,对吧?
l = nn.Linear(1, 1)
p = l.parameters()
for _ in p:
print (_)
# Parameter containing:
# tensor([[-0.3258]], requires_grad=True)
# Parameter containing:
# tensor([0.6040], requires_grad=True)
另一个结构,
with torch.no_grad():
意味着你不能在这里学习。
所以你的代码,只是表明你有能力学习,即使你在 torch.no_grad()
禁止学习的地方。
with torch.no_grad():
linear = nn.Linear(1, 1)
linear.eval()
print(linear.weight.requires_grad) #true
如果你真的打算关闭权重参数requires_grad
,你也可以这样做:
linear.weight.requires_grad_(False)
或
linear.weight.requires_grad = False
所以你的代码可能会变成这样:
with torch.no_grad():
linear = nn.Linear(1, 1)
linear.weight.requires_grad_(False)
linear.eval()
print(linear.weight.requires_grad)
如果您打算为模块中的所有参数切换到 requires_grad:
l = nn.Linear(1, 1)
for _ in l.parameters():
_.requires_grad_(False)
print(_)
我想冻结我的一些模型。遵循官方文档:
with torch.no_grad():
linear = nn.Linear(1, 1)
linear.eval()
print(linear.weight.requires_grad)
但它打印 True
而不是 False
。如果我想将模型设置为评估模式,我应该怎么做?
这是方法;
linear = nn.Linear(1,1)
for param in linear.parameters():
param.requires_grad = False
with torch.no_grad():
linear.eval()
print(linear.weight.requires_grad)
输出:错误
要完成@Salih_Karagoz的回答,您还有 torch.set_grad_enabled()
context (further documentation here),它可以用来在 train/eval 模式之间轻松切换:
linear = nn.Linear(1,1)
is_train = False
for param in linear.parameters():
param.requires_grad = is_train
with torch.set_grad_enabled(is_train):
linear.eval()
print(linear.weight.requires_grad)
requires_grad=假
如果您想冻结模型的一部分并训练其余部分,您可以将要冻结的参数中的 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
为真,但未计算梯度,因为操作是在 no_grad
上下文中完成的。
model.eval()
如果您的目标不是微调,而是将模型设置为推理模式,最方便的方法是使用 torch.no_grad
上下文管理器。在这种情况下,您还必须将模型设置为 evaluation 模式,这是通过在 nn.Module
上调用 eval()
来实现的,例如:
model = torchvision.models.vgg16(pretrained=True)
model.eval()
此操作将层的属性 self.training
设置为 False
,实际上这将更改必须表现不同的 Dropout
或 BatchNorm
等操作的行为在训练和测试时间。
这 tutorial 可能会有所帮助。
简而言之,我认为这个问题的好方法可能是:
linear = nn.Linear(1,1)
for param in linear.parameters():
param.requires_grad = False
linear.eval()
print(linear.weight.requires_grad)
不错。诀窍是检查当你定义一个Linear layar时,默认情况下参数会有requires_grad=True
,因为我们想学习,对吧?
l = nn.Linear(1, 1)
p = l.parameters()
for _ in p:
print (_)
# Parameter containing:
# tensor([[-0.3258]], requires_grad=True)
# Parameter containing:
# tensor([0.6040], requires_grad=True)
另一个结构,
with torch.no_grad():
意味着你不能在这里学习。
所以你的代码,只是表明你有能力学习,即使你在 torch.no_grad()
禁止学习的地方。
with torch.no_grad():
linear = nn.Linear(1, 1)
linear.eval()
print(linear.weight.requires_grad) #true
如果你真的打算关闭权重参数requires_grad
,你也可以这样做:
linear.weight.requires_grad_(False)
或
linear.weight.requires_grad = False
所以你的代码可能会变成这样:
with torch.no_grad():
linear = nn.Linear(1, 1)
linear.weight.requires_grad_(False)
linear.eval()
print(linear.weight.requires_grad)
如果您打算为模块中的所有参数切换到 requires_grad:
l = nn.Linear(1, 1)
for _ in l.parameters():
_.requires_grad_(False)
print(_)