【机器学习】梯度下降的基本概念和如何使用梯度下降自动化优化w和b

news2024/11/12 16:44:11

引言

梯度下降是一种用于寻找函数最小值的优化算法,它在机器学习中广泛用于训练模型,如线性回归、神经网络等

一、梯度下降的基本概念

1.1 目标函数

在机器学习中,这通常是损失函数(如均方误差、交叉熵等),我们希望最小化它以训练模型

1.2 梯度

目标函数相对于每个参数的偏导数向量。它指向目标函数增长最快的方向

1.3 学习率(步长)

决定了在梯度下降过程中每一步移动的距离大小

二、梯度下降的步骤

2.1 初始化参数

随机选择一个参数的初始值或者基于某些启发式方法

2.2 计算梯度

计算目标函数在当前参数值处的梯度

2.3 更新参数

根据梯度和学习率来更新参数
θ θ θ= θ θ θ α α α ∇ θ ∇_θ θ J ( θ ) J(θ) J(θ)
其中, θ θ θ是参数向量, α α α是学习率, J ( θ ) J(θ) J(θ)是目标函数, ∇ θ ∇_θ θ J ( θ ) J(θ) J(θ)是目标函数的梯度

2.4 重复步骤2和3

重复计算梯度并更新参数,直到满足停止条件(如梯度变得非常小或者达到预设的迭代次数)

三、梯度下降的变体

3.1 批量梯度下降(Batch Gradient Descent)

使用所有样本来计算梯度

3.2 随机梯度下降(Stochastic Gradient Descent, SGD)

每次迭代使用一个样本来计算梯度

3.3 小批量梯度下降(Mini-batch Gradient Descent)

每次迭代使用一部分样本来计算梯度

四、注意事项

4.1 学习率的选择

学习率太大可能导致算法无法收敛,太小则收敛速度过慢。

4.2 局部最小值和鞍点

梯度下降可能会陷入局部最小值或鞍点,尤其是在非凸优化问题中

4.3 梯度消失/爆炸

在深度学习中,梯度可能会在反向传播过程中变得非常小(消失)或非常大(爆炸),影响训练

在实现梯度下降时,可能需要调整多个超参数(如学习率、迭代次数等)以获得最佳性能。此外,还有一些高级的梯度下降变种和优化技术,如动量(Momentum)、自适应学习率(如AdaGrad、RMSprop、Adam等),它们可以帮助算法更快地收敛

五、如何使用梯度下降自动化优化 w w w b b b

5.1 工具

在本次实验中,我们将使用以下工具:

  • NumPy,一个流行的科学计算库
  • Matplotlib,一个流行的绘图数据库
  • 在本地目录的lab_utils.py文件中的绘图例程
import math, copy
import numpy as np
import matplotlib.pyplot as plt
plt.style.use('./deeplearning.mplstyle')
from lab_utils_uni import plt_house_x, plt_contour_wgrad, plt_divergence, plt_gradients

5.2 问题陈述

让我们使用之前相同的两个数据点 :一个1000平方英尺的房子以30万美元的价格售出,一个2000平方英尺的房子以50万美元的价格售出。

尺寸(1000平方英尺)价格(以千美元计)
1300
2500
# 加载数据集
x_train = np.array([1.0, 2.0])   # 特征
y_train = np.array([300.0, 500.0])   # 目标值

5.3 计算成本

# 计算成本的函数
def compute_cost(x, y, w, b):
   
    m = x.shape[0] 
    cost = 0
    
    for i in range(m):
        f_wb = w * x[i] + b
        cost = cost + (f_wb - y[i])**2
    total_cost = 1 / (2 * m) * cost

    return total_cost

5.4 梯度下降概述

