如何在torch.optim.LBFGS的优化器更新网络参数下限制网络权重的范围?
①网上搜到的限制网络权重范围的方法有2种:设置类/在训练中限制如下:
class weightConstraint(object):
def __init__(self):
pass
def __call__(self, module):
if hasattr(module, 'weight'):
# print("Entered")
w = module.weight.data
w = w.clamp(0,99) # 将参数范围限制到0-1之间
module.weight.data = w
或者
for p in net.parameters():
p.register_hook(lambda grad: torch.clamp(grad, 0,10))
这两种方法对Adam等优化器都有效果,但是我用的是LBFGS优化器,它的格式是要接收一个闭包的函数:
def loss_func_LBFGS(self):
theta_pred, k_pred, psi_pred = self.RRE_net(self.z,self.t)
theta_t_pred, psi_z_pred, psi_zz_pred, k_z_pred, f_pred=self.f_net(self.z_rre,self.t_rre)
loss = torch.mean((self.theta - theta_pred) ** 2)*10 + 0.1*torch.mean(f_pred ** 2)
#loss = torch.mean((self.theta - theta_pred) ** 2)
self.optimizer.zero_grad()
loss.backward()
self.iter += 1
print(self.iter,'======',loss.item())
return loss
self.optimizer.step(self.loss_func_LBFGS)
主要问题就出现在:我把这两种方法都加在这个闭包函数中添加了 都没用 不知道该如何修改?
【以下回答由 GPT 生成】
LBFGS优化器在更新网络参数时无法直接使用方法一和方法二来限制权重范围。LBFGS优化器需要接收一个闭包函数作为参数,并且没有提供像register_hook方法一样的钩子函数来限制梯度。下面是一个可以使用的解决方案:
def closure():
optimizer.zero_grad()
output = net(input)
loss = criterion(output, target)
loss.backward()
return loss
def closure():
optimizer.zero_grad()
output = net(input)
loss = criterion(output, target)
# 限制权重范围
for p in net.parameters():
p.data = p.data.clamp(0, 99)
loss.backward()
return loss
optimizer = torch.optim.LBFGS(net.parameters())
def train():
# ...
optimizer.step(closure)
这样,每次更新参数之前,都会对权重进行限制,然后再计算梯度和更新参数。
这是一种可以在LBFGS优化器中限制权重范围的解决方案,希望对你有帮助。如果这个方案无法满足你的需求,请告诉我,我会尽力提供其他的解决方案。