梯度下降法求解局部最小值深入讨论以及 Python 实现

文章目录

0. 前期准备

在开始讲梯度下降法求解函数的局部最小值之前, 你需要有梯度下降法求解函数的最小值的相关知识。

如果你还不是很了解,可以参看我的另外一篇文章:

梯度下降法以及 Python 实现(小提示:小手点一点就可以跳转了)

1. 局部最小值

对于一些函数而言,在某个自变量区间范围内存在一个最小值,且这个最小值比全局最小值大。那么我们就称这个最小值为局部最小值。

数学定义:

如果存在一个 ε > 0 \varepsilon > 0 ε>0,使得所有满足 ∣ x − x ∗ ∣ < ε \lvert x-x^* \rvert < \varepsilon xx<ε x x x 都有 f ( x ∗ ) ≤ f ( x ) f(x^*) \leq f(x) f(x)f(x),我们就把点 x ∗ x^* x 对应的函数值 f ( x ∗ ) f(x^*) f(x) 称为函数 f ( x ) f(x) f(x) 的一个局部最小值。

2. 例子

上面的定义可能不好理解,用图来表示就很非常直观了。接下来,直接给出一个例子:

使用梯度下降法来计算下面函数 f ( x ) f(x) f(x) 的最小值。
f ( x ) = x 4 + 2 x 3 − 3 x 2 − 2 x . f(x) = x^4 + 2x^3 - 3x^2 - 2x. f(x)=x4+2x33x22x.


f ( x ) f(x) f(x) x x x 的微分为:
f ′ ( x ) = d f ( x ) d x = 4 x 3 + 6 x 2 − 6 x − 2 f'(x) = \frac{\mathrm{d}f(x)}{\mathrm{d}x} = 4x^3 + 6x^2 - 6x - 2 f(x)=dxdf(x)=4x3+6x26x2

设置学习率 η = 0.01 \eta=0.01 η=0.01,初始值 x 0 = 2.0 x^0=2.0 x0=2.0

eta = 0.01
x = 2.0

Python 代码实现:

import numpy as np
import matplotlib.pyplot as pltdef my_func(x):"""$y = x^4 + 2x^3 - 3x^2 - 2x$:param x: 变量:return: 函数值"""return x ** 4 + 2 * x ** 3 - 3 * x ** 2 - 2 * xdef grad_func(x):"""函数 $y = 4x^3 + 6x^2 - 6x - 2$ 的导数:param x: 变量:return: 导数值"""return 4 * x ** 3 + 6 * x ** 2 - 6 * x - 2eta = 0.01
x = 2.0
record_x = []
record_y = []for i in range(20):y = my_func(x)record_x.append(x)record_y.append(y)x -= eta * grad_func(x)print(np.round(record_x, 4))
print(np.round(record_y, 4))x_f = np.linspace(-3, 2)
y_f = my_func(x_f)plt.plot(x_f, y_f, linestyle='--', color='red')
plt.scatter(record_x, record_y)plt.xlabel('x', size=14)
plt.ylabel('y', size=14)
plt.grid()
plt.show()

x x x 的变化过程:

[2. 1.58 1.3872 1.2682 1.1862 1.1262 1.0805 1.0449 1.0164 0.9934 0.9746 0.959 0.9461 0.9353 0.9262 0.9185 0.912 0.9065 0.9018 0.8978]

f ( x ) f(x) f(x) 的变化过程:

[16. 3.4714 0.495 -0.6951 -1.2755 -1.5919 -1.7774 -1.8916 -1.9647 -2.0128 -2.0451 -2.0672 -2.0826 -2.0933 -2.101 -2.1064 -2.1103 -2.1132 -2.1152 -2.1167]

在这里插入图片描述

可以看到,初始值 x 0 = 2.0 x^0=2.0 x0=2.0 在图像的右上角。经过梯度下降法求解, f ( x ) f(x) f(x) 的值落在了一个局部最小值上。

3. 讨论

我们来讨论一下,在知晓函数图像的情形下,如何才能得到正确的全局最小值。

3.1 增加迭代次数

在上面的这种情况下,我们继续迭代,也不无法得到最小值的。也即是说 x x x 被右侧的局部最小值抓取并无法脱离,陷入了局部最小值陷阱。

为什么说是陷阱呢?因为假如你的目的是求解这个函数的最小值,现在梯度下降法停止了,得到了一个局部最小值。但是你并不清楚这是局部最小值,还开心的以为是全局最小值。你就将这个局部最小值当做是全局最小值进行处理了。你就陷入了这个陷阱中。

使用 Python 模拟一下:
将迭代的次数设置为 100 次(200 次也可以,甚至更多次都行)。
只需要修改

for i in range(100):

或者设置一个变量

num_max_iterations = 100
for i in range(num_max_iterations):

x x x 的值会在 0.8733 处停止变化:

