梯度法有哪些?

2024-01-20 08:50
文章标签 梯度 法有

本文主要是介绍梯度法有哪些?,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

为啥要提出梯度法?因为机器学习的主要任务就是在学习时寻找最优参数。啥叫最优参数?就是使损失函数值最小时的权重和偏置。而损失函数很复杂,参数空间庞大,使用梯度来寻找函数最小值的方法就是梯度法。梯度法使用梯度信息决定前进方向。由全部变量的偏导数汇总而成的向量成为梯度(gradient)。梯度指示方向是各点处函数值减少最多的方向,因此无法保证梯度所指方向就是函数最小值或真正应该前进的方向。因为函数的极小值、最小值以及被成为鞍点(saddle point)的地方,梯度都为0。极小值是局部最小值,也就是限定在某个范围内的最小值。鞍点是从某个方向上看是极大值,从另一个方向上看则是极小值的点。虽然梯度法是要寻找梯度为0的地方,但是那个地方不一定就是最小值,也有可能是极小值或鞍点。此外,当函数很复杂且呈扁平状时,学习可能会进入一个平坦地区,陷入被成为“学习高原”的无法前进的停滞期。

 在梯度法(gradient method)中,函数的取值从当前位置沿着梯度方向前进一定距离,然后在新地方重新求梯度,再沿着新梯度方向前进,如此反复不断沿梯度方向前进。梯度法是解决机器学习中最优化问题的常用方法,特别在神经网络的学习中经常被用到。根据目的是寻找最小值还是最大值,梯度法的叫法也不同。寻找最小值的梯度法称为梯度下降法(gradient descent method ),寻找最大值的梯度法称为梯度上升法(gradient ascent method)。神经网络中梯度法主要是指梯度下降法。

梯度法主要有以下两种。一种是数值微分,一种是误差反向传播。

1、数值微分

导数就是表示某个瞬间的变化量。

\frac{df(x)}{dx}= \lim_{h\rightarrow 0}\frac{f(x+h)-f(x)}{h}

上式表示x的微小变化将导致函数f(x)的值在多大程度上发生变化。但是这种数值微分法是有缺陷的,因为在Python中h不可能无限接近0,当h小的一定程度时就会出现舍入误差(rounding error)。为了减小这个误差,可以计算函数f在(x+h)和(x-h)之间的差分,由于是以x为中心计算左右两边的差分,所以也成为中心差分(而(x+h)和之间的差分成为前向差分)。

def numerical_diff(f, x):h = 1e-4 # 0.0001return (f(x+h) - f(x-h)) / (2*h)

这样Python实现代码是利用微小的差分求导数的,所以也叫数值微分(numerical differentiation)。

比如实现一个二次函数y=0.01x^{2}+0.1x的求导,分别在x=5和x=10处求切线。

# coding: utf-8
import numpy as np
import matplotlib.pylab as pltdef numerical_diff(f, x):h = 1e-4 # 0.0001return (f(x+h) - f(x-h)) / (2*h)def function_1(x):return 0.01*x**2 + 0.1*x def tangent_line(f, x):#画x点处的切线d = numerical_diff(f, x)print(d)y = f(x) - d*xreturn lambda t: d*t + y#返回一个t为自变量的函数x = np.arange(0.0, 20.0, 0.1)
y = function_1(x)
plt.xlabel("x")
plt.ylabel("f(x)")tf = tangent_line(function_1, 5)
y2 = tf(x)plt.plot(x, y)
plt.plot(x, y2, linestyle = "--", label="x=5")
plt.legend()
plt.show()

数值微分求的导数是有误差的,不是真的导数。想要求真的导数要通过数学式推导,也成为解析性求导,这样求出来的导数是不含误差的。

当求有多个变量的函数的导数时,就要使用偏导数。对哪个变量求导就固定住其他变量,以该变量求数值微分。比如对f(x_{0},x_{1})=x_{0}^{2}+x_{1}^{2}求偏导数(\frac{\partial f}{\partial x_{0}},\frac{\partial f}{\partial x_{1}})

