线性回归模型:梯度下降(机器学习)(python)

ps.线性回归模型可以看我之前发的文章:机器学习:线性回归模型(python)_cornki的博客-CSDN博客

目录

   

        一、什么是梯度下降

        二、梯度下降的数学形式

        三、直观理解梯度下降

         四、学习率

         五、代码实践(python)


        一、什么是梯度下降

        梯度下降是一种优化算法,用于最小化一个损失函数。它通过沿着损失函数的负梯度方向迭代来更新模型参数,从而使损失函数不断减小。

        二、梯度下降的数学形式

        同时更新w和b,重复到收敛:

        w=w-\alpha\frac{\partial J(w,b)}{\partial w}

        b=b-\alpha\frac{\partial J(w,b)}{\partial b}

        梯度定义为:

\frac{\partial J(w,b)}{\partial w}=\frac{1}{m}\sum\limits_{i=0}^{m-1}(f_{w,b}(x^{(i)})-y^{(i)})x^{(i)}

\frac{\partial J(w,b)}{\partial b}=\frac{1}{m}\sum\limits_{i=0}^{m-1}(f_{w,b}(x^{(i)})-y^{(i)})

        三、直观理解梯度下降

               

         如上图显示,\frac{\partial J(w,b)}{\partial w}成本曲线相对于𝑤,在图的右侧,导数为正数,而在左侧为负数。由于“碗形”,导数将始终导致梯度下降到梯度为零的底部。

         四、学习率

        \alpha:学习率是梯度下降算法中用于控制每次迭代中参数更新的步长大小的超参数。

         如上图所示,学习率越小,则每次迭代中参数更新的步长越小,算法收敛的速度较慢,但是更有可能找到全局最优解。学习率越大,则每次迭代中参数更新的步长越大,算法能够更快地收敛到最优解,但是可能会出现无法收敛或者收敛到局部最优解的问题。因此,在使用梯度下降算法时,需要根据具体问题选择合适的学习率。

通常初始学习率可选取范围为0.01~0.1,具体取值需要根据问题复杂程度、数据集大小等进行调整。

在编写代码时可以通过生成图形来判断自己设置的学习率是否合适 

         五、代码实践(python)

# 导入numpy、matplotlib模块
import numpy as np
from matplotlib import pyplot as plt
# 设定特征值
x_train = np.array([1,2,3,4,5,6] )
y_train = np.array([15,22,31,44,57,62] )
# 设定权重、偏移、学习率、x的数量、方差列表、w的列表(后面作图)
w = 1
b = 0
a = 0.01
m = len(x_train)
J_wb_list = []
w_list = []
# 定义#J_wb函数(方差)
def J_wb(w,x,b,m):
    cost_sum = 0
    for i in range(m):
        f_wb = w * x[i] + b
        cost = (f_wb - y_train[i]) ** 2
        cost_sum = cost_sum + cost
    J_wb = 1 / (2 * m) * cost_sum
    return J_wb
# 定义w_new函数(优化w值)
def w_new(w,x,b,m,a):
    cost_w_sum = 0
    for i in range(m):
        f_wb = w * x[i] + b
        cost_w = (f_wb - y_train[i]) * x[i]
        # print(cost_w)
        cost_w_sum = cost_w_sum + cost_w
    J_wb_w = w - (1 / m) * a * cost_w_sum
    return J_wb_w
# 定义b_new函数(优化b值)
def b_new(w,x,b,m,a):
    cost_b_sum = 0
    for i in range(m):
        f_wb = w * x[i] + b
        cost_b = f_wb - y_train[i]
        cost_b_sum = cost_b_sum + cost_b
    J_wb_b = b - (1 / m) * a * cost_b_sum
    return J_wb_b
# 设置循环判定条件和结束条件
J_wb_one = J_wb(w,x_train,b,m)
w_one = w_new(w,x_train,b,m,a)
b_one = b_new(w,x_train,b,m,a)
w=w_one
b=b_one
# 如果方差在图形(学习率的图片)左侧
if J_wb_one > J_wb(w,x_train,b,m):
    while J_wb_one > J_wb(w,x_train,b,m):
        J_wb_one = J_wb(w, x_train, b, m)
        w_one = w_new(w,x_train,b,m,a)
        b_one = b_new(w,x_train,b,m,a)
        w=w_one
        b=b_one
        J_wb_list.append(J_wb(w, x_train, b, m))
        w_list.append(w)
        if J_wb(w,x_train,b,m) == J_wb_one:
            break
# 如果方差在图形(学习率的图片)右侧
else:
    while J_wb_one < J_wb(w,x_train,b,m):
        J_wb_one = J_wb(w, x_train, b, m)
        w_one = w_new(w,x_train,b,m,a)
        b_one = b_new(w,x_train,b,m,a)
        w=w_one
        b=b_one
        J_wb_list.append(J_wb(w, x_train, b, m))
        w_list.append(w)
        if J_wb(w,x_train,b,m) == J_wb_one:
            break
print(w,b,J_wb(w,x_train,b,m))
# 绘制成本函数点
plt.scatter(w_list, J_wb_list)
# 绘制成本函数线
plt.plot(w_list, J_wb_list, color='red')
# 添加标题和标签
plt.title('Change map')
plt.xlabel('w')
plt.ylabel('J_wb')
# 显示图形
plt.show()

循环中的if语句是为了防止方差为0而导致死循环 

 

  • 4
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值