C++线性回归(SGD、BGD、MBGD)

代码

#include<iostream>
#include<random>

using namespace std;

double w = 0;//y=w*x+b,初始w
double b = 0;//y=w*x+b,初始b
double true_w = 10.0;//真实w
double true_b = 10.0;//真实b
double alpha = 0.3;//步长
int samples = 1000;//样本数

double* x = new double[samples];//样本特征
double* y = new double[samples];//样本标签


/*
* 函数:生成数据
* 输入:无
* 输出:无
*/
void generator()
{
	default_random_engine gen;//随机数
	normal_distribution<double>normal(0.01, 0.01);//正态分布
	for (int i = 0; i < samples; i++) {
		x[i] = rand() * 1.0 / RAND_MAX;//x取值为[0,1]
		y[i] = true_w * x[i] + true_b + normal(gen);//根据x计算y
	}
}


/*
* 函数:随机梯度下降
* 输入:特征值x,标签y
* 输出:w、b的预测值
*/
void SGD(double* x, double* y)
{
	for (int i = 0; i < samples; i++) {
		double TempW = w - 2 * alpha * x[i] * (w * x[i] + b - y[i]);//求导
		double TempB = b - 2 * alpha * (w * x[i] + b - y[i]);//求导
		w = TempW;//更新
		b = TempB;//更新
	}
	cout << "w=" << w << "  b=" << b << endl;
}


/*
* 函数:批量梯度下降
* 输入:特征值x,标签y,停止求解的阈值dert
* 输出:w、b的预测值
*/
void BGD(double* x, double* y, double dert)
{
	double TempW = 0;
	double tempB = 0;

	while (1) {
		double RcdW = w;
		double RcdB = b;

		for (int i = 0; i < samples; i++) {
			TempW += 2 * x[i] * (w * x[i] + b - y[i]);//导数累加
			tempB += 2 * (w * x[i] + b - y[i]);//导数累加
		}
		w -= alpha * TempW / (2.0 * samples);//更新
		b -= alpha * tempB / (2.0 * samples);//更新
		if (abs(RcdW - w) < dert && abs(RcdB - b) < dert)break;
	}
	cout << "w=" << w << "  b=" << b << endl;
}


/*
* 函数:小批量梯度下降
* 输入:特征值x,标签y,每批数量
* 输出:w、b的预测值
*/
void MBGD(double* x, double* y, int batch)
{
	for (int i = 0; i < samples / batch; i++) {
		double TempW = 0;
		double TempB = 0;
		for (int j = 0; j < batch; j++) {
			int k = i * batch + j;
			TempW += 2 * x[k] * (w * x[k] + b - y[k]);//导数累加
			TempB += 2 * (w * x[k] + b - y[k]);//导数累加
		}
		w -= alpha * TempW / (2.0 * samples);//更新
		b -= alpha * TempB / (2.0 * samples);//更新
	}
	cout << "w=" << w << "  b=" << b << endl;
}

int main(){

	generator();
	SGD(x, y);

	generator();
	BGD(x, y, 0.001);

	generator();
	MBGD(x, y, 10);

	system("pause");
}

结果

最后的求解结果还行,记录一下。
拟合结果

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值