# coding: utf-8
# cf.http://d.hatena.ne.jp/white_wheels/20100327/p3
import numpy as np
import matplotlib.pylab as plt
from mpl_toolkits.mplot3d import Axes3D
from matplotlib import cmdef _numerical_gradient_no_batch(f, x):h = 1e-4 # 0.0001grad = np.zeros_like(x)for idx in range(x.size):tmp_val = x[idx]x[idx] = float(tmp_val) + hfxh1 = f(x) # f(x+h)x[idx] = tmp_val - h fxh2 = f(x) # f(x-h)grad[idx] = (fxh1 - fxh2) / (2*h)x[idx] = tmp_val # 还原值return graddef numerical_gradient(f, X):if X.ndim == 1:return _numerical_gradient_no_batch(f, X)else:grad = np.zeros_like(X)for idx, x in enumerate(X):grad[idx] = _numerical_gradient_no_batch(f, x)return graddef function_2(x):if x.ndim == 1:return np.sum(x**2)else:return np.sum(x**2, axis=1)def tangent_line(f, x):d = numerical_gradient(f, x)print(d)y = f(x) - d*xreturn lambda t: d*t + yif __name__ == '__main__':x0 = np.arange(-2, 2.5, 0.25)x1 = np.arange(-2, 2.5, 0.25)X, Y = np.meshgrid(x0, x1)Z = X**2 + Y**2fig = plt.figure()ax = fig.add_subplot(111, projection='3d')ax.plot_surface(X, Y, Z, rstride=4, cstride=4, cmap=cm.YlGnBu_r)plt.show()X = X.flatten()Y = Y.flatten()grad = numerical_gradient(function_2, np.array([X, Y]) )plt.figure()plt.quiver(X, Y, -grad[0], -grad[1],  angles="xy",color="#666666")#,headwidth=10,scale=40,color="#444444")plt.xlim([-2, 2])plt.ylim([-2, 2])plt.xlabel('x0')plt.ylabel('x1')plt.grid()plt.legend()plt.draw()plt.show()

可以看到梯度呈现为有向向量,梯度指向函数的最低处(最小值),所有剪头指向同一点,并且离最低处越远剪头越大。

用数学式表示梯度法

x_{0}=x_{0}-\eta \frac{\partial f}{\partial x_0}

x_{1}=x_{1}-\eta \frac{\partial f}{\partial x_1}

\eta表示更新量,在神经网络中称为学习率 (learning rate) ,学习率决定在一次学习中应该学习多少,以及在多大程度上更新参数。学习率需要实现确定某个值,过大过小都无法抵达一个最小值,过大会发散成一个很大的值,过小的话没怎么更新就结束了。神经网络中一般都是边改变学习率的值变确认学习是否正确进行。像学习率这样的参数称为超参数,需要人工设定,因此需要尝试多个值。                                                                                             

对于神经网络求梯度是指损失函数关于权重参数的梯度。比如权重W的神经网络,损失函数L,梯度为\frac{\partial L}{\partial W},即

W=\begin{pmatrix} w11 &w12 &w13 \\ w21& w22 & w23 \end{pmatrix}

\frac{\partial L}{\partial W}=\begin{pmatrix} \frac{\partial L}{\partial W11} &\frac{\partial L}{\partial W12} &\frac{\partial L}{\partial W13} \\ \frac{\partial L}{\partial W21}&\frac{\partial L}{\partial W22} &\frac{\partial L}{\partial W23} \end{pmatrix}

