最適化アルゴリズム-勾配降下
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)
}
}