代码
#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");
}
结果
最后的求解结果还行,记录一下。