最適化アルゴリズム-勾配降下

5665 ワード

勾配降下アルゴリズムは、Edwinの「最適化導論」8.2章を参照し、アルゴリズムはgo言語で実現される.
ここでアルゴリズムは依然として疑問があり,主に勾配降下を取得する際にどのようにステップ長を決定するか,割線法を用いて最適ステップ長を取得しても,割線法の初期値はどのように決定するか.
次のプログラムではニュートン法で極値を取得していますが、初期値範囲に非常に依存しています!!
/*****************************************
 * FileName  : grad.go
 * Author    : fredric
 * Date      : 2017.09.01
 * Note      :     
 * History   :
*****************************************/
package grad

import(
    "fmt"
    "math"
)

//            ,             ,        
func _get_argmin_newton(x1, x2, x3, grad_x1, grad_x2, grad_x3 float64) float64 {

    fmt.Printf("_get_argmin input value %f,%f,%f,%f,%f,%f
", x1, x2, x3, grad_x1, grad_x2, grad_x3) //f(x - a*delta) = (x1 - a * grad_x1 - 4)^4 + (x2 - a * grad_x2 - 3)^2 + 4 * (x3 - a*grad_x3 + 5)^4 //f'(x - a*delta) = 4 * grad_x1 * (x1 - a * grad_x1 - 4)^3 // + 2 * grad_x2 * (x2 - a * grad_x2 - 3) // + 16* grad_x3 * (x3 - a*grad_x3 + 5)^3 //f''(x - a*delta)= 12 * grad_x1^2 * (x1 - a * grad_x1 - 4)^2 // + 2 * grad_x2^2 * a // + 48 * grad_x3^2 * (x3 - a*grad_x3 + 5)^2 // f(a) // , , var a0 float64 = 0.0002 var a1 float64 = 0.0005 delta := 0.0005 for math.Abs(a1 - a0) > delta { a0 = a1 //fmt.Printf("a0: %f
" , a0) //fmt.Printf("grad_x2: %f
" , grad_x2) //fmt.Printf("grad_x2 * a0: %f
" , grad_x2 * a0) //fmt.Printf("grad_x2 * 0.2: %f
" , grad_x2 * 0.2) f_1_v := 4 * grad_x1 * (x1 - a0 * grad_x1 - 4)* (x1 - a0 * grad_x1 - 4)* (x1 - a0 * grad_x1 - 4) + 2 * grad_x2 * (x2 - a0 * grad_x2 - 3) + 16* grad_x3 * (x3 - a0 * grad_x3 + 5)* (x3 - a0 * grad_x3 + 5) * (x3 - a0 * grad_x3 + 5) f_2_v := 12 * grad_x1 * grad_x1 * (x1 - a1 * grad_x1 - 4)* (x1 - a1 * grad_x1 - 4) + 2 * grad_x2* grad_x2 * a1 + 48 * grad_x3* grad_x3 * (x3 - a1 * grad_x3 + 5)* (x3 - a1 * grad_x3 + 5) a1 = a0 - f_1_v / f_2_v //fmt.Printf("----------abs = %f
", math.Abs(a1 - a0)) fmt.Printf("step value = %f f_1_v = %f, f_2_v = %f
", (a0 + a1)/2, f_1_v, f_2_v) } return (a0 + a1)/2 } // func _get_argmin_const(x1, x2, x3, grad_x1, grad_x2, grad_x3 float64) float64{ /* * , , * L>0 |f(x1)-f(x2)|<=L|x1-x2|, 1/L * x3 , , */ return 0.0004 } func DoGradAlgorithm(){ // f(x1,x2,x3) = (x1 - 4)^4 + (x2 - 3)^2 + 4*(x3 + 5)^4 // , , , ; // // x0 = [4, 2, -1] x1 := 4.0 x2 := 2.0 x3 := -1.0 // for i := 0; i < 4; i++ { grad_x1 := 4 * (x1 - 4)*(x1 - 4)*(x1 - 4) grad_x2 := 2 * (x2 - 3) grad_x3 := 16 * (x3 + 5)* (x3 + 5)* (x3 + 5) a := _get_argmin_newton(x1,x2,x3, grad_x1, grad_x2, grad_x3) fmt.Printf("grad_x1 = %f, grad_x2 = %f, grad_x3 = %f
", grad_x1, grad_x2, grad_x3) x1 = x1 - a * grad_x1 x2 = x2 - a * grad_x2 x3 = x3 - a * grad_x3 fmt.Printf("x1 = %f, x2 = %f, x3 = %f
", x1, x2, x3) } }