----------------------------------最小二乘法与梯度算法求解--------------------------------------*
*-description:用户输入W、B真实值以及X值后生成带正态分布噪声的Y值后用梯度算法拟合
*- author:Luo
*-e-mail:[email protected]
*- Version :Dev-C++ 5.11
*--------------------------------------------------------------------------------------------------------*
关于其中一些类的成员定义可参考我上一篇文章!都是一些矩阵的加减乘除、数乘、点乘的运算 符重载等,主要利用矩阵的相关运算将数学形式转为代码形式即可。
程序的探索过程如下:
①定义好矩阵的类及其相关性质的成员函数(有问题请在上一篇文章dd我)
②为了模拟真实场景需要自己产生一组关于X、Y的数据,同时为了更贴近实际选用正态分布(高斯)随机噪声在实际Y值上作偏差以实现数据的生成
③梯度下降法的实现,具体步骤如下述:
1)构造损失函数loss,我这里选用|Y_test-Y|^2/2作为损失函数,其中1/2为了后续求导约分所构
2)给定梯度算法中的步长(也即学习率h),并设定无穷小界限(作为退出循环条件所定),给定W_test与B_test的初始值(我这里将其均初始化为1矩阵),同时设置好迭代次数
3计算损失函数loss的梯度,并对W_test、B_test进行更新迭代,即分别写作N=(N-1)+h*梯度g
4)循环上述步骤,当出现|loss|小于所界定的无穷小界限或者循环次数大于迭代次数,退出循环
5)将过程中W和B的真实值以及优化得到的测试值打印进行对比
源码如下:
#include
#include
#include
using namespace std;
typedef long long ll;
class Matrix //封装一个矩阵类便于后续使用
{
int row;
int col;
double** base; //二维数组存放矩阵
public:
Matrix(int r,int c) //构造函数初始化
{
row=r;
col=c;
create();
}
Matrix(const Matrix& e) //拷贝构造函数
{
row=e.getrow();
col=e.getcol();
create();
for(int i=0;i>(istream& cin,Matrix& e) //重载>>方便输入
{
int r=e.getrow();
int c=e.getcol();
for(int i=0;i>e[i][j];
}
}
return cin;
}
Matrix operator*(double n,Matrix& e) //重载*实现数乘
{
Matrix ret(e.getrow(),e.getcol());
for(int i=0;i>R1;
cin>>C1;
cout<<"对Y=WX+B输入矩阵B的行数与列数"<>R2;
cin>>C2;
//[R1,C1]*[Rx,Cx]=[R2,C2] 即 Rx=C1且 Cx=C2 R1=R2
if(R1!=R2)
{
cout<<"W的行与B的行数不相等"<>W;
int choice;
cout<<"B为一个数请输入 1 B为矩阵请输入 2"<>choice;
switch (choice) //生成矩阵B
{
case 1:
{
cout<<"请输入数字B"<>b;
B=transfer(R1,C2,b);
}
break;
case 2:
{
cout<<"请输入矩阵B"<>B;
}
break;
}
system("pause");
cout<<"请给X赋值进而得到Y值"<>X;
Matrix Y1(R1,C2);
Y1=W*X; Y1=Y1+B; //得到不带偏差的矩阵
Y=W*X; Y=Y+B; Y=Y+random; //得到带偏差的Y矩阵
cout<<"--------------随机模拟生成的数据[X Y]-------------"<=max_times)) //当 loss1差别很小时或者超过了最大迭代次数认为完成
{
ret=0;
}
epoch=epoch+1;
}
cout<<"----------------W与B的训练值----------------------"<= 1 || S == 0);
X = V1 * sqrt (-2 * log (S) / S);
}
else
X = V2 * sqrt (-2 * log (S) / S);
phase = 1 - phase;
return X;
}
Matrix transfer(int r,int c,double b) //将数b转为矩阵B
{
Matrix ret(r,c);
for(int i=0;i
以上是源码啦!喜欢的话请点赞收藏!当然,觉得有可以改进的点请务必评论告知,十分乐意与各位uu交流学习!