一文搞懂非线性优化(python)

介绍

非线性优化是应用数学和工程学中的一个重要领域,专注于优化受约束的非线性目标函数。本文概述了非线性优化的理论、算法和实际应用,特别是使用 Python。

目录

介绍

什么是非线性规划?

非线性规划中的关键概念

什么是混合整数非线性规划?

MINLP 的关键组件

MINLP 的求解技术

为什么非线性规划很重要?

关键概念

好处

非线性规划示例

小非线性规划问题

不可行非线性规划问题

无界非线性规划问题

资源分配问题

非线性规划 Python 实现

安装 SciPy

使用 SciPy

1.Rosenbrock函数

2. 球面函数

3.

4. Beale 函数

5.二次规划问题

结论

什么是非线性规划?

非线性规划 (NLP) 是数学优化领域,其中目标函数或任何约束都是非线性的。这与线性规划形成对比,线性规划中的目标函数和约束都是线性的。由于可能存在局部最优、非凸性以及目标函数和约束的复杂性,非线性规划问题可能更复杂且更难解决。

非线性规划中的关键概念

  • 目标函数:您想要优化(最大化或最小化)的函数。在非线性规划中,此函数是非线性的,这意味着它在绘制时不会形成直线。

  • 约束:这些是解决方案可行的必须满足的条件。在 NLP 中,约束也可能是非线性的,这增加了问题的复杂性。

  • 可行区域:满足约束的所有点的集合。在非线性规划中,此区域可能很复杂且不规则。

  • 局部最优与全局最优:局部最优是一种比邻近解决方案更好的解决方案,但不一定是整体上最好的解决方案。全局最优是所有可行解决方案中最好的解决方案。非线性问题可以有多个局部最优,因此很难找到全局最优。

  • 凸性:如果目标函数是凸的,并且可行域是凸集,则问题为凸问题。凸问题通常更容易解决,因为任何局部最优也是全局最优。不满足这些条件的非凸问题更难解决。

算法:各种算法用于解决非线性规划问题,包括:

梯度下降:利用目标函数的梯度来寻找最小值的迭代方法。

牛顿法:使用二阶导数比梯度下降更有效地寻找最优解。

内点法:通过在优化过程中考虑约束来处理约束。

遗传算法:利用自然选择和遗传原理寻找最佳解决方案。

什么是混合整数非线性规划?

混合整数非线性规划 (MINLP) 是一种结合了整数规划和非线性规划的优化问题。它涉及优化受约束的非线性目标函数,其中一些决策变量被限制为整数值,而其他决策变量可以是连续的。这种类型的问题比单独的整数规划或非线性规划更复杂。

MINLP 的关键组件

  • 目标函数:您想要最大化或最小化的非线性函数。非线性特性使得寻找最优解变得具有挑战性。

  • 约束:这些是解决方案必须满足的方程或不等式。约束可以是线性的或非线性的,可能涉及整数和连续变量。

  • 整数变量:被限制为整数值的决策变量。这些变量通常用于表示离散选择,例如是否建造设施,或者生产多少单位的产品。

  • 连续变量:决策变量,可以在给定范围内取任意值。这些变量通常用于表示可以平稳变化的数量,例如生产水平或资源分配。

  • 混合整数性质:该问题涉及整数和连续变量,这增加了解决过程的复杂性。整数约束引入了组合方面,可以显著增加问题的难度。

MINLP 的求解技术

  • 分支定界法:一种解决整数规划问题的通用方法,可适用于 MINLP。它系统地探索决策树的分支,并使用边界来消除次优解决方案。

  • 分支裁剪法:分支定界法的扩展,结合切割平面来细化可行区域并提高效率。

  • 外部近似:将 MINLP 分解为一系列更简单的子问题,通常是线性和非线性规划的混合,并通过迭代方式进行求解。

  • 顺序凸规划:涉及解决原始非凸问题的一系列凸近似。

  • 元启发式方法:遗传算法、模拟退火或粒子群优化等技术可以在合理的时间范围内提供良好的解决方案,尽管它们不能保证最优性。

为什么非线性规划很重要?

非线性规划很重要,因为许多现实世界的问题本质上都是非线性的。它允许更准确地建模和解决各个领域的复杂问题。

关键概念

复杂性:非线性问题通常比线性模型更好地反映现实世界的复杂性。

优化:在简单线性模型失效的情况下,提供一种寻找最优解决方案的方法。

好处

  • 精确建模:捕捉复杂系统的真实本质。

  • 广泛适用性:用于工程、经济学和机器学习等不同领域。

  • 效率:帮助在给定的约束条件下找到最佳的解决方案。

非线性规划示例

小非线性规划问题