到目前为止,已经开发了一个线性模型,用于预测 f w , b ( x ( i ) ) f_{w,b}(x(i)) fw,b(x(i))
f w , b ( x ( i ) ) = w ⋅ x ( i ) + b f_{w,b}(x(i)) = w \cdot x(i) + b fw,b(x(i))=wx(i)+b
在线性回归中,利用输入训练数据来拟合参数 w w w b b b
通过最小化预测 f w , b ( x ( i ) ) f_{w,b}(x(i)) fw,b(x(i)) 和实际数据 y ( i ) y(i) y(i) 之间的误差来衡量
这个度量被称为成本 J ( w , b ) J(w, b) J(w,b)
在训练中,需要衡量所有训练样本 x ( i ) , y ( i ) x(i), y(i) x(i),y(i) 的成本:
J ( w , b ) = 1 2 m ∑ i = 0 m − 1 ( f w , b ( x ( i ) ) − y ( i ) ) 2 J(w, b) = \frac{1}{2m} \sum_{i=0}^{m-1} (f_{w,b}(x(i)) - y(i))^2 J(w,b)=2m1i=0m1(fw,b(x(i))y(i))2

梯度下降被描述为:

  1. 重复 w , b w, b w,b 直到收敛:
  2. w = w − α ∂ J ( w , b ) ∂ w w = w - \alpha \frac{\partial J(w, b)}{\partial w} w=wαwJ(w,b)
  3. b = b − α ∂ J ( w , b ) ∂ b b = b - \alpha \frac{\partial J(w, b)}{\partial b} b=bαbJ(w,b)
  • 其中,参数 w w w b b b 同时更新

梯度定义为:

∂ J ( w , b ) ∂ w = 1 m ∑ i = 0 m − 1 ( f w , b ( x ( i ) ) − y ( i ) ) x ( i ) \frac{\partial J(w, b)}{\partial w} = \frac{1}{m} \sum_{i=0}^{m-1} (f_{w,b}(x(i)) - y(i)) x(i) wJ(w,b)=m1i=0m1(fw,b(x(i))y(i))x(i)
∂ J ( w , b ) ∂ b = 1 m ∑ i = 0 m − 1 ( f w , b ( x ( i ) ) − y ( i ) ) \frac{\partial J(w, b)}{\partial b} = \frac{1}{m} \sum_{i=0}^{m-1} (f_{w,b}(x(i)) - y(i)) bJ(w,b)=m1i=0m1(fw,b(x(i))y(i))

5.5 实现梯度下降

实现一个特征的梯度下降算法,需要以下三个函数:

  • compute_gradient 实现定义的方程式
  • compute_cost 实现上面的方程式
  • gradient_descent,使用compute_gradientcompute_cost
    以下是对这些函数的实现和如何使用它们来找到最优的 w w w b b b 值的详细说明:
  • 包含偏导数的Python变量的命名遵循这种模式,∂𝐽(𝑤,𝑏)∂𝑏 将被称为 d j d b dj_db djdb
  • w.r.t 是 With Respect To 的缩写,例如偏导数 𝐽(𝑤𝑏) 关于 𝑏 的偏导数。

5.6 计算梯度

计算梯度实现了上面的方程式,并返回 ∂𝐽(𝑤,𝑏)∂𝑤 和 ∂𝐽(𝑤,𝑏)∂𝑏。内嵌的注释描述了操作

# compute_gradient函数的实现
def compute_gradient(x, y, w, b): 
    """
    Computes the gradient for linear regression 
    Args:
      x (ndarray (m,)): Data, m examples 
      y (ndarray (m,)): target values
      w,b (scalar)    : model parameters  
    Returns
      dj_dw (scalar): The gradient of the cost w.r.t. the parameters w
      dj_db (scalar): The gradient of the cost w.r.t. the parameter b     
     """
    
    # 训练样本的数量
    m = x.shape[0]    
    dj_dw = 0
    dj_db = 0
    
    for i in range(m):  
        f_wb = w * x[i] + b 
        dj_dw_i = (f_wb - y[i]) * x[i] 
        dj_db_i = f_wb - y[i] 
        dj_db += dj_db_i
        dj_dw += dj_dw_i 
    dj_dw = dj_dw / m 
    dj_db = dj_db / m 
        
    return dj_dw, dj_db

在这里插入图片描述
文章中描述了梯度下降如何利用目标函数相对于参数在某个点的偏导数来更新该参数

使用compute_gradient函数来找到并绘制我们成本函数相对于其中一个参数的偏导数,比如 w 0 w_0 w0

