图形学算法-牛顿迭代的原理及运用

一、牛顿迭代法的原理(公式编辑太麻烦,直接引用了截图):

二、牛顿迭代法具体案例分析

1.xoy平面内有一群带噪音的散乱点,从分布规则上看大致接近于f(x)的函数分布,此时就可以使用牛顿迭代法将目标函数拟合出来。
2.比如以下方式,拟合y=ax+b的过程
3.已知条件:n个点的坐标(xi,yi)
4.构建误差项:loss =1/n
((a*xi+b-yi)^2+…),i从0到n-1;
5.牛顿迭代公式:xi+1=xi - t * f(xi)’,其中t为步进
6.因此对于未知量a和b的迭代公式分别为:
*

ai+1=ai-tf(ai)'
bi+1=bi-tf(bi)'

其中

d(loss)/d(a)=1/n * (2 * (axi+b-yi)*x+.....)
d(loss)/d(b)=1/n * (2 * (axi+b-yi)+.....)

三、牛顿迭代法的代码实现:

1、生成随机点,在直线附近增加一个噪音

// y=ax+b, a=1.5,b=0.6;
vector<float> getRand(vector<float>&x)
{
	vector<float>ylist;
	for (auto&i : x)
	{
		float y = 1.5*i + 0.6 + rand() % 1000/10000.0;
		ylist.push_back(y);
	}
	return ylist;
}

2、计算误差项

float getLoss(vector<float>&x, vector<float>&y, float a, float b)
{
	int n = x.size();
	float loss = 0;
	for (int i = 0; i < n; i++)
	{
		float t = a*x[i] + b - y[i];
		loss += t*t;
	}
	loss /= n;
	return loss;
}

3、迭代1000次

int main()
{
	vector<float>x_val;
	for (float x = 0.5; x < 10.0f; x += 0.05f)
	{
		x_val.push_back(x);
	}
	cout << "真值a:1.5 ,b:0.6" << endl;
	// y=1.5x+0.6
	vector<float>y_val = getRand(x_val);
	int n = x_val.size();
	float a = 0, b = 0;
	float step = 0.005;
	cout << "a:" << a << "," << "b:" << b << ":loss=" << getLoss(x_val, y_val, a, b) << endl;

	for (int i = 0; i < 1000; i++)
	{
		float del_a = 0;
		float del_b = 0;
		for (int j = 0; j < n; j++)
		{
			del_a += 2 * (a*x_val[j] + b - y_val[j])*x_val[j];
			del_b += 2 * (a*x_val[j] + b - y_val[j]);
		}
		del_a /= n;
		del_b /= n;
		a = a - step*del_a;
		b = b - step*del_b;
	}
	cout <<"a:" <<a << "," <<"b:"<< b << ":loss=" << getLoss(x_val, y_val, a, b) << endl;
	getchar();
    return 0;
}

4、运行结果:
在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值