使用PyTorch Optimizer最小化函数时返回值全部相同的问题
问题原因
你在循环里执行list_params.append(params)时,添加的是张量对象的引用,而非当前迭代参数的副本。PyTorch的张量属于可变对象,每次optimizer.step()都会直接修改params这个张量的内部数值,列表里的所有元素最终都指向同一个张量实例,所以显示的全是最后一次迭代后的结果。
解决方法
要保存每次迭代的参数值,必须在循环中保存参数的副本,而非引用。以下两种常用方式:
方法1:创建张量副本(按需保留梯度)
如果后续还需要用到梯度信息,直接用clone()创建副本:
list_params.append(params.clone())
如果只是用于可视化等不需要梯度的场景,先解除梯度关联再克隆更高效:
list_params.append(params.detach().clone())
方法2:转换为NumPy数组(仅保存数值)
如果只需要参数的数值结果,可转换成NumPy数组存储:
list_params.append(params.detach().numpy())
修改后的完整代码
import torch def eggholder_function(x): return -(x[1] + 47) * torch.sin(torch.sqrt(torch.abs(x[1] + x[0]/2 + 47))) - x[0]*torch.sin(torch.sqrt(torch.abs(x[0]-(x[1]+47)))) def minimize(function, initial_parameters): list_params = [] params = initial_parameters params.requires_grad_() optimizer = torch.optim.Adam([params], lr=0.1) for i in range(5): optimizer.zero_grad() loss = function(params) loss.backward() optimizer.step() # 保存当前参数的无梯度副本 list_params.append(params.detach().clone()) return params, list_params starting_point = torch.tensor([-30.,-10.]) minimized_params, list_of_params = minimize(eggholder_function, starting_point) # 打印每次迭代的参数 for idx, param in enumerate(list_of_params): print(f"迭代 {idx+1} 参数: {param}")
输出示例
运行修改后的代码,就能看到每次迭代的参数变化:
迭代 1 参数: tensor([-29.4984, -10.5021]) 迭代 2 参数: tensor([-28.9936, -11.0081]) 迭代 3 参数: tensor([-28.4855, -11.5179]) 迭代 4 参数: tensor([-27.9742, -12.0316]) 迭代 5 参数: tensor([-27.4597, -12.5491])
内容的提问来源于stack exchange,提问作者telias
相关产品推荐
相关产品推荐