plt_gradients(x_train,y_train, compute_cost, compute_gradient)
plt.show()

输出结果:
在这里插入图片描述
在上图中,左边的图显示了 ∂𝐽(𝑤,𝑏)∂𝑤 或成本曲线相对于 𝑤 在三个点的斜率。在图的右边,导数是正的,而在左边则是负的。由于“碗形”的形状,偏导数将总是引导梯度下降向成本为零的底部
左边的图固定了 𝑏=100。梯度下降将利用 ∂𝐽(𝑤,𝑏)∂𝑤 和 ∂𝐽(𝑤,𝑏)∂𝑏 来更新参数。右边的“箭头图”提供了一种查看两个参数梯度的方法。箭头的大小反映了该点的梯度大小。箭头的方向和斜率反映了该点处 ∂𝐽(𝑤,𝑏)∂𝑤 和 ∂𝐽(𝑤,𝑏)∂𝑏 的比率

请注意,梯度指向最小值之外。回顾上面的方程式。缩放的梯度被从当前的 𝑤 或 𝑏 值中减去。这会使参数移动到将减少成本的方向

5.7 梯度下降

现在可以计算梯度,就可以在下方的gradient_descent中实现梯度下降,实现细节在注释中进行了描述。下面,使用这个函数在训练数据上找到 𝑤 和 𝑏 的最优值

def gradient_descent(x, y, w_in, b_in, alpha, num_iters, cost_function, gradient_function): 
    """
    执行梯度下降来拟合 w,b。通过使用学习率 alpha 进行 num_iters 步的梯度下降来更新 w,b。
    
    参数:
      x (ndarray (m,))  : 数据集,包含 m 个样本
      y (ndarray (m,))  : 目标值
      w_in,b_in (标量): 模型参数的初始值
      alpha (float): 学习率
      num_iters (int): 运行梯度下降的迭代次数
      cost_function: 用于产生成本的函数
      gradient_function: 用于产生梯度的函数
      
    返回:
      w (标量): 运行梯度下降后更新的参数值
      b (标量): 运行梯度下降后更新的参数值
      J_history (列表): 成本值的历史记录
      p_history (列表): 参数 [w,b] 历史记录
      """
    
    w = copy.deepcopy(w_in) # 避免修改全局 w_in
    # 用于存储每个迭代周期的成本 J 和 w 的数组,主要用于后续的图形化展示
    J_history = []
    p_history = []
    b = b_in
    w = w_in
    
    for i in range(num_iters):
        # 计算梯度并使用 gradient_function 更新参数
        dj_dw, dj_db = gradient_function(x, y, w , b)     
        # 使用方程 (3) 更新参数
        b = b - alpha * dj_db                            
        w = w - alpha * dj_dw                            
        # 保存每个迭代周期的成本 J
        if i<100000:      # 防止资源耗尽
            J_history.append( cost_function(x, y, w , b))
            p_history.append([w,b])
        # 每隔一定迭代次数打印成本
        if i% math.ceil(num_iters/10) == 0:
            print(f"迭代 {i:4}: 成本 {J_history[-1]:0.2e} ",
                  f"dj_dw: {dj_dw: 0.3e}, dj_db: {dj_db: 0.3e}  ",
                  f"w: {w: 0.3e}, b:{b: 0.5e}")
 
    return w, b, J_history, p_history # 返回 w 和 J,w 历史记录用于图形化展示
# 初始化参数
w_init = 0
b_init = 0
# 一些梯度下降设置
iterations = 10000 # 设置梯度下降的迭代次数
tmp_alpha = 1.0e-2 # 设置初始学习率
# 运行梯度下降
w_final, b_final, J_hist, p_hist = gradient_descent(x_train ,y_train, w_init, b_init, tmp_alpha, 
                                                    iterations, compute_cost, compute_gradient)
print(f"(w,b) 由梯度下降找到的值: ({w_final:8.4f},{b_final:8.4f})")

输出结果:
在这里插入图片描述
在这里插入图片描述

