R:直接对函数而不是函数中的数据点执行梯度下降
R: Performing Gradient Descent Directly on Functions Instead of Data Points from the Function
我正在使用 R 编程语言。在 https://www.ocf.berkeley.edu/~janastas/stochastic-gradient-descent-in-r.html 上使用这个 link ,我发现了一个函数,它允许您对来自函数的数据点执行梯度下降:
gradientR<-function(y, X, epsilon,eta, iters){
epsilon = 0.0001
X = as.matrix(data.frame(rep(1,length(y)),X))
N= dim(X)[1]
print("Initialize parameters...")
theta.init = as.matrix(rnorm(n=dim(X)[2], mean=0,sd = 1)) # Initialize theta
theta.init = t(theta.init)
e = t(y) - theta.init%*%t(X)
grad.init = -(2/N)%*%(e)%*%X
theta = theta.init - eta*(1/N)*grad.init
l2loss = c()
for(i in 1:iters){
l2loss = c(l2loss,sqrt(sum((t(y) - theta%*%t(X))^2)))
e = t(y) - theta%*%t(X)
grad = -(2/N)%*%e%*%X
theta = theta - eta*(2/N)*grad
if(sqrt(sum(grad^2)) <= epsilon){
break
}
}
print("Algorithm converged")
print(paste("Final gradient norm is",sqrt(sum(grad^2))))
values<-list("coef" = t(theta), "l2loss" = l2loss)
return(values)
}
例如,我尝试使用此函数“优化”y = x^3 - 2x - 5:
x = seq(1,1000, by=1)
y = (x^3) - (2*x) -5
gdec.eta1 = gradientR(y = y, X = x, eta = 100, iters = 1000)
但是,我收到以下错误:
Error in if (sqrt(sum(grad^2)) <= epsilon) { :
missing value where TRUE/FALSE needed
有人可以告诉我我做错了什么吗?为什么会产生这个错误?
有谁知道 R 中的其他一些梯度下降函数是否允许您“直接”优化此函数而不是从该函数生成点?
像这样:
func2 <- function(x) {
x^3 - 2* x - 5
}
gradientR(func2, eta = 100, iters = 1000)
有谁知道这是否可行?
谢谢!
注意: 这适用于以下示例(来自上面 linked 的网站):
> y = rnorm(n = 10000, mean = 0, sd = 1)
> x1 = rnorm(n = 10000, mean = 0, sd = 1)
> x2 = rnorm(n = 10000, mean = 0, sd = 1)
> x3 = rnorm(n = 10000, mean = 0, sd = 1)
> x4 = rnorm(n = 10000, mean = 0, sd = 1)
> x5 = rnorm(n = 10000, mean = 0, sd = 1)
>
> ptm <- proc.time()
> gdec.eta1 = gradientR(y = y, X = data.frame(x1,x2,x3, x4,x5), eta = 100, iters = 1000)
[1] "Initialize parameters..."
[1] "Algorithm converged"
[1] "Final gradient norm is 9.80308529574335e-05"
我只是不知道为什么它不适用于我的示例。
我们假设 gradientR 解决了您遇到的问题,问题是让它与您的输入一起工作。这里有几个问题:
不能将函数传递给 gradientR。 y 和 X 必须是向量或矩阵。
如果给许多优化问题提供非常不同的数字,它们就会出现缩放问题。这个没什么不同。使用 x/1000 而不是 x.
为了弄清楚要解决的潜在问题是什么,找到一个系数向量 b 使得
在 y 和 x 已知的情况下,残差向量 y - cbind(1, x) %% b
被最小化。一些评论者对问题的解释不同,但如果他们的解释是你想要的,那么 gradientR 不适用,无论如何,最大化或最小化 x^3-2x-5 的问题没有有限的解决方案。
如果你想传递 func 而不是 y 那么只需编写一个简单的包装器 grad2,如下所示。
要解决缩放问题,请将其与 x/1000 和 y 一起使用,如图所示。
x = seq(1, 1000, by = 1) / 1000
y = (x^3) - (2*x) -5
gdec.eta1 = gradientR(y = y, X = x, eta = 100, iters = 1000)
str(gdec.eta1)
## List of 2
## $ coef : num [1:2, 1] -5.2 -1.1 <----------------
## ..- attr(*, "dimnames")=List of 2
## .. ..$ : chr [1:2] "rep.1..length.y.." "X"
## .. ..$ : NULL
## $ l2loss: num [1:260] 101.44 50.34 25.5 13.83 8.86 ...
# check that lm gives the same coefficients
coef(lm(y ~ x))
## (Intercept) x
## -5.200701 -1.098500 <----------------
现在定义一个接受 func 而不是 y 的函数。 func 必须满足 func(x) 为 y。我们在最后对其进行了测试,它给出了相同的结果。
# func must be such that func(X) gives Y
grad2 <- function(func, X, ...) gradientR(func(X), X, ...)
# test
x = seq(1, 1000, by = 1) / 1000
func <- function(x) (x^3) - (2*x) -5
grad2 <- function(func, ...) gradientR(func(x), ...)
gdec.etal2 <- grad2(func, x, eta = 100, iters = 1000)
str(gdec.etal2)
## List of 2
## $ coef : num [1:2, 1] -5.2 -1.1 <----------------
## ..- attr(*, "dimnames")=List of 2
## .. ..$ : chr [1:2] "rep.1..length.y.." "X"
## .. ..$ : NULL
## $ l2loss: num [1:238] 141.66 69.93 34.71 17.59 9.57 ...
我正在使用 R 编程语言。在 https://www.ocf.berkeley.edu/~janastas/stochastic-gradient-descent-in-r.html 上使用这个 link ,我发现了一个函数,它允许您对来自函数的数据点执行梯度下降:
gradientR<-function(y, X, epsilon,eta, iters){
epsilon = 0.0001
X = as.matrix(data.frame(rep(1,length(y)),X))
N= dim(X)[1]
print("Initialize parameters...")
theta.init = as.matrix(rnorm(n=dim(X)[2], mean=0,sd = 1)) # Initialize theta
theta.init = t(theta.init)
e = t(y) - theta.init%*%t(X)
grad.init = -(2/N)%*%(e)%*%X
theta = theta.init - eta*(1/N)*grad.init
l2loss = c()
for(i in 1:iters){
l2loss = c(l2loss,sqrt(sum((t(y) - theta%*%t(X))^2)))
e = t(y) - theta%*%t(X)
grad = -(2/N)%*%e%*%X
theta = theta - eta*(2/N)*grad
if(sqrt(sum(grad^2)) <= epsilon){
break
}
}
print("Algorithm converged")
print(paste("Final gradient norm is",sqrt(sum(grad^2))))
values<-list("coef" = t(theta), "l2loss" = l2loss)
return(values)
}
例如,我尝试使用此函数“优化”y = x^3 - 2x - 5:
x = seq(1,1000, by=1)
y = (x^3) - (2*x) -5
gdec.eta1 = gradientR(y = y, X = x, eta = 100, iters = 1000)
但是,我收到以下错误:
Error in if (sqrt(sum(grad^2)) <= epsilon) { :
missing value where TRUE/FALSE needed
有人可以告诉我我做错了什么吗?为什么会产生这个错误?
有谁知道 R 中的其他一些梯度下降函数是否允许您“直接”优化此函数而不是从该函数生成点?
像这样:
func2 <- function(x) {
x^3 - 2* x - 5
}
gradientR(func2, eta = 100, iters = 1000)
有谁知道这是否可行?
谢谢!
注意: 这适用于以下示例(来自上面 linked 的网站):
> y = rnorm(n = 10000, mean = 0, sd = 1)
> x1 = rnorm(n = 10000, mean = 0, sd = 1)
> x2 = rnorm(n = 10000, mean = 0, sd = 1)
> x3 = rnorm(n = 10000, mean = 0, sd = 1)
> x4 = rnorm(n = 10000, mean = 0, sd = 1)
> x5 = rnorm(n = 10000, mean = 0, sd = 1)
>
> ptm <- proc.time()
> gdec.eta1 = gradientR(y = y, X = data.frame(x1,x2,x3, x4,x5), eta = 100, iters = 1000)
[1] "Initialize parameters..."
[1] "Algorithm converged"
[1] "Final gradient norm is 9.80308529574335e-05"
我只是不知道为什么它不适用于我的示例。
我们假设 gradientR 解决了您遇到的问题,问题是让它与您的输入一起工作。这里有几个问题:
不能将函数传递给 gradientR。 y 和 X 必须是向量或矩阵。
如果给许多优化问题提供非常不同的数字,它们就会出现缩放问题。这个没什么不同。使用 x/1000 而不是 x.
为了弄清楚要解决的潜在问题是什么,找到一个系数向量 b 使得 在 y 和 x 已知的情况下,残差向量
y - cbind(1, x) %% b
被最小化。一些评论者对问题的解释不同,但如果他们的解释是你想要的,那么 gradientR 不适用,无论如何,最大化或最小化 x^3-2x-5 的问题没有有限的解决方案。如果你想传递 func 而不是 y 那么只需编写一个简单的包装器 grad2,如下所示。
要解决缩放问题,请将其与 x/1000 和 y 一起使用,如图所示。
x = seq(1, 1000, by = 1) / 1000
y = (x^3) - (2*x) -5
gdec.eta1 = gradientR(y = y, X = x, eta = 100, iters = 1000)
str(gdec.eta1)
## List of 2
## $ coef : num [1:2, 1] -5.2 -1.1 <----------------
## ..- attr(*, "dimnames")=List of 2
## .. ..$ : chr [1:2] "rep.1..length.y.." "X"
## .. ..$ : NULL
## $ l2loss: num [1:260] 101.44 50.34 25.5 13.83 8.86 ...
# check that lm gives the same coefficients
coef(lm(y ~ x))
## (Intercept) x
## -5.200701 -1.098500 <----------------
现在定义一个接受 func 而不是 y 的函数。 func 必须满足 func(x) 为 y。我们在最后对其进行了测试,它给出了相同的结果。
# func must be such that func(X) gives Y
grad2 <- function(func, X, ...) gradientR(func(X), X, ...)
# test
x = seq(1, 1000, by = 1) / 1000
func <- function(x) (x^3) - (2*x) -5
grad2 <- function(func, ...) gradientR(func(x), ...)
gdec.etal2 <- grad2(func, x, eta = 100, iters = 1000)
str(gdec.etal2)
## List of 2
## $ coef : num [1:2, 1] -5.2 -1.1 <----------------
## ..- attr(*, "dimnames")=List of 2
## .. ..$ : chr [1:2] "rep.1..length.y.." "X"
## .. ..$ : NULL
## $ l2loss: num [1:238] 141.66 69.93 34.71 17.59 9.57 ...