请修正最速上升法的R代码:参数无法更新问题
问题排查与代码修正
原代码核心问题
- 全局变量污染+计算逻辑错误:
sum1-sum4定义在全局环境,函数内未重新初始化,会累积错误值;且原代码中sum3、sum4的计算公式存在笔误,导致梯度方向完全错误,参数无法正确更新。 - 死循环:
while (accept==FALSE)无终止条件,循环内未修改accept状态,程序会陷入无限循环,无法执行后续逻辑。 - 变量作用域问题:函数内修改的参数无法传递到全局环境,最终输出的还是初始值。
- 迭代逻辑错误:原代码的
accept判断逻辑不符合最速上升法的核心——沿梯度方向更新参数,直到梯度足够小。
修正后的代码
x <- c(1,2,3,4,5,6,7,8,9,10) y <- c(1.3,1.9,2.4,2.5,2.4,2.5,2.6,2.7,2.7,2.7) del <- 0.01 # 步长因子 tol <- 1e-5 # 收敛阈值 # 最速上升法实现函数 steepest_ascent <- function(b1_init, b2_init, del, tol) { b1 <- b1_init b2 <- b2_init while(TRUE) { # 基于当前b2实时计算求和项 sum1 <- sum(y * exp(1 - exp(-x / b2))) sum2 <- sum(exp(2 - 2 * exp(-x / b2))) # 修正后的sum3:对应目标函数对b2求导的第一部分求和 sum3 <- sum(y * x * exp(1 - exp(-x / b2)) * exp(-x / b2) / (b2^2)) # 修正后的sum4:对应目标函数对b2求导的第二部分求和 sum4 <- sum(x * exp(2 - 2 * exp(-x / b2)) * exp(-x / b2) / (b2^2)) # 计算梯度 grad_b1 <- -0.01 + 100 * sum1 - 100 * b1 * sum2 grad_b2 <- -0.01 + 100 * b1 * sum3 - 100 * b1^2 * sum4 # 收敛判断:梯度的L2模小于阈值则停止迭代 grad_norm <- sqrt(grad_b1^2 + grad_b2^2) if(grad_norm < tol) break # 沿梯度方向更新参数 b1 <- b1 + del * grad_b1 b2 <- b2 + del * grad_b2 } return(c(b1, b2)) } # 运行最速上升法 initial_params <- c(2, 2.5) final_params <- steepest_ascent(initial_params[1], initial_params[2], del, tol) # 输出结果 cat("更新后的参数值:b1 =", round(final_params[1], 4), ",b2 =", round(final_params[2], 4), "\n")
修正说明
- 实时计算求和项:将
sum1-sum4移至循环内部,每次迭代都基于当前b2重新计算,避免全局变量污染和过时值的使用。 - 修复梯度公式:修正了
sum3、sum4的计算逻辑,确保梯度方向符合目标函数的导数推导。 - 标准收敛逻辑:用梯度的L2模长判断收敛,当梯度足够小时停止迭代,符合最速上升法的核心规则。
- 作用域优化:通过函数返回值传递最终参数,避免全局变量修改的问题。
- 移除无效逻辑:删除了原代码中无意义的
accept判断和死循环结构,替换为清晰的迭代收敛循环。
内容的提问来源于stack exchange,提问作者scily09
相关产品推荐
相关产品推荐

