• 作者:老汪软件技巧
  • 发表时间:2024-08-29 07:02
  • 浏览量:

0 前言:

在这一章节中我们会介绍一些基础的深度学习优化概念

1.局部极小值与鞍点:判断与逃离1.1:鞍点与极小值

有时候有人会将深度学习的过程戏称为“调参”,但是在某些时候,我们会发现我们不论如何更新参数,训练的损失就不会再下降了。

此时我们可以做一猜想,我们在优化到某个地方的时候 这个地方对损失的微分为0(也就是损失不再变化)。就好像下图所示的一样。

这种情况下,梯度为0),该点也被称为临界点。在这个时候我们需要考虑损失的三种情况

局部极小值:梯度下降已经失效了(模型已经收敛于临界点)

鞍点:可以通过某些方法来逃离,这里鞍点的形状决定了其仍然有路径可以使得损失变得更低,也坑在某个地方更高

那么此时摆在我们面前的问题就变为了我们如何判断这个点是局部极小值点亦或者是鞍点,这里我们简单介绍一下判断的方法(其实就是一堆公式)

泰勒级数近似:

损失函数 L(θ)L(\theta)L(θ) 在某点 θ′\theta'θ′ 附近可以用泰勒级数近似:

L(θ)≈L(θ′)+(θ−θ′)Tg+12(θ−θ′)TH(θ−θ′)L(\theta) \approx L(\theta') + (\theta - \theta')^T g + \frac{1}{2} (\theta - \theta')^T H (\theta - \theta')L(θ)≈L(θ′)+(θ−θ′)Tg+21​(θ−θ′)TH(θ−θ′)

在临界点:

L(θ)≈L(θ′)+12(θ−θ′)TH(θ−θ′)L(\theta) \approx L(\theta') + \frac{1}{2} (\theta - \theta')^T H (\theta - \theta')L(θ)≈L(θ′)+21​(θ−θ′)TH(θ−θ′)

判断临界点类型:

vTHvv^T H vvTHv

特征值判断:

我们可以上个简单的代码来表示这个过程

import numpy as np
# 定义损失函数及其梯度和海森矩阵
def loss_function(theta):
    # 示例损失函数
    return (1 - theta[0] * theta[1]) ** 2
def gradient(theta):
    # 计算梯度
    w1, w2 = theta
    grad_w1 = -2 * (1 - w1 * w2) * w2
    grad_w2 = -2 * (1 - w1 * w2) * w1
    return np.array([grad_w1, grad_w2])
def hessian(theta):
    # 计算海森矩阵
    w1, w2 = theta
    h11 = 2 * w2 * w2
    h12 = -2 + 4 * w1 * w2
    h21 = -2 + 4 * w1 * w2
    h22 = 2 * w1 * w1
    return np.array([[h11, h12], [h21, h22]])
import numpy as np
# 定义损失函数及其梯度和海森矩阵
def loss_function(theta):
    # 示例损失函数
    return (1 - theta[0] * theta[1]) ** 2
def gradient(theta):
    # 计算梯度
    w1, w2 = theta
    grad_w1 = -2 * (1 - w1 * w2) * w2
    grad_w2 = -2 * (1 - w1 * w2) * w1
    return np.array([grad_w1, grad_w2])
def hessian(theta):
    # 计算海森矩阵
    w1, w2 = theta
    h11 = 2 * w2 * w2
    h12 = -2 + 4 * w1 * w2
    h21 = -2 + 4 * w1 * w2
    h22 = 2 * w1 * w1
    return np.array([[h11, h12], [h21, h22]])
# 判断临界点类型
def check_critical_point(theta):
    H = hessian(theta)
    eigenvalues = np.linalg.eigvals(H)
    
    if all(eigenvalues > 0):
        return "局部极小值"
    elif all(eigenvalues < 0):
        return "局部极大值"
    else:
        return "鞍点"
# 示例参数
theta = np.array([0, 0])
# 计算梯度和海森矩阵
grad = gradient(theta)
H = hessian(theta)
print("梯度:", grad)
print("海森矩阵:\n", H)
print("临界点类型:", check_critical_point(theta))

1.2 一个简单网络的例子:

在这个神经元的例子中,我们研究一个简单的神经网络模型的优化问题。这里的神经网络如下图所示:

网络结构数据集损失函数

我们可以看看其误差表面

梯度和海森矩阵

梯度:

海森矩阵:

临界点分析

此时我们已经可以判断基本的鞍点了,这里还有一个问题,我们到底是局部最小点更多呢?还是鞍点更多。

这个答案我们需要通过升维来解决

这里我们可以看到一个一维度的误差表面,在这个表面上,我们得到的是一个局部最小值

但是我们不妨思考这么一个问题:这个一维的误差表面是否可能是某个二维误差表面的低维表示?或者换句话说,这个一维误差表面有没有可能是一个鞍点呢?答案当然是肯定的。

我们继续把这个例子推广到更加高维的情况(也就对应更加复杂的误差表面)

这里我们很容易做一个推导,在有参数量成千上万的网络中,维度是很高的(这里的参数量等同于维度)局部极小值的情况其实非常少,大部分实践都有很多的下降路径可走。

这里我们定义一个公式:最小值比例

我们可以观察到

由此可见,大部分时候我们还是多是遇到鞍点。