用梯度下降做点小实验

赶在国庆回家前做点小实验==

利用梯度下降法去拟合任意你想拟合的东西,哈哈

自己想出来的曲线:

 目标函数:

其中:

然后计算迭代式:

其中:

k表示第k次迭代,

 

 至此,有了梯度方向就可以计算啦,附上c++代码:

#include<iostream>
#include<vector>
#include<ctime>
using namespace std;

int main() {
	//产生数据
	srand(time(NULL));
	vector<vector<double>> x(5,vector<double>(3,0.0));
	for (int i = 0; i < 5; i++) {
		for (int j = 0; j < 3; j++) {
			x[i][j] = rand() % 10+1;
			//cout << x[i][j] << " ";
		}
		//cout << ",";
	}
	//double *y = new double[5];
	double y[5];
	for (int i = 0; i < 5; i++) {
		 y[i] = 3 * x[i][0] + 5 * x[i][1] - 7 * x[i][2] + double((rand() % 7)) / 10;
		// cout << y[i] << endl;
	}
	double a=0.0,b=0.0,c=0.0,
		aa=0.0,bb=0.0,cc=0.0;
	double diff;
	double error=0,error1=0;
	int itertornum = 0;//记录迭代次数
	while (1) {
		itertornum++;
		for (int i = 0; i < 5; i++) {
			cout << "第"<<itertornum<<"次迭代:"<<aa << "," << bb << "," << cc << "," << endl;
			diff = y[i] - (a*x[i][0] + b*x[i][1] + c*x[i][2]);
			aa = aa + 0.001*diff*x[i][0];
			bb = bb + 0.001*diff*x[i][1];
			cc = cc + 0.001*diff*x[i][2];
		}
		a = aa; b = bb; c = cc;//更新状态量
		error = 0;
		for (int i = 0; i < 5; i++) {
			error += 0.5*(pow(y[i] - (a*x[i][0] + b*x[i][1] + c*x[i][2]), 2));
		}
		if (abs(error - error1) < 1e-5) {
			break;
		}
		else {
			error1 = error;
		}
	}
	cout << "最终结果是:" << a <<","<< b<<"," << c<<endl;
	system("pause");
	return 0;
}

  

 

posted @ 2017-09-29 19:53  实事求是>_<  阅读(448)  评论(0编辑  收藏  举报