例子 :

import numpy as npfrom scipy.optimize import minimize
# Define the objective functiondef objective_function(x):    return x[0]**2 + x[1]**2 + x[0]*x[1]
# Define the constraintsconstraints = ({'type': 'eq', 'fun': lambda x: x[0] + x[1] - 1})
# Initial guessx0 = np.array([0.5, 0.5])
# Perform the optimizationresult = minimize(objective_function, x0, constraints=constraints)
print('Optimal value:', result.fun)print('Optimal solution:', result.x)​​​
Optimal value: 0.75Optimal solution: [0.5 0.5]

不可行非线性规划问题

例子 :

constraints = ({'type': 'eq', 'fun': lambda x: x[0] + x[1] - 3})result = minimize(objective_function, x0, constraints=constraints)print('Message:', result.message)print('Success:', result.success)​​​​​
Message: Optimization terminated successfullySuccess: True

无界非线性规划问题

例子 :​​​​​​​

def objective_function_unbounded(x):    return -x[0]**2 - x[1]**2
constraints = ({'type': 'eq', 'fun': lambda x: x[0] + x[1] - 1})result = minimize(objective_function_unbounded, x0, constraints=constraints)print('Message:', result.message)print('Success:', result.success)​​​​​​
Message: Optimization terminated successfullySuccess: True

资源分配问题

例子 :​​​​​​​

from scipy.optimize import linprog
c = [-1, -2]A = [[1, 2], [3, 4]]b = [4, 10]x0_bounds = (0, None)x1_bounds = (0, None)
res = linprog(c, A_ub=A, b_ub=b, bounds=[x0_bounds, x1_bounds], method='highs')print('Optimal value:', res.fun)print('Optimal solution:', res.x)​​​​​​​
Optimal value: -4.0Optimal solution: [0. 2.]

非线性规划 Python 实现

安装 SciPy

要开始使用 Python 进行非线性规划,您需要安装必要的库。SciPy 和 PuLP 是两个广泛用于优化问题的库。

使用 pip 安装它们:

pip install scipy

使用 SciPy

SciPy 提供了多种优化算法,可用于解决非线性规划 (NLP) 问题。下面是使用 SciPy 解决非线性优化问题的示例。

1.Rosenbrock函数

具有狭窄弯曲谷值的函数用于测试优化算法。

问题陈述:最小化 Rosenbrock 函数,这是优化算法的常见测试问题。

目标函数: f(x, y) = (a — x)² + b(y — x²)²​​​​​​​

import numpy as np import matplotlib.pyplot as plt from scipy.optimize import minimal from mpl_toolkits.mplot3d import Axes3D 
# 目标函数def  rosenbrock ( vars ):     x, y = vars     a, b = 1 , 100     return (a - x)** 2 + b * (y - x** 2 )** 2 
# 初始猜测initial_guess = [ 0 , 0 ] 
# 执行优化result = minimal(rosenbrock, initial_guess) 
# 提取结果x_opt, y_opt = result.x optimal_value = rosenbrock(result.x) 
# 打印结果print ( f"x 的最佳值:{x_opt} " ) print ( f"y 的最佳值:{y_opt} " ) print ( f"Rosenbrock 函数的最小值:{optimal_value} " ) 
# 绘图x = np.linspace(- 2 , 2 , 100 ) y = np.linspace(- 1 , 3 , 100 ) X, Y = np.meshgrid(x, y) Z = rosenbrock([X, Y]) 
# 3D 表面图fig = plt.figure(figsize=( 14 , 8 )) ax = fig.add_subplot( 111 , projecting= '3d' ) ax.plot_surface(X, Y, Z, cmap= 'viridis' , edgecolor= 'none' ) ax.scatter(x_opt, y_opt, optimal_value, color= 'red' , s= 50 , label= '最佳解决方案' ) ax.set_xlabel( 'x' ) ax.set_ylabel( 'y' ) ax.set_zlabel( '目标函数值' ) ax.set_title( 'Rosenbrock 函数的 3D 曲面图' ) ax.legend() 
plt.show()

图片

2. 球面函数

通常使用简单的二次函数来检查优化性能。

问题陈述:最小化球体函数,这是一个用于优化的简单测试函数。

目标函数: f(x,y)= x² + y²​​​​​​​