[2. 1.58 1.3872 1.2682 1.1862 1.1262 1.0805 1.0449 1.0164 0.9934
0.9746 0.959 0.9461 0.9353 0.9262 0.9185 0.912 0.9065 0.9018 0.8978
0.8943 0.8914 0.8889 0.8867 0.8848 0.8832 0.8819 0.8807 0.8797 0.8788
0.878 0.8774 0.8768 0.8763 0.8759 0.8756 0.8752 0.875 0.8747 0.8745
0.8744 0.8742 0.8741 0.874 0.8739 0.8738 0.8737 0.8737 0.8736 0.8736
0.8735 0.8735 0.8735 0.8734 0.8734 0.8734 0.8734 0.8734 0.8734 0.8734
0.8733 0.8733 0.8733 0.8733 0.8733 0.8733 0.8733 0.8733 0.8733 0.8733
0.8733 0.8733 0.8733 0.8733 0.8733 0.8733 0.8733 0.8733 0.8733 0.8733
0.8733 0.8733 0.8733 0.8733 0.8733 0.8733 0.8733 0.8733 0.8733 0.8733
0.8733 0.8733 0.8733 0.8733 0.8733 0.8733 0.8733 0.8733 0.8733 0.8733]

f ( x ) f(x) f(x) 的值会在 -2.1209 处停止变化:

[16. 3.4714 0.495 -0.6951 -1.2755 -1.5919 -1.7774 -1.8916 -1.9647
-2.0128 -2.0451 -2.0672 -2.0826 -2.0933 -2.101 -2.1064 -2.1103 -2.1132
-2.1152 -2.1167 -2.1178 -2.1186 -2.1192 -2.1196 -2.12 -2.1202 -2.1204
-2.1205 -2.1206 -2.1207 -2.1207 -2.1208 -2.1208 -2.1208 -2.1208 -2.1208
-2.1208 -2.1209 -2.1209 -2.1209 -2.1209 -2.1209 -2.1209 -2.1209 -2.1209
-2.1209 -2.1209 -2.1209 -2.1209 -2.1209 -2.1209 -2.1209 -2.1209 -2.1209
-2.1209 -2.1209 -2.1209 -2.1209 -2.1209 -2.1209 -2.1209 -2.1209 -2.1209
-2.1209 -2.1209 -2.1209 -2.1209 -2.1209 -2.1209 -2.1209 -2.1209 -2.1209
-2.1209 -2.1209 -2.1209 -2.1209 -2.1209 -2.1209 -2.1209 -2.1209 -2.1209
-2.1209 -2.1209 -2.1209 -2.1209 -2.1209 -2.1209 -2.1209 -2.1209 -2.1209
-2.1209 -2.1209 -2.1209 -2.1209 -2.1209 -2.1209 -2.1209 -2.1209 -2.1209
-2.1209]

在这里插入图片描述
结果和上面迭代次数为 20 的情形是一致的。说明在这种情形下,增加迭代次数是无效的。

3.2 修改学习率 η \eta η

将这个局部最小值想象成一个“小水坑”,那么我们能不能不要踩到“水坑”里,一下子“跳”过去呢?

答案是可以的。学习率 η \eta η 就可以实现这个功能。

同样的 x 0 = 2.0 x^0=2.0 x0=2.0,学习率 η \eta η 设置为 0.1。

eta = 0.1
x = 2.0

x x x 的变化:

[ 2. -2.2 -1.9648 -2.2259 -1.9227 -2.2513 -1.879 -2.2711 -1.8428
-2.2828 -1.8207 -2.2879 -1.811 -2.2896 -1.8076 -2.2901 -1.8066 -2.2903
-1.8063 -2.2903]

f ( x ) f(x) f(x) 的变化:

[16. -7.9904 -7.9187 -7.9206 -7.7945 -7.8352 -7.6367 -7.7556 -7.4858
-7.7035 -7.3855 -7.6799 -7.3396 -7.6716 -7.3235 -7.6691 -7.3186 -7.6683
-7.3172 -7.6681]

图像求解过程:
在这里插入图片描述

可以看到当 η \eta η 变大后, x x x 直接就跳到了 f ( x ) f(x) f(x) 的图像左侧,进入了全局最小值的范围内。

3.3 修改初始值 x 0 x^0 x0

设置合适的初始值,就可以得到正确的全局最小值。

比如观察图像,可以看到全局最小值的点, x x x 落在区间 ( − 3 , − 2 ] (-3, -2] (3,2] 之间。

所以我们设置 x 0 = − 3 x^0 = -3 x0=3,学习率 η = 0.01 \eta=0.01 η=0.01

x = -3.0
eta = 0.01

x x x

