采用Rosenbrock函数测试优化算法,定义为:
$f(x,y)=(a-x)^2+b(y-x^2)^2$
library(torch)
a <- 1
b <- 5
# defining rosenbrock
rosenbrock <- function(x) {
x1 <- x[1]
x2 <- x[2]
(a - x1)^2 + b * (x2 - x1^2)^2
}
num_iterations <- 1000 # 迭代1000次 1000 iterations
lr <- 0.01 # Set the learning rate to 0.01
x <- torch_tensor(c(-1, 1), requires_grad = TRUE) # 初始化一个张量 x,初始值为 (-1, 1),并设置 requires_grad = TRUE 以便计算梯度。
for (i in 1:num_iterations) {
if (i %% 100 == 0) cat("Iteration: ", i, "\n") # 每100次迭代输出当前的迭代次数。
value <- rosenbrock(x) #计算Rosenbrock函数在当前 x 值下的函数值。
if (i %% 100 == 0) { # 每100次迭代输出当前的函数值。
cat("Value is: ", as.numeric(value), "\n")
}
value$backward() # 计算函数值对 x 的梯度。
if (i %% 100 == 0) { # 每100次迭代输出当前的梯度值。
cat("Gradient is: ", as.matrix(x$grad), "\n")
}
with_no_grad({ # 在不计算梯度的上下文中更新参数 x。
x$sub_(lr * x$grad) # 用梯度下降法更新参数 x,即用学习率乘以梯度的值从 x 中减去。
x$grad$zero_() # 将 x 的梯度清零,以便在下一次迭代中重新计算梯度。
})
}
展开/折叠结果
Iteration: 100
Value is: 0.3502924
Gradient is: -0.667685 -0.5771312
Iteration: 200
Value is: 0.07398106
Gradient is: -0.1603189 -0.2532476
Iteration: 300
Value is: 0.02483024
Gradient is: -0.07679074 -0.1373911
Iteration: 400
Value is: 0.009619333
Gradient is: -0.04347242 -0.08254051
Iteration: 500
Value is: 0.003990697
Gradient is: -0.02652063 -0.05206227
Iteration: 600
Value is: 0.001719962
Gradient is: -0.01683905 -0.03373682
Iteration: 700
Value is: 0.0007584976
Gradient is: -0.01095017 -0.02221584
Iteration: 800
Value is: 0.0003393509
Gradient is: -0.007221781 -0.01477957
Iteration: 900
Value is: 0.0001532408
Gradient is: -0.004811743 -0.009894371
Iteration: 1000
Value is: 6.962555e-05
Gradient is: -0.003222887 -0.006653666
经过一千次迭代后,我们达到了一个低于 0.0001 的函数值。此时x的值为:
x
展开/折叠结果
torch_tensor
0.9918
0.9830
[ CPUFloatType{2} ][ requires_grad = TRUE ]
当 a=1, b=5时,
$f(x,y)=(1-x)^2+5(y-x^2)^2$
当$x=1$时,$(1-x)^2=(1-1)^2=0$
当$y=x^2=1^2=1$时,$5(y-x^2)^2=5(1-1)^2=0$
因此,函数在1,1时达到最小值0。与x1=0.9918和x2=0.9830极为接近。本例中x和y用x1和x2表示。
发表评论