# 目标函数def  sphere_function ( vars ):     x, y = vars     return x** 2 + y** 2 
# 初始猜测initial_guess = [ 1 , 1 ] 
# 执行优化result = minimal(sphere_function, initial_guess) 
# 提取结果x_opt, y_opt = result.x optimal_value = sphere_function(result.x) 
# 打印结果print ( f"x 的最佳值:{x_opt} " ) print ( f"y 的最佳值:{y_opt} " ) print ( f"Sphere 函数的最小值:{optimal_value} " ) 
# 绘图x = np.linspace(- 2 , 2 , 100 ) y = np.linspace(- 2 , 2 , 100 ) X, Y = np.meshgrid(x, y) Z = sphere_function([X, Y]) 
# 3D 表面图fig = plt.figure(figsize=( 14 , 8 )) ax = fig.add_subplot( 111 , projecting= '3d' ) ax.plot_surface(X, Y, Z, cmap= 'viridis' , edgecolor= 'none' ) ax.scatter(x_opt, y_opt, optimal_value, color= 'red' , s= 50 , label= '最佳解决方案' ) ax.set_xlabel( 'x' ) ax.set_ylabel( 'y' ) ax.set_zlabel( '目标函数值' ) ax.set_title( '球体函数的 3D 表面图' ) ax.legend() 
plt.show()

图片

3.

具有多个局部最小值的函数测试优化算法寻找全局最小值的能力。

问题陈述:最小化 Himmelblau 函数,该函数具有多个局部最小值。

目标函数: f(x,y)=(x²+ y — 11)²+(x + y² — 7)²​​​​​​​

# 目标函数def  himmelblau ( vars ):     x, y = vars     return (x** 2 + y - 11 )** 2 + (x + y** 2 - 7 )** 2 
# 初始猜测initial_guess = [ 0 , 0 ] 
# 执行优化result = minimal(himmelblau, initial_guess) 
# 提取结果x_opt, y_opt = result.x optimal_value = himmelblau(result.x) 
# 打印结果print ( f"x 的最佳值:{x_opt} " ) print ( f"y 的最佳值:{y_opt} " ) print ( f"Himmelblau 函数的最小值:{optimal_value} " ) 
# 绘图x = np.linspace(- 5 , 5 , 100 ) y = np.linspace(- 5 , 5 , 100 ) X, Y = np.meshgrid(x, y) Z = himmelblau([X, Y]) 
# 3D 表面图fig = plt.figure(figsize=( 14 , 8 )) ax = fig.add_subplot( 111 , projecting= '3d' ) ax.plot_surface(X, Y, Z, cmap= 'viridis' , edgecolor= 'none' ) ax.scatter(x_opt, y_opt, optimal_value, color= 'red' , s= 50 , label= '最佳解决方案' ) ax.set_xlabel( 'x' ) ax.set_ylabel( 'y' ) ax.set_zlabel( '目标函数值' ) ax.set_title( 'Himmelblau 函数的 3D 表面图' ) ax.legend() 
plt.show()

图片

4. Beale 函数

具有多个局部最小值的函数,对于优化算法来说具有挑战性。

问题陈述:最小化 Beale 函数,另一个具有多个局部最小值的测试函数。

目标函数: f(x,y)=(1.5 — x + xy)² +(2.25 — x + xy²)² +(2.625 — x + xy³)²​​​​​​​

# 目标函数def  beale ( vars ):     x, y = vars     return ( 1.5 - x + x * y)** 2 + ( 2.25 - x + x * y** 2 )** 2 + ( 2.625 - x + x * y** 3 )** 2 
# 初始猜测initial_guess = [ 1 , 1 ] 
# 执行优化result = minimal(beale, initial_guess) 
# 提取结果x_opt, y_opt = result.x optimal_value = beale(result.x) 
# 打印结果print ( f"x 的最佳值:{x_opt} " ) print ( f"y 的最佳值:{y_opt} " ) print ( f"Beale 函数的最小值:{optimal_value} " ) 
# 绘图x = np.linspace(- 4 , 4 , 100 ) y = np.linspace(- 4 , 4 , 100 ) X, Y = np.meshgrid(x, y) Z = beale([X, Y]) 
# 3D 表面图fig = plt.figure(figsize=( 14 , 8 )) ax = fig.add_subplot( 111 , projecting= '3d' ) ax.plot_surface(X, Y, Z, cmap= 'viridis' , edgecolor= 'none' ) ax.scatter(x_opt, y_opt, optimal_value, color= 'red' , s= 50 , label= '最优解' ) ax.set_xlabel( 'x' ) ax.set_ylabel( 'y' ) ax.set_zlabel( '目标函数值' ) ax.set_title( '3D 表面图Beale 函数' ) ax.legend() 
plt.show()

图片

5.二次规划问题

具有线性约束的二次函数演示了如何处理优化中的约束。

问题陈述:最小化受线性约束的二次函数。

目标函数: f(x,y)= x² + 2xy + y²

约束:
x+y≥1
x−y≥0​​​​​​​