# coding: utf-8
import numpy as npdef softmax(x):if x.ndim == 2:x = x.Tx = x - np.max(x, axis=0)y = np.exp(x) / np.sum(np.exp(x), axis=0)return y.T x = x - np.max(x) # 溢出对策return np.exp(x) / np.sum(np.exp(x))def numerical_gradient(f, x):h = 1e-4 # 0.0001grad = np.zeros_like(x)it = np.nditer(x, flags=['multi_index'], op_flags=['readwrite'])while not it.finished:idx = it.multi_indextmp_val = x[idx]x[idx] = float(tmp_val) + hfxh1 = f(x) # f(x+h)x[idx] = tmp_val - h fxh2 = f(x) # f(x-h)grad[idx] = (fxh1 - fxh2) / (2*h)x[idx] = tmp_val # 还原值it.iternext()   return graddef cross_entropy_error(y, t):if y.ndim == 1:t = t.reshape(1, t.size)y = y.reshape(1, y.size)# 监督数据是one-hot-vector的情况下,转换为正确解标签的索引if t.size == y.size:t = t.argmax(axis=1)batch_size = y.shape[0]return -np.sum(np.log(y[np.arange(batch_size), t] + 1e-7)) / batch_sizeclass simpleNet:def __init__(self):self.W = np.random.randn(2,3)def predict(self, x):return np.dot(x, self.W)def loss(self, x, t):z = self.predict(x)y = softmax(z)loss = cross_entropy_error(y, t)return lossx = np.array([0.6, 0.9])
t = np.array([0, 0, 1])net = simpleNet()f = lambda w: net.loss(x, t)
dW = numerical_gradient(f, net.W)print(dW)

这里以softmax为激活函数,交叉熵作为损失函数求关于权重的梯度。这里的权重是随机生成的,梯度采用数值微分的方法求解。

当训练数据庞大时,通常会随机选出一部分数据来求梯度,因此称为随机梯度下降法(stochastic gradient descent)。在很多深度学习的框架中,随机梯度下降法通常使用一个名为SGD的函数实现。

2、误差反向传播

使用计算图反向传播高效计算导数。反向传播的关键是链式法则,也就是复合函数求导,可以计算局部导数并传递。比如,z=(x+y)^{2}

z=t^{2}

\\ t=x+y

由上例可以推导出,加法节点的反向传播将上游传过来的导数原封不动的传给下游。

 左边为正向传播,右边为反向传播。

乘法节点的反向传播会将上游的值乘以正向传播时输入信号的“翻转值”后传递给下游。

 python代码实现

# coding: utf-8class MulLayer:def __init__(self):self.x = Noneself.y = Nonedef forward(self, x, y):self.x = xself.y = y                out = x * yreturn outdef backward(self, dout):dx = dout * self.ydy = dout * self.xreturn dx, dyclass AddLayer:def __init__(self):passdef forward(self, x, y):out = x + yreturn outdef backward(self, dout):dx = dout * 1dy = dout * 1return dx, dy

 

这篇关于梯度法有哪些?的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/625457

相关文章

✨机器学习笔记(二)—— 线性回归、代价函数、梯度下降

1️⃣线性回归(linear regression) f w , b ( x ) = w x + b f_{w,b}(x) = wx + b fw,b​(x)=wx+b 🎈A linear regression model predicting house prices: 如图是机器学习通过监督学习运用线性回归模型来预测房价的例子,当房屋大小为1250 f e e t 2 feet^

AI学习指南深度学习篇-带动量的随机梯度下降法的基本原理

AI学习指南深度学习篇——带动量的随机梯度下降法的基本原理 引言 在深度学习中,优化算法被广泛应用于训练神经网络模型。随机梯度下降法(SGD)是最常用的优化算法之一,但单独使用SGD在收敛速度和稳定性方面存在一些问题。为了应对这些挑战,动量法应运而生。本文将详细介绍动量法的原理,包括动量的概念、指数加权移动平均、参数更新等内容,最后通过实际示例展示动量如何帮助SGD在参数更新过程中平稳地前进。

AI学习指南深度学习篇-带动量的随机梯度下降法简介

