optim函数返回使用渐变gr时提供的初始值

时间:2017-10-22 22:53:54

标签: r optimization gradient

当我使用gr参数时,我得到初始值。没有它我会得到明智的结果。为什么提供gr参数会导致optim()函数返回初始值。这是问题的复制。 func_0要优化的函数和func_1是它的渐变

func_0 <- function(mu, mu0, Sigma_inv0, t_z){
    log_theta = mu - log(sum(exp(mu))) # mu is a Kx1 column vector
    f = t(log_theta)%*%t_z # t_z is a Kx1 column vector
    f = -(f - 0.5*t(mu - mu0)%*%Sigma_inv0%*%(mu - mu0))
    return(f)
    }

func_1 <- function(mu, mu0, Sigma_inv0, t_z){ 
    log_sum = log(sum(exp(mu)))
    theta = exp(mu - log_sum)
    df = t_z - sweep(as.matrix(theta), 1, sum(t_z), '*') - Sigma_inv0%*%(mu - mu0)
    return(df)
    }

初始值为:

Sigma_inv0 = diag(1, 5)
num_topics_  = 6
mu0 = c(0,0,0,0,0)
mu = c(0.5,0,0.75,0.25,1)
t_z = c(5,4,7,2,10)

我将optim()应用于这些函数:

optim(par = mu, fn = func_0,
  mu0 = mu0, t_z = t_z, Sigma_inv0 = Sigma_inv0,
  method = "CG")$par

这是明智的输出:

$par
[1] -0.02084741 -0.19948432  0.27185348 -0.65718095  0.60566111

$value
[1] 42.2506

$counts
function gradient 
     78       33 

$convergence
[1] 0

$message
NULL

现在应用了渐变的相同功能:

optim(par = mu, fn = func_0, gr = func_1,
  mu0 = mu0, t_z = t_z, Sigma_inv0 = Sigma_inv0,
  method = "CG")$par

$par
[1] 0.50 0.00 0.75 0.25 1.00

$value
[1] 43.47864

$counts
function gradient 
    24        1 

$convergence
[1] 0

$message
NULL

使用渐变参数有什么问题?我只是得到了初始值。我尝试了荒谬的初始值,我仍然将我的初始值返回给我。 提前谢谢!

有人认为渐变可能是错误的。我不认为是这样的。这是一个小亩的试验性检查。

> optim(par = mu[1:2], fn = func_0,
+       mu0 = mu0[1:2], t_z = t_z[1:2], Sigma_inv0 = Sigma_inv0[1:2,1:2],
+       method = "CG")

$par
[1]  0.09111349 -0.09111587

$value
[1] 6.192819

$counts
function gradient 
     74       31 

$convergence
[1] 0

$message
NULL

现在,我可以计算梯度,对于最佳mu,该梯度为零。

> func_1(c(0.09111349, -0.09111587), mu0[1:2], Sigma_inv0[1:2,1:2], 
t_z[1:2])
             [,1]
[1,] 1.330154e-06
[2,] 1.049846e-06

这几乎为零。 但是,如果μ更大,则梯度不再接近零。我承认我不知道optim()的内部工作。

1 个答案:

答案 0 :(得分:0)

更改渐变符号,您会得到想要的答案...

func_1 <- function(mu, mu0, Sigma_inv0, t_z){

  log_sum = log(sum(exp(mu)))
  theta = exp(mu - log_sum)
  df = (t_z - sweep(as.matrix(theta), 1, sum(t_z), '*') - Sigma_inv0%*%(mu - mu0))*alpha

  return(df)
} 

alpha=-1
optim(par = mu, fn = func_0, gr = func_1,
      mu0 = mu0, t_z = t_z, Sigma_inv0 = Sigma_inv0,control=list(trace=1),
      method = "L-BFGS-B")$par #"CG"