R Error: function returns NA at 3.07653253930756e+181 distance from x

R Error: function returns NA at 3.07653253930756e+181 distance from x

我正在使用 R 编程语言。

基于以下网站 https://www.stat.cmu.edu/~ryantibs/statcomp-F15/lectures/optimization.pdf 的代码(注意:由于某些原因,此网站无法在 Google Chrome 中打开 - 请尝试 Microsoft Edge Explorer),我正在尝试使用“梯度下降优化算法”优化(即找到最小值)函数:f(x) = x^3 - 2x - 5

我首先定义了我要优化的函数:

#define function to be optimized
func2 <- function(x) {
 return( x[1]^3 - 2* x[1] - 5)
}

接下来,我定义了梯度下降优化算法的函数:

#load library
library(numDeriv)


#define gradient descent function
grad.descent = function(f, x0, max.iter=200, step.size=0.05,
stopping.deriv=0.01, ...) {
n = length(x0)
xmat = matrix(0,nrow=n,ncol=max.iter)
xmat[,1] = x0
for (k in 2:max.iter) {
# Calculate the gradient
grad.cur = grad(f,xmat[,k-1],...)
# Should we stop?
if (all(abs(grad.cur) < stopping.deriv)) {
k = k-1; break
}
# Move in the opposite direction of the grad
xmat[,k] = xmat[,k-1] - step.size * grad.cur
}
xmat = xmat[,1:k] # Trim
return(list(x=xmat[,k], xmat=xmat, k=k))
}

最后,我尝试优化了功能:

# I think this serves as an initialization value
 x0 = c(-1.9)

#run gradient descent algorithm
 gd = grad.descent(func2,x0,step.size=1/3)

问题:但是这个returns出现如下错误:

 Error in grad.default(f, xmat[, k - 1], ...) : 
  function returns NA at 3.07653253930756e+181 distance from x. 

有人可以告诉我我做错了什么吗?

谢谢!

如果你想强加边界,你可以这样做:

#load library
library(numDeriv)

#define gradient descent function
grad.descent = function(f, x0, max.iter=200, step.size=0.05,
                        stopping.deriv=0.01, boundaries = NULL, verbose = TRUE, ...) {
  n = length(x0)
  xmat = matrix(0,nrow=n,ncol=max.iter)
  xmat[,1] = x0
  for (k in 2:max.iter) {
    if (verbose) message(paste(xmat[, k-1], collapse = ", "))
    # Calculate the gradient
    grad.cur = grad(f,xmat[,k-1],...)
    # Should we stop?
    if (all(abs(grad.cur) < stopping.deriv)) {
      k = k-1; break
    }
    # Move in the opposite direction of the grad
    xmat[,k] = xmat[,k-1] - step.size * grad.cur
    if (!is.null(boundaries)) {
      xmat[,k] <- ifelse(xmat[,k] < boundaries[1], boundaries[1], xmat[,k])
      xmat[,k] <- ifelse(xmat[,k] > boundaries[2], boundaries[2], xmat[,k])
      if (all(xmat[, k] == xmat[, k-1] | abs(grad.cur) < stopping.deriv))) break #stop if boundaries
    }
  }
  xmat = xmat[,1:k, drop = FALSE] # Trim
  return(list(x=xmat[,k], xmat=xmat, k=k))
}

# starting values
x0 = c(-1.9, 1.9)

#use functions that are actually vectorized 
#if you want to use multiple starting values
f1 <- \(x) x^3 - 2* x - 5
grad.descent(f1,x0,step.size=1/3, boundaries = c(-5, 5))

f2 <- \(x) x^2
grad.descent(f2,x0,step.size=1/3, boundaries = c(-5, 5))