仔细观察上述打印的梯度下降过程,注意其一些特点:

  • 成本开始时很大,然后迅速下降,这与讲座中的幻灯片描述一致
  • 部分导数 ( dj_dw ) 和 ( dj_db ) 也变小,起初很快,然后逐渐变慢。如图所示,随着过程接近“碗底”,由于该点的导数值较小,进展变得较慢
  • 尽管学习率 ( \alpha ) 保持固定,但进展仍然变慢

5.8 梯度下降过程中的成本与迭代次数

成本与迭代次数的图表是梯度下降过程中进度的一个有用的衡量指标。在成功的运行中,成本应该始终下降。初始时,成本的变化非常迅速,因此将初始下降放在不同的尺度上与最终下降相比是有用的。在下面的图表中,请注意成本轴上的尺度以及迭代步骤

# 绘制成本与迭代次数
fig, (ax1, ax2) = plt.subplots(1, 2, constrained_layout=True, figsize=(12,4))
ax1.plot(J_hist[:100])
ax2.plot(1000 + np.arange(len(J_hist[1000:])), J_hist[1000:])
ax1.set_title("成本与迭代(开始)");  ax2.set_title("成本与迭代 (结束)")
ax1.set_ylabel('成本')            ;  ax2.set_ylabel('成本') 
ax1.set_xlabel('迭代步骤')  ;  ax2.set_xlabel('迭代步骤') 
plt.show()

输出结果:
在这里插入图片描述
预测
现在已经发现了参数 w w w b b b 的最优值,可以使用学到的参数来预测房价。如预期,预测值与同一住房的训练值几乎相同。此外,不在预测中的值与预期值一致。

print(f"1000平方英尺房子的预测 {w_final*1.0 + b_final:0.1f} 千美元")
print(f"1200平方英尺房子的预测 {w_final*1.2 + b_final:0.1f} 千美元")
print(f"2000平方英尺房子的预测 {w_final*2.0 + b_final:0.1f} 千美元")

输出结果

在这里插入图片描述

5.9 绘图

