梯度下降算法求一元凸函数的最优解

梯度下降算法:

        X(n+1) = X(n) - ηf'(X)

该算法可以用在求一元凸函数的极值(当然也可以求多元凸函数),前提是凸函数。这里使用一元二次方程为例。

// 梯度下降算法求一元凸函数的最优解(极值点)
// 梯度下降算法 X(n+1) = X(n) - ηf'(X)
// 设一元凸函数 y = ax^2 + bx + c (a > 0)

// 1.构造一元凸函数
float a = 1;		// a > 0
float b = 2;
float c = 3;

// 2.设置下降起点和下降率(学习率)
float Xn1, Xn0;		// X(n+1) 和 X(n)
Xn0 = 10;			// 下降起点
// 下降率yita,该值越小,下降越慢(训练过程越慢),结果越准确,该值越大,下降越快(训练过程越快),结果越不准确,
// 当值超过一定的值时,结果无法收敛,将发散。
float yita = 0.001;	

float det = 0.001;	// 用于利用极限求导数
float thresh = 0.000001; // 判断收敛的阈值
int times = 0;		// 迭代次数

// 3.开始梯度迭代
while (1)
{
	// 极限法求导数(不使用解析解,因为大部分情况下无法直接求得解析解)
	//					f(x+det) - f(x)
	// lim		=	-----------------------
	//(det->0)				 det
	//		
	float Xgap = Xn0 + det;
	float Fdiv = (((a * Xgap * Xgap) + (b * Xgap) + c) - ((a * Xn0 * Xn0) + (b * Xn0) + c)) / det;	// 在Xn0处的导数
	Xn1 = Xn0 - yita * Fdiv;

	times++;
	// 如果梯度下降趋于稳定(下降幅度基本不变),就认为下降已经收敛,找到最优解。
	if (fabs(Xn1 - Xn0) < thresh){
		
		cout << "yita = " 			<< yita 	<< endl;
		cout << "Best value: " 		<< Xn1 		<< endl;
		cout << "Iteration times: " << times 	<< endl;
		break;
	}
	Xn0 = Xn1;
}

实验结果:

(1)当yita = 0.001时
       yita = : 0.001
       Best value: -0.999952
       Iteration times: 4942
(2)当yita = 0.01时
        yita = : 0.01
        Best value: -1.00043
        Iteration times: 567
(3)当yita = 0.1时
        yita = : 0.1
        Best value: -1.00044
        Iteration times: 53
(4)当yita = 1时

        结果发散。

结论:

可以看出:下降率yita,该值越小,下降越慢(训练过程越慢),结果越准确,该值越大,下降越快(训练过程越快),结果越不准确,当值超过一定的值时,结果无法收敛,将发散。


评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值