梯度下降法简介:
梯度下降算法的思想:选择合适的损失函数,开始时随机选择一个参数作为初值,选择合适的学习率,即步长。在训练过程中不断迭代出下一个能够使得损失函数下降速度最快的参数。持续计算直到寻找到一个局部最小值,而初值的不同可能会造成函数寻找到不同的最小值点。 但是对于线性回归而言,其代价函数总是凸或者凹函数,因此线性回归函数中的局部最优解就是全局最优解。
1.设拟合直线方程为
y ∗ = w x + b , y i 为 真 实 值 即 所 给 的 样 本 数 据 的 纵 坐 标 的 值 y^{*}=w x+b, y_{i}为真实值即所给的样本数据的纵坐标的值 y∗=wx+b,yi为真实值即所给的样本数据的纵坐标的值
2.定义损失函数,解决最小二乘问题
loss = 1 2 N ∑ i = 0 N ( w x + b − y i ) 2 \operatorname{loss}=\frac{1}{2 N} \sum_{i=0}^{N}\left(w x+b-y_{i}\right)^{2} loss=2N1i=0∑N(wx+b−yi)2
3.计算每一步的梯度
4.开始迭代过程,采用梯度下降法,确定w和b的值
5.绘制图像
'''
@ File name :Practice of linear regression
@ Role of documents: For getting started with deep learning
@ Author's name (CSDN): 草原一只鹰
@ Website link : https://blog.csdn.net/qq_46214369/article/details/114489120
'''
import numpy as np
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif']=['SimHei'] #用来正常显示中文标签
plt.rcParams['axes.unicode_minus']=False
# 1.定义损失函数,计算误差 loss = 求和(wx+b-yi)的平方和
def compute_error_for_line_given_points(b,w,points):
totalError = 0
for i in range(0,len(points)):
x = points[i,0]
y = points[i,1]
'''
points[]表示引用列表中的数据,points中的数据是成对排列为两列,
第一列标号为0,第二列标号为1,行号为i,x在第一行,y在第二行
'''
totalError += (y - (w * x + b)) ** 2
return totalError / (2*float(len(points)))
# 2. 计算每一步的梯度,对b和w求导,并更新参数,返回
def step_gradient(b_current,w_current,points,learningrate):
b_gradient = 0
w_gradient = 0
N = float(len(points))
for i in range(len(points)):
x = points[i,0]
y = points[i,1]
b_gradient += -(1/N)*(y - ((w_current*x)+b_current))
w_gradient += -(1/N)*x*(y-((w_current*x)+b_current))
new_b = b_current - (learningrate*b_gradient)
new_w = w_current - (learningrate*w_gradient)
return [new_b,new_w]
# 3.开始执行梯度下降迭代过程,并绘制图像
def gradient_descent_runner(points, starting_b, starting_w, learning_rate, num_iterations):
b = starting_b
w = starting_w
losserror = [] # losserror用来保存每轮迭代的误差,用来绘制函数图像
for i in range(num_iterations):
b, w = step_gradient(b, w, np.array(points), learning_rate)
# np.array()的作用就是按照一定要求将object转换为数组。
# 将此轮迭代的误差添加到losserror列表中
losserror.append(compute_error_for_line_given_points(b, w, points))
# 绘制误差函数随着迭代次数增加对应的图像
plt.figure() # 定义一个图像窗口
plt.plot(range(num_iterations), losserror)
plt.xlabel('迭代次数')
plt.ylabel('损失函数的值')
plt.title('损失函数随迭代次数关系图')
plt.show() # 注意不能忘了plt.show()
return [b, w]
# 4.运行程序,并定义所需参数
def run():
points = np.genfromtxt("data.csv", delimiter=",")
learning_rate = 0.0001
initial_b = 0 # 假设初值为零
initial_w = 0
num_iterations = 20 # 定义迭代次数为20次
# 假设b,w的初值后,计算误差
print("Starting gradient descent at b = {0}, m = {1}, error = {2}"
.format(initial_b, initial_w,
compute_error_for_line_given_points(initial_b, initial_w, points))
)
print("Running...")
# 开始运行梯度下降法计算b和w的值
[b, w] = gradient_descent_runner(points, initial_b, initial_w, learning_rate, num_iterations)
print("After {0} iterations b = {1}, m = {2}, error = {3}".
format(num_iterations, b, w,
compute_error_for_line_given_points(b, w, points))
)
[b_final, w_final] = [b,w]
# 绘制拟合图像
c = np.linspace(1.0, 100.0, 20) # np.linspace()函数为在指定的间隔内返回均匀间隔的数字,把区间等分
d = np.zeros(20)
for i in range(20):
d[i] = c[i] * w_final + b_final
plt.figure()
# 添加原始数据
x = points[:, 0]
y = points[:, 1]
plt.scatter(x, y, c='r', s=4.0)
plt.plot(c, d)
plt.title('数据拟合图像')
plt.show()
'''
scatter()函数用来绘制散点图并,使用实参s设置了绘制图形时使用的点的尺寸。
'''
# 5.程序开始运行
if __name__ == '__main__':
run()
程序所用数据集链接如下:
链接: https://pan.baidu.com/s/1iny7TvOhZVUsaZ9HHjsDLw
提取码: hgut