赶在国庆回家前做点小实验==
利用梯度下降法去拟合任意你想拟合的东西,哈哈
自己想出来的曲线:
目标函数:
其中:
,
然后计算迭代式:
其中:
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; }
时间: 2024-11-08 23:04:28