[-3. -2.62 -2.4497 -2.3487 -2.2824 -2.2363 -2.2032 -2.1788 -2.1607
-2.1469 -2.1365 -2.1285 -2.1223 -2.1175 -2.1138 -2.1109 -2.1087 -2.1069
-2.1056 -2.1045]

f ( x ) f(x) f(x)

[ 6. -4.2027 -6.493 -7.3339 -7.7058 -7.8879 -7.9828 -8.0345 -8.0635
-8.0801 -8.0897 -8.0954 -8.0988 -8.1008 -8.102 -8.1028 -8.1032 -8.1035
-8.1036 -8.1037]

在这里插入图片描述

那假如同样的初始值,但是将学习率变化呢?

  • 合适的初始值,搭配过大的学习率

设置 x 0 = − 3.0 x^0=-3.0 x0=3.0 η = 0.1 \eta=0.1 η=0.1

x = -3.0
eta = 0.1

在这里插入图片描述
从图像可以看出,这种情形下,仍然无法得到正确的全局最小值。

  • 合适的初始值,搭配过小的学习率

设置 x 0 = − 3.0 x^0=-3.0 x0=3.0 η = 0.001 \eta=0.001 η=0.001

x = -3.0
eta = 0.001

在这里插入图片描述
从图像可以看出,这种情形下, f ( x ) f(x) f(x) 向着全局最小值收敛,但在固定迭代次数内,还没有达到。这需要增加迭代次数,消耗更多的资源。

4. 总结

初始值 x 0 x^0 x0、学习率 η \eta η、迭代次数,共同影响梯度下降法的求解过程。

其中, x 0 x^0 x0 η \eta η 决定了方向,起了关键性作用。

参考

-《用Python编程和实践!数学教科书》

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

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

相关文章

css部分

前面我们学习了HTML&#xff0c;但是HTML仅仅只是做数据的显示&#xff0c;页面的样式比较简陋&#xff0c;用户体验度不高&#xff0c;所以需要通过CSS来完成对页面的修饰&#xff0c;CSS就是页面的装饰者&#xff0c;给页面化妆&#xff0c;让它更好看。 1 层叠样式表&#…

7-zip如何分卷压缩文件并加密?

想要压缩的文件过大&#xff0c;想要在压缩过程中将文件拆分为几个压缩包并且同时为所有压缩包设置加密应该如何设置&#xff1f; 想要分卷压缩文件并加密一起操作就可以完成了&#xff0c;设置方法如下&#xff1a; 打开7-zip&#xff0c;选中需要压缩的文件&#xff0c;选择…

14.在 Vue 3 中使用 OpenLayers 自定义地图版权信息

在 WebGIS 开发中&#xff0c;默认的地图服务通常会带有版权信息&#xff0c;但有时候我们需要根据项目需求自定义版权信息或添加额外的版权声明。在本文中&#xff0c;我们将基于 Vue 3 的 Composition API 和 OpenLayers&#xff0c;完成自定义地图版权信息的实现。 最终效果…

【游戏】超休闲游戏:简单易上手的游戏风潮

1. 什么是超休闲游戏&#xff1f; 超休闲游戏&#xff08;Hyper-Casual Games&#xff09; 是一种专注于简单玩法、快速上手、短时间内能完成的游戏类型。这类游戏通常具有以下特点&#xff1a; 玩法简单&#xff1a;规则直观&#xff0c;用户无需教程即可上手。碎片化体验&a…

【RTKLIB源码阅读】rtklibexplorer博客翻译-Updated guide to the RTKLIB configuration file

我已经有一段时间没有更新我的RTKLIB配置文件指南了。 自从上次更新以来,我增加了一些新的功能,并对一些现有的功能有了更多的了解。 对于以前的更新,我只是更新了原帖,但这次我想我应该重新发布它,使它更容易被找到。、 RTKLIB 的一大优点是它的可配置性极强,有一系列的…

excel文件合并,每个excel名称插入excel列

import pandas as pd import os # 设置文件夹路径 folder_path rC:\test # 替换为您的下载文件夹路径 output_file os.path.join(folder_path, BOM材料.xlsx) # 创建一个空的 DataFrame 用于存储合并的数据 combined_data pd.DataFrame() # 遍历文件夹中的所有文件 for …

无法找到 msvcr120.dll,无法执行程序要怎么处理?修改msvcr120.dll文件

遇到“无法找到 msvcr120.dll&#xff0c;无法执行程序”这类错误通常指示着你的计算机缺少了一个核心组件&#xff0c;即 Microsoft Visual C 2013 Redistributable 的一部分&#xff1a;msvcr120.dll 文件。这个文件是许多依赖 Visual C 的应用程序运行的基础。目前修复此类问…

MongDB快速入门

一&#xff0c;MongoDB简介 MongoDB是一个开源&#xff0c;高性能&#xff0c;无模式的文档数据库&#xff0c;当初的设计就是用于简化开发和方便扩展&#xff0c;是NoSQL数据库产品的一种&#xff0c;也是最想关系型数据库的非关系型数据库 它支持的数据结构非常松散&#x…

