目前csdn上对LM算法的实现基本都是基于Matalab,对pytorch学习者很不友好。
以文献[1]中的数据进行一个复现和学习。需要完整代码(带部分注释)在我主页资源,避免侵权,数据大家自行找到文献进行查找。使用pytorch1.11版本,使用pip安装functorch(目前不支持windows,本文基于linux上实现) 。创作不易,请大家点赞支持。
核心代码如下:
def lm(residual: Callable, theta_0: Tensor, *args: Any, jac_mode: str = "forward", lam_0: float = 10.,
num_iter: int = 100, lam_min: float = 1e-7, lam_max: float = 1e7, L: float = 2., verbose=False,
ftol=1e-6, lam_momentum: float = 0.):
jac = jacfwd(residual) if jac_mode == "forward" else jacrev(residual)
theta = theta_0.clone()
lam = lam_0
r = residual(theta, *args)
loss = (r ** 2).sum()
loss_list = []
for i in range(num_iter):
loss_list.append(loss.item())
if verbose and (i % 1 == 0):
print(f"At iter {i}: {lam}, loss = {loss.item()}")
J = jac(theta, *args)
n, m = J.shape
JTJ = J.mT @ J
damp = lam * (torch.eye(m, device=JTJ.device) + torch.diag(torch.diag(JTJ)))
step = torch.linalg.solve(JTJ + damp, -J.mT @ r)
theta = theta + step
new_r = residual(theta, *args)
new_loss = (new_r ** 2).sum()
文献中的实现效果:
实现效果(基本一致,但坐标轴画反了,可自行调整):
注:坐标画反了,迭代约450次后停止
参考文献:
[1]庄育锋,胡晓瑾,翟宇.基于BP神经网络的微量药品动态称重系统非线性补偿[J].仪器仪表学报,2014,35(08):1914-1920.DOI:10.19650/j.cnki.cjsi.2014.08.032.