AI学习指南深度学习篇 - 带动量的随机梯度下降法简介 引言 在深度学习的广阔领域中,优化算法扮演着至关重要的角色。它们不仅决定了模型训练的效率,还直接影响到模型的最终表现之一。随着神经网络模型的不断深化和复杂化,传统的优化算法在许多领域逐渐暴露出其不足之处。带动量的随机梯度下降法(Momentum SGD)应运而生,并被广泛应用于各类深度学习模型中。 在本篇文章中,我们将深入探讨带动量的随

什么是GPT-3的自回归架构?为什么GPT-3无需梯度更新和微调

文章目录 知识回顾GPT-3的自回归架构何为自回归架构为什么架构会影响任务表现自回归架构的局限性与双向模型的对比小结 为何无需梯度更新和微调为什么不需要怎么做到不需要 🍃作者介绍:双非本科大四网络工程专业在读,阿里云专家博主,专注于Java领域学习,擅长web应用开发,目前开始人工智能领域相关知识的学习 🦅个人主页:@逐梦苍穹 📕所属专栏:人工智能 🌻gitee地址:x

分布式训练同步梯度出现形状不一致的解决方案

1、问题描述           为了加快大模型的训练速度,采用了分布式训练策略,基于MultiWorkerServerStrategy模式,集群之间采用Ring—Reduce的通信机制,不同节点在同步梯度会借助collective_ops.all_gather方法将梯度进行汇聚收集,汇聚过程出现了: allreduce_1/CollectiveGather_1 Inconsitent out

【机器学习】梯度提升和随机森林的概念、两者在python中的实例以及梯度提升和随机森林的区别

引言 梯度提升(Gradient Boosting)是一种强大的机器学习技术,它通过迭代地训练决策树来最小化损失函数,以提高模型的预测性能 随机森林(Random Forest)是一种基于树的集成学习算法,它通过组合多个决策树来提高预测的准确性和稳定性 文章目录 引言一、梯度提升1.1 基本原理1.1.1 初始化模型1.1.2 迭代优化1.1.3 梯度计算1.1.4模型更新 1.2

jmeter 梯度测试 如何查看TPS、RT指标

TPS= 服务器处理请求总数/花费的总时间 149371 (请求量)÷ 113(1分53秒)=1321/秒 跟汇总报告的吞吐量差不多,可以认为吞吐量=TPS 平均值,中位数,最大值,最小值的单位都是毫秒ms 下载插件梯度插件 https://jmeter-plugins.org/install/Install/ 插件管理器的jar包下载好以后,我们需要把jar包放在lib\ext目录下边

mllib之随机森林与梯度提升树

随机森林和GBTs都是集成学习算法,它们通过集成多棵决策树来实现强分类器。 集成学习方法就是基于其他的机器学习算法,并把它们有效的组合起来的一种机器学习算法。组合产生的算法相比其中任何一种算法模型更强大、准确。 随机森林和梯度提升树(GBTs)。两者之间主要差别在于每棵树训练的顺序。 随机森林通过对数据随机采样来单独训练每一棵树。这种随机性也使得模型相对于单决策树更健壮,且不易在

基于Python的机器学习系列(26):PyTorch中的梯度计算

在本篇中,我们将探讨PyTorch的autograd功能,它为张量操作提供自动微分。我们将学习如何使用torch.autograd工具计算梯度并进行反向传播。 自动微分(Autograd)         PyTorch的autograd包自动计算张量的梯度。当一个张量的.requires_grad属性被设置为True时,PyTorch会追踪该张量的所有操作。在计算完成后,您可

AI学习指南深度学习篇-随机梯度下降法(Stochastic Gradient Descent,SGD)简介

AI学习指南深度学习篇-随机梯度下降法(Stochastic Gradient Descent,SGD)简介 在深度学习领域,优化算法是至关重要的一部分。其中,随机梯度下降法(Stochastic Gradient Descent,SGD)是最为常用且有效的优化算法之一。本篇将介绍SGD的背景和在深度学习中的重要性,解释SGD相对于传统梯度下降法的优势和适用场景,并提供详细的示例说明。 1.