Kruskal 算法在特定边权重条件下的性能分析及其实现

引言 Kruskal 算法是一种用于求解最小生成树(Minimum Spanning Tree, MST)的经典算法。它通过逐步添加权重最小的边来构建最小生成树,同时确保不会形成环路。在本文中,我们将探讨在特定边权重条件下 Kruskal 算法的性能,并分别给出伪代码和 C 语言实现。特别是,我们将分…

实战 | C# 中使用GPU加速YOLOv11 推理

导 读 本文主要介绍如何在C#中使用GPU加速YOLOv11推理。 YOLOv11介绍 C# 中使用YOLOv11 (GPU版本) 【1】环境和依赖项。 下载安装CUDA12.6和CUDNN9.6,截止文章日期最新版本,注意选择自己的版本,我的系统是win11 64位。

大数据-244 离线数仓 - 电商核心交易 ODS层 数据库结构 数据加载 DataX

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; Java篇开始了&#xff01; 目前开始更新 MyBatis&#xff0c;一起深入浅出&#xff01; 目前已经更新到了&#xff1a; Hadoop&#xff0…

以nlp为例,区分BatchNorm、LayerNorm、GroupNorm、RMSNorm

以nlp中一个小批次数据&#xff0c;详细区分BatchNorm、LayerNorm、GroupNorm、RMSNorm。这几种归一化的不同。如下表格&#xff0c;从计算范围、统计量、计算复杂度以及应用场景等方面的差异给出。 方法计算范围统计量计算复杂度应用场景BatchNorm跨所有句子的同一维度使用批…

C# 高效编程指南:从命名空间到异常处理的技巧与最佳实践

在这条成长的路上&#xff0c;有一些核心概念将成为你开发过程中的得力助手—命名空间、预处理指令、正则表达式、异常处理和文件输入输出&#xff0c;这些看似独立的技术&#xff0c;实际上在大多数应用中都紧密相连&#xff0c;共同构成了C#开发的基础。 目录 C#命名空间 C…

普及组集训--图论最短路径设分层图

P4568 [JLOI2011] 飞行路线 - 洛谷 | 计算机科学教育新生态 可以设置分层图&#xff1a;(伪代码&#xff09; E(u,v)w;无向图 add(u,v,w),add(v,u,w); for(j1~k){add(ujn,vjn,w);add(vjn,ujn,w);add(ujn-j,vjn-j,0);add(vjn-j,ujn-j,0); } add(ujn-j,vjn-j,0); add(vjn-j,uj…

常用传感器介绍合集

SW-520D倾斜传感器 HX711模块&#xff1a;高精度称重的核心利器 GY302光照传感器模块详解 MLX90614红外测温传感器介绍 MAX30102心率血氧传感器模块&#xff1a;精准健康监测的利器 RGB颜色传感器简介 DS18B20温度传感器模块 人体红外传感器简介 FC-28土壤湿度传感器 …

gitee常见命令

目录 1.本地分支重命名 2.更新远程仓库分支 3.为当前分支设置远程跟踪分支 4.撤销已经push远程的代码 5.idea->gitee的‘还原提交’ 需要和本地当前的代码解决冲突 解决冲突 本地工作区的差异代码显示 本地commit和push远程 6.idea->gitee的‘将当前分支重置到此…

C++设计模式(建造者、中介者、备忘录)

一、建造者模式 将一个复杂对象的构建与它的表示分离&#xff0c;使得同样的构建过程可以创建不同的表示。 示例&#xff1a; //房子&#xff08;产品类&#xff09; class House { private:int rooms;int windows;string decoration; public:void setRooms(int r) {rooms …

简易图书管理系统

javawebjspservlet 实体类 package com.ghx.entity;/*** author &#xff1a;guo* date &#xff1a;Created in 2024/12/6 10:13* description&#xff1a;* modified By&#xff1a;* version:*/ public class Book {private int id;private String name;private double pri…

什么是甘特图?使用甘特图制定项目计划表的步骤

在项目管理中&#xff0c;项目计划是项目的核心要素&#xff0c;它详细记录了项目任务详情、责任人、时间规划以及所需资源。 这份计划不仅为项目推进提供指引&#xff0c;更是控制范围蔓延、争取更多支持的有力工具。 在项目管理中&#xff0c;项目计划是项目的核心要素&…

mock.js介绍

mock.js http://mockjs.com/ 1、mock的介绍 *** 生成随机数据&#xff0c;拦截 Ajax 请求。** 通过随机数据&#xff0c;模拟各种场景&#xff1b;不需要修改既有代码&#xff0c;就可以拦截 Ajax 请求&#xff0c;返回模拟的响应数据&#xff1b;支持生成随机的文本、数字…