2

我是 Scheme 的新手,正在执行一项实现随机梯度下降的任务。到目前为止,我相信我的程序结构是正确的,但是我的程序采用函数 f(x) 的导数给我带来了一些麻烦。在代码底部的“try”循环中,我递归调用(try (func-eval guess))where(func-eval guess)计算函数局部最小值的下一个猜测,公式为*x - alpha*f'(x)* where alpha = 0.1。

我在计算导数时似乎遇到了错误...我正在使用 Dr.Racket IDE,它突出显示了以下行有问题: (f (+ x dx))...这是我本地导数过程中的第二行:

(define (local-minimal first-guess)

;A way to check a guess
(define(good-enough? val1 val2)
(<(abs(- val1 val2)) 0.00001))

; x_new = x_old - alpha*f'(x)    /// f(x)=(x+1)^2+2  //// alpha = 0.1
(define (func-eval x)
  (- x (* 0.1((derivative (+ 2(expt (+ x 1) 2)) 0.00001)x))))

  (define (derivative f dx)
  (lambda (x)
    (/ (- (f (+ x dx)) (f x))
       dx)))

; trys the guess
(define (try guess)
  (if (good-enough? guess -1)
      guess
      (try (func-eval guess))))
(try first-guess)) 

我收到一条错误消息:

application: not a procedure;
 expected a procedure that can be applied to arguments
  given: 3
  arguments...:
   -1.99999

这是语法错误吗?我认为我可以通过使用(f (+ x dx))... 来表示 f(x+dx)。这是否意味着我需要在括号中的 f 之前放置一个运算符?

4

2 回答 2

3

突出显示和错误消息一起告诉您一些有用的信息:该事物derivative正在接收,因为它的第一个参数f不是一个函数,它需要被调用 in (f (+ x dx))。论据从何而来?我们可以运行 DrRacket 的调试器,但是在这里我们可以只看代码——唯一derivative调用的地方是 的第一行func-eval,所以我们必须在这里传递一个数字而不是一个函数。果然,(+ 2 (expt (+ x 1) 2))(with xbound) 只是一个数字,尝试应用它会出错。

于 2012-11-08T07:30:18.563 回答
2

调用时derivative,第一个参数必须是函数。在下面的过程调用中,第一个参数中的表达式被计算为一个数字,而不是一个函数:

(derivative (+ 2 (expt (+ x 1) 2)) 0.00001)

要修复它,请将表达式打包在 alambda中,使其成为实际函数:

(derivative (lambda (x) (+ 2 (expt (+ x 1) 2))) 0.00001)
于 2012-11-08T14:09:52.010 回答