我是Scheme的新手,正致力于实现随机梯度下降的任务。到目前为止,我相信我的程序结构是正确的,但是我的程序采用函数f(x)的导数给我带来了一些麻烦。在代码底部的“try”循环中,我递归调用(try (func-eval guess))
,其中(func-eval guess)
使用公式 * x - alpha * f'(x)计算函数局部最小值的下一个猜测)* 其中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之前放置一个运算符?
答案 0 :(得分:3)
突出显示和错误消息一起告诉你一些有用的东西:derivative
正在接收的东西,因为它的第一个参数f
不是一个函数,它需要在{{1}中调用}}。论证来自何处?我们可以运行DrRacket的调试器,但是在这里我们可以看看代码 - (f (+ x dx))
被调用的唯一位置是derivative
的第一行,所以我们必须传递一个数字而不是一个功能。果然,func-eval
(绑定(+ 2 (expt (+ x 1) 2))
)只是一个数字,尝试应用此错误会产生错误。
答案 1 :(得分:2)
调用derivative
时,第一个参数必须是函数。在以下过程调用中,第一个参数中的表达式将计算为数字,而不是函数:
(derivative (+ 2 (expt (+ x 1) 2)) 0.00001)
要解决此问题,请将表达式打包在lambda
内,这使其成为实际功能:
(derivative (lambda (x) (+ 2 (expt (+ x 1) 2))) 0.00001)