可以通过在成本 ( w , b ) ( w, b ) (w,b的等高线图上绘制成本来展示梯度下降在其执行过程中的进度。

fig, ax = plt.subplots(1,1, figsize=(12, 6))
plt_contour_wgrad(x_train, y_train, p_hist, ax)

输出结果
在这里插入图片描述

在上面的等高线图中,显示了 w w w b b b 范围内的 J ( w , b ) J(w, b) J(w,b)。成本水平由环形表示。覆盖在上面的,使用红色箭头,是梯度下降的路径。这里有一些需要注意的事情:

  • 路径稳步(单调)地朝着其目标前进。
  • 初始步骤比接近目标时的步骤要大得多。
  • 放大,我们可以看到梯度下降的最终步骤。注意,随着梯度接近零,步骤之间的距离缩小了。
fig, ax = plt.subplots(1,1, figsize=(12, 4))
plt_contour_wgrad(x_train, y_train, p_hist, ax, w_range=[180, 220, 0.5], b_range=[80, 120, 0.5],
            contours=[1,5,10,20],resolution=0.5)

输出结果:
在这里插入图片描述

增加学习率
在讲座中,有关学习率 α \alpha α 的适当值的讨论与方程式有关。较大的 α \alpha α 会使梯度下降更快地收敛到解决方案。但是,如果它太大,梯度下降将会发散。在上面的例子中,有一个收敛良好的解决方案。
让我们尝试增加 α \alpha α 的值,看看会发生什么:

# 初始化参数
w_init = 0
b_init = 0
# 将alpha设置为一个大值
iterations = 10
tmp_alpha = 8.0e-1
# 运行梯度下降
w_final, b_final, J_hist, p_hist = gradient_descent(x_train ,y_train, w_init, b_init, tmp_alpha, 
                                                    iterations, compute_cost, compute_gradient)

在这里插入图片描述

在上面的图中, w w w b b b 在每次迭代中都在正负之间弹跳,其绝对值随着每次迭代而增加。此外,每次迭代中 ∂ J ( w , b ) / ∂ w \partial J(w,b)/\partial w J(w,b)/w 的符号都会改变,而成本却在增加而不是减少。这是一个明显的迹象,表明学习率太大,解决方案正在发散

六、总结

  • 深入了解单变量梯度下降的细节
  • 开发一个计算梯度的例行程序
  • 可视化梯度的本质
  • 完成一个梯度下降例行程序
  • 利用梯度下降找到参数
  • 检查学习率大小的影响

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1948279.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

[渗透测试] 主动信息收集

主动信息收集 在红蓝对抗过程中&#xff0c;资产属于核心地位&#xff0c;攻击方&#xff08;红方&#xff09;要尽可能的去获取对方资产&#xff0c;暴露目标资产&#xff0c;包括IP地址、网络设备、安全设备、服务器、存储在服务器中的数据等。防守方也要清楚自己有多少有价…

了解网络是如何运作

“Web 的工作原理”提供了一个简化的视图,用于了解在计算机或手机上的 Web 浏览器中查看网页时发生的情况。 这个理论对于短期内编写 Web 代码来说并不是必需的,但不久之后,你就会真正开始从理解后台发生的事情中受益。 客户端和服务器 连接到 Internet 的计算机称为客户端和…

dns逆向解析,主从服务,多域名访问(穿插ntp服务器)

复习 域名解析&#xff1a; 正向解析&#xff1a;将域名解析为ip 反向解析&#xff1a;将ip解析为域名 逆向解析 关闭防火墙和selinux&#xff0c;配置静态ip [rootdns ~]# vim /etc/named.rfc1912.zones [rootdns ~]# vim /etc/named.conf [rootdns ~]# cd /var/named/ [rootd…

刚购买的阿里云服务器该如何配置环境(CentOS)

文章目录 购买开始初始设置登录云服务器安装 Apache 服务安装 MySQL安装 PHP快照 第三方 SSH 登录笔者的话 购买 按照需求购买就行。学生有免费试用一个月的活动&#xff0c;可以试着玩玩。 开始初始设置 登录云服务器 购买完后&#xff0c;点击实例&#xff0c;点击实例名…

Linux下RDMA驱动程序探索系列-2

本系列文章将带领读者逐步了解Linux操作系统下的RDMA子系统。本篇文章作为系列的第二篇&#xff0c;将深入内核态驱动程序的代码&#xff0c;主要介绍如下内容&#xff1a; Driver的初始化流程几个重要verbs回调函数的简介 01、Kernel Driver的初始化流程 由于不同厂商的驱动…

进销存系统开发,含税小计和含税单价计算,含税和不含税,1000元电脑为案例

if (data ! null) {console.log("中断调试&#xff0c;2024-7-25 最终计算税务");//删除不需要会报错var 未来之窗_人工智能_计算_税额 parseFloat((data.price * data.num * data.tax_rate / 100 ).toFixed(2));var 未来之窗_人工智能_计算_含税小计 parseFloat((…

js轮播图制作

实现一个简单的JavaScript轮播图可以通过以下步骤完成&#xff1a; 创建HTML结构&#xff0c;包括轮播图容器和图片列表。 使用CSS进行样式设置&#xff0c;包括隐藏多余的图片。 使用JavaScript编写函数来控制图片的切换。

07-15 周一 lmdeploy导出迁移因子到量化模型中

07-15 周一 lmdeploy导出迁移因子到量化模型中 时间版本修改人描述2024年7月15日14:57:02V0.1宋全恒新建文档 简介 方案设计 由于norm层的前后导致smoothquant执行量化不好融合&#xff0c;为了降低我事先的难度&#xff0c;所以就不再融合normalization的算子了&#xff0c…

vue3编程-import.meta.glob实现动态路由(菜单)

import.meta.glob 是vite提供的批量懒加载组件的方法 本地开发环境&#xff1a; const modules import.meta.glob(../views/**/*.vue)这段代码返回的modules是一个Map&#xff1a; key是vue文件的相对路径&#xff0c;值是一个函数&#xff0c;将函数打印出来&#xff0c;如…

【微信小程序实战教程】之微信小程序原生开发详解

微信小程序原生开发详解 微信小程序的更新迭代非常频繁&#xff0c;几乎每个月都会有新版本发布&#xff0c;这就会让初学者感觉到学习的压力和难度。其实&#xff0c;我们小程序的每次版本迭代都是在现有小程序架构基础之上进行更新的&#xff0c;如果想要学好小程序开发技术&…

配置mysql8.0.21版本docker-compose启动容器

1. 总览 2 docker-compose.xml配置 version: 3 services:mysql:image: 192.168.188.131:8000/mysqlrestart: alwaysvolumes:- ./data:/var/lib/mysql- ./my.cnf:/etc/mysql/my.cnf- ./mysql-files:/var/lib/mysql-files- ./log/mysql:/var/log/mysqlenvironment:MYSQL_ROOT_PA…

Shell实现服务自动部署

一、环境 注意&#xff1a; nfs.example.com应该为nfs.exam.com 172.25.250.101-172.25.250.105 共 5 个 IP 地址由servera.exam.com服务器进行提供。 172.25.250.106 由 serverb.exam.com 服务器进行提供。 二、需求 项目需求&#xff1a; 1. 172.25.250.101 主机上的 W…

UEFI DebugLib 介绍

1.我们调试中常用Debug 打印信息&#xff0c;这些会输出到BIOS串口日志中 EFI_STATUSEFIAPIHelloWorld2(IN EFI_HANDLE ImageHandle,IN EFI_SYSTEM_TABLE *SystemTable){EFI_STATUS Status;StatusEFI_SUCCESS;gST->ConOut->OutputString(gST->ConOut,L&q…

如何保护您的 WordPress 不被黑?

明月可以说是见到过太多 WordPress 网站被黑的示例了&#xff0c;加上平时明月也会接一些 WordPress 疑难杂症的解决服务订单&#xff0c;所以这方面绝对是专业对口了。作为一个资深 WordPress 博客站长&#xff0c;谁都有被黑过的经历&#xff0c;都是一步步走过来的&#xff…

从零入门AI for Science(AI+化学)#Datawhale AI 夏令营

基于天池平台“第二届世界科学智能大赛 物质科学赛道&#xff1a;催化反应产率预测”使用平台 我的Notebook 魔搭社区 https://modelscope.cn/my/mynotebook/preset 赛事官网 上海科学智能研究院 http://competition.sais.com.cn/competitionDetail/532233/myScore Task1 …

七、SpringBoot日志

1. 得到日志对象 import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; //打印日志…

【Vue实战教程】之Vue工程化项目详解

Vue工程化项目 随着多年的发展&#xff0c;前端越来越模块化、组件化、工程化&#xff0c;这是前端发展的大趋势。webpack是目前用于构建前端工程化项目的主流工具之一&#xff0c;也正变得越来越重要。本章节我们来详细讲解一下如何使用webpack搭建Vue工程化项目。 1 使用we…

Web渗透-WAF绕过技巧

一、WAF简介 Web应用防护系统&#xff08;也称为&#xff1a;网站应用级入侵防御系统。英文&#xff1a;Web Application Firewall&#xff0c;简称&#xff1a; WAF&#xff09;。利用国际上公认的一种说法&#xff1a;Web应用防火墙是通过执行一系列针对HTTP/HTTPS的安全策略…

叮!2024 龙蜥操作系统大会议题征集正式启动

定啦&#xff01;2024 龙蜥操作系统大会&#xff08;OpenAnolis Conference&#xff0c;以下简称“龙蜥大会”&#xff09;将于 2024 年 8 月 30 日在北京中关村国家自主创新示范区会议中心盛大召开。 2024 龙蜥大会由中关村科学城管委会、海淀区委网信办、中国开源软件推进联…

配置sublime的中的C++编译器(.sublime-build),实现C++20

GCC 4.8: 支持 C11 (部分) GCC 4.9: 支持 C11 和 C14 (部分) GCC 5: 完全支持 C14 GCC 6: 支持 C14 和 C17 (部分) GCC 7: 支持 C17 (大部分) GCC 8: 完全支持 C17&#xff0c;部分支持 C20 GCC 9: 支持更多的 C20 特性 GCC 10: 支持大部分 C20 特性 GCC 11: 更全面地支持 C20 …