事先声明,机器学习入门,手写代码加深理解,加了一些自己的理解。文中的代码实现借鉴自另一大神博主,如有需要,请戳:https://blog.csdn.net/pennyliang/article/details/6998517(自己动手真的能学到很多)
欢迎一起交流学习,不足之处,还请指正。
/*
Matrix_A
1 42 5
5 1
4 2
theta_C
?
?
Matrix_A*theta_C
19
26
19
20
*/
具体情景为对衣服的估价,矩阵A表示衣服的特征,如第一列可以表示颜色评分,第二列可以表示质地评分。矩阵C表示假设函数中的参数。矩阵A*矩阵C表示的是衣服的真实价格。
批梯度下降
#include "stdio.h"
#include<iostream>
using namespace std;
int main()
{
float matrix[4][2] = { { 1,4 },{ 2,5 },{ 5,1 },{ 4,2 } };//训练集合特征
float result[4] = { 19,26,19,20 };
float theta[2] = { 2,5 }; // 对于参数,给定一个初始值,后面根据训练集合来不断优化
float learning_rate = 0.01;
float loss = 1000.0; //用来判断是否收敛的一个变量,从后面可以看出,这里采用的是最小二乘法
for (int i = 0; i<100 && loss>0.0001; ++i)
{
float error_sum = 0.0;
float cool[2] = { 0.0, 0.0 };
for (int j = 0; j<4; ++j)//对于每次迭代需要遍历一遍整个训练集合
{
float h = 0.0;
for (int k = 0; k<2; ++k)
{
h += matrix[j][k] * theta[k];
}
error_sum = h-result[j] ;//注意这里用的是假设函数减去样本 for (int k = 0; k < 2; ++k) {
cool[k] += error_sum * matrix[j][k];
}
}
for (int k = 0; k<2; ++k)//每次迭代需要更新一次参数
{
theta[k] -= learning_rate * cool[k];
}
printf("*************************************\n");
printf("theta now: %f,%f\n", theta[0], theta[1]);
loss = 0.0;
for (int j = 0; j<4; ++j)//利用最小二乘法求出loss
{
float sum = 0.0;
for (int k = 0; k<2; ++k)
{
sum += matrix[j][k] * theta[k];
}
loss += (sum - result[j])*(sum - result[j]);
}
printf("loss now: %f\n", loss);
}
system("PAUSE");
return 0;
}
这里有一点需要注意,原博文中把更新参数值放在了每次迭代时遍历整个训练集合的for循环中,评论区说是有问题,个人理解并没有问题,因为在每次迭代中更新theta时,每个训练样本对theta更新都用贡献,这里只是在每次遍历时去改变一下theta而不是最后求和来一次性更新theta,只是这样做使得theta概念有些不清晰,不易理解,所以我新加了一个cool数组。
随机梯度下降
int main()
{
float matrix[4][2]={{1,4},{2,5},{5,1},{4,2}};
float result[4]={19,26,19,20};
float theta[2]={2,5};
float loss = 10.0;
for(int i =0 ;i<100&&loss>0.001;++i)
{
float error_sum=0.0;
int j=i%4;//每次迭代只用一个训练样本,j=0,1,2,3,其他部分与批梯度下降相同
{
float h = 0.0;
for(int k=0;k<2;++k)
{
h += matrix[j][k]*theta[k];
}
error_sum = result[j]-h;
for(int k=0;k<2;++k)
{
theta[k] += 0.01*(error_sum)*matrix[j][k];
}
}
printf("%f,%f\n",theta[0],theta[1]);
float loss = 0.0;
for(int j = 0;j<4;++j)
{
float sum=0.0;
for(int k = 0;k<2;++k)
{
sum += matrix[j][k]*theta[k];
}
loss += (sum-result[j])*(sum-result[j]);
}
printf("%f\n",loss);
}
return 0;
}