问题描述
一阶线性函数可表示为如下形式(其中x为横坐标,y为纵坐标):
给定数据如下图所示,共有10个样本点。
其中左边一列(1, 2, 3, …, 10)为X坐标,右边一列(3.64, 4.35, 4.74, …, 7.50)为Y坐标。

将数据表示在坐标轴上,如下图所示:

要求根据给出的数据,使用梯度下降法求出k和b的值。
Python实现
import numpy as np
def grad_descent(points, k_start, b_start, learning_rate, num_iter):
k = k_start
b = b_start
for i in range(num_iter):
# 根据k和b的初始值,计算新一轮迭代后k和b的值
# 该部分每运行一次,意味着k和b更新一次
# k和b梯度初始值设为0
grad_k = 0
grad_b = 0
# 依次代入每个样本点
for i in range(len(points)):
# 读取样本点中的X和Y坐标
x = points[i][0]
y = points[i][1]
# 将每个样本点代入损失函数的偏导数,累加计算梯度值
# 损失函数:E = 0.5 * ((k * x) + b - y) ** 2
# 所以损失函数对于k和b的偏导数分别为:dE/dk、dE/db
grad_k += x * ((k * x) + b - y) # grad_k = dE/dk
grad_b += (k * x) + b - y # grad_b = dE/db
# 更新k和b的值
k = k - (learning_rate * grad_k)
b = b - (learning_rate * grad_b)
return [k, b]
if __name__ == "__main__":
# 训练集数据点坐标
points = [[1,3.64],[2,4.35],[3,4.74],[4,4.4],[5,4.3],[6,5.5],[7,7.42],[8,6.69],[9,8.52],[10,7.5]]
# 设置参数
learning_rate = 0.001 # 学习率
num_iter = 100 # 迭代次数
# 设定k和b的初始值
k_start = 1
b_start = 1
# 计算k和b的值
[k, b] = grad_descent(points, k_start, b_start, learning_rate, num_iter)
print("k = ", k)
print("b = ", b)
输出结果如下:
k = 0.7343955949672608
b = 1.3369372262480115
将k和b的值代入,然后画图(程序略),结果如下:

图中蓝色的散点即为训练集样本点,红色的直线即为由k和b值得到的图像。
matlab实现
构造函数grad_descent如下:
function [k, b] = grad_descent(points, k_start, b_start, learning_rate, num_iter)
% function [k, b] = grad_descent(points, k_start, b_start, learning_rate, num_iter)
% 梯度下降法求解线性回归问题
% 输入:point——训练集样本点坐标集合,每行表示一个样本点,第1列表示X坐标,第2列表示Y坐标
% 输入:k_start、b_start——k和b的初始值
% 输入:learning_rate——学习率
% 输入:num_iter——迭代次数
% 输出:k、b——计算后得到的k和b值
k = k_start;
b = b_start;
% 进行num_iter次迭代
for i = 1 : num_iter
grad_k = 0;
grad_b = 0;
% 对于每个样本点
for j = 1 : size(points, 1)
% X、Y坐标
x = points(j, 1);
y = points(j, 2);
% 偏导数(梯度)
grad_k = grad_k + x * ((k * x) + b - y);
grad_b = grad_b + (k * x) + b - y;
% 更新k和b的值
k = k - (learning_rate * grad_k);
b = b - (learning_rate * grad_b);
end
end
代入数据计算:
clear all;
close all;
% 样本点
points = [1,3.64; 2,4.35; 3,4.74; 4,4.4; 5,4.3;
6,5.5; 7,7.42; 8,6.69; 9,8.52; 10,7.5];
% 参数设置
learning_rate = 0.001; % 学习率
num_iter = 100; % 迭代次数
% k、b的初始值
k_start = 1;
b_start = 1;
% 计算k、b的值
[k, b] = grad_descent(points, k_start, b_start, learning_rate, num_iter);
fprintf("k = %d\n", k);
fprintf("b = %d\n", b);
输出结果如下:
k = 5.571244e-01
b = 2.585857e+00
根据求出的k和b的值,画图如下:

图中蓝色的散点即为训练集样本点,红色的直线即为由k和b值得到的图像。
版权声明:本文为sinat_41482627原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。