from scipy.optimize import minimal, LinearConstraint 
# 目标函数def  quadratic_function ( vars ):     x, y = vars     return x** 2 + 2 *x*y + y** 2 
# 约束def  constrain1 ( vars ):     x, y = vars     return x + y - 1 
def  constrain2 ( vars ):     x, y = vars     return x - y 
# 定义约束constrains = [     { 'type' : 'ineq' , 'fun' : constrain1},     { 'type' : 'ineq' , 'fun' : constrain2} ] 
# 初始猜测initial_guess = [ 0 , 0 ] 
# 执行优化result = minimal(quadratic_function, initial_guess,constraints=constraints) 
# 提取结果x_opt, y_opt = result.x optimal_value = quadratic_function(result.x) 
# 打印结果print ( f"x 的最佳值:{x_opt} " ) print ( f"y 的最佳值:{y_opt} " ) print ( f"二次函数的最小值:{optimal_value} " ) 
# 绘图x = np.linspace(- 1 , 2 , 100 ) y = np.linspace(- 1 , 2 , 100 ) X, Y = np.meshgrid(x, y) Z = quadratic_function([X, Y]) 
# 3D 表面图fig = plt.figure(figsize=( 14 , 8 )) ax = fig.add_subplot( 111 , projecting= '3d' ) ax.plot_surface(X, Y, Z, cmap= 'viridis' , edgecolor= 'none' ) ax.scatter(x_opt, y_opt, optimal_value, color= 'red' , s= 50 , label= '最优解' ) ax.set_xlabel( 'x' ) ax.set_ylabel( 'y' ) ax.set_zlabel( '目标函数值' ) ax.set_title('二次函数的 3D 曲面图' ) ax.legend() 
plt.show()

图片

结论

非线性规划优化是一种功能强大且用途广泛的工具,可用于解决变量之间关系非线性的复杂现实问题。它超越了线性优化的能力,允许对系统进行更复杂、更现实的建模,同时适应非线性目标函数和约束。通过各种技术和算法(例如梯度下降和进化算法),非线性优化可以在工程、经济学和机器学习等具有挑战性的多样化领域中找到最佳解决方案。

### Transformer编码器工作原理 #### 编码器架构概述 Transformer模型中的编码器由多个相同的层堆叠而成。每一层主要包含两个子层:一个多头自注意力机制(Multi-head Self-Attention Mechanism),以及一个全连接前馈网络(Feed Forward Network)。这些组件共同作用来处理输入数据并生成上下文感知的特征向量[^1]。 #### 多头自注意力机制 多头自注意力允许模型在不同的位置上关注输入的不同部分,从而捕捉到更丰富的语义信息。具体来说,在每个多头自注意单元内部,会计算查询键值三元组(Q,K,V),并通过矩阵运算得到加权求和的结果作为输出。此过程可以理解为对同一句话里的各个单词之间相互影响程度的一种量化描述。 为了增强表达能力,实际应用中通常采用多个平行运行的小型自注意力模块——即所谓的“头部”,最后再把这些头部产生的结果拼接起来形成最终输出。这种设计使得模型能够同时学习不同类型的关联模式[^2]。 ```python import torch.nn as nn class MultiHeadSelfAttention(nn.Module): def __init__(self, d_model, num_heads): super(MultiHeadSelfAttention, self).__init__() assert d_model % num_heads == 0 self.d_k = d_model // num_heads self.num_heads = num_heads # 定义线性变换参数WQ,WK,WV用于产生q,k,v ... def forward(self, Q, K, V, mask=None): ... ``` #### 前馈神经网络(FFN) 紧跟其后的是一系列两层的全连接层组成的前馈神经网络。它接收来自前面一层经过归一化之后的数据,并通过激活函数引入非线性特性。值得注意的是,这里的权重在整个序列长度维度上共享,意味着对于同一个时间步内的所有元素都施加相同的操作。 ```python class FeedForwardNetwork(nn.Module): def __init__(self, d_model, hidden_size): super(FeedForwardNetwork, self).__init__() self.linear_1 = nn.Linear(d_model, hidden_size) self.relu = nn.ReLU() self.linear_2 = nn.Linear(hidden_size, d_model) def forward(self, x): return self.linear_2(self.relu(self.linear_1(x))) ``` #### 层规范化与残差连接 除了上述核心部件外,还有一个非常重要的细节就是加入了Layer Normalization 和 Residual Connection 。前者有助于加速训练收敛速度;后者则能有效缓解深层网络可能出现的信息传递衰减问题,确保梯度稳定流动。 ![transformer_encoder](https://miro.medium.com/max/784/1*ZvYbJjzX9hLgUOaPmDyGGA.png)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值