网站公告: 诚信为本,市场在变,诚信永远不变...
400-123-4657

24小时全国服务热线

400-123-4657

如果您有任何疑问或是问题, 请随时与我们联系

查看联系方式>>
行业资讯 当前位置: 首页 > 世纪动态 > 行业资讯

智能优化算法vs数学优化

作者:佚名    时间:2024-04-22 14:28:49

梯度下降和遗传算法的应用场景不同。梯度下降适用于求解可导函数的最优解,而遗传算法适用于求解非可导函数的最优解。在实际应用中,根据具体问题的特点,选择合适的优化算法可以提高模型的准确性和效率。

智能优化算法

遗传算法是一种模拟生物进化过程的优化算法,目标是通过模拟自然选择和遗传机制,不断迭代生成适应度更高的个体。在遗传算法中,每个个体都有一组基因,每次迭代中,通过交叉、变异和选择等操作,生成新的基因组合,以期望找到全局最优解。遗传算法的优点是可以在复杂的、高维的非线性问题中找到全局最优解,但它需要较长的时间和更多的计算资源。

遗传算法,还有粒子群算法,蚁群算法等等为代表的智能算法(也被称为进化计算),本质来说是单纯仅依靠对目标函数进行采样,然后通过一定的机制(不同的智能算法其搜索机制不一样)来达到群体的随机搜索的一类方法。

数学优化算法

梯度下降是一种基于求解函数梯度的优化算法,目标是通过不断迭代调整模型参数,使得损失函数最小化。在每次迭代中,通过计算当前点的梯度方向来更新参数,以期望找到全局最优解。梯度下降算法的优点是收敛速度快,但它需要满足函数是可导的前提条件,并且对于复杂的非凸函数,容易陷入局部最优解。
梯度类算法属于传统数学优化的范畴,主要采用目标函数梯度作为搜索方向或者根据梯度来构造搜索方向。

遗传算法的初衷:仅依靠采样目标函数的随机搜索
你回到遗传算法被发明的初衷:在于不依赖优化对象的模型,也就是说我是无需知道优化目标函数长啥样的,完全就靠采样就可以了。这么做的好处是对于黑箱一类的优化问题或者目标函数和目标函数梯度难以获得的优化问题来讲,此类算法有一定的优势。如果我比较容易能获得目标函数的梯度的话,那其实已经在很大程度上没有必要用遗传算法了。
遗传算法的优势其实也就是它的劣势,由于没有过多引入优化问题本身的信息(仅仅依靠对目标函数采样的信息)去设计算法。简单来说就是对什么问题都能用的算法,那一定对特定某一类问题效果不好。这一点非常符合 No Free Lunch 。
相对来说梯度类算法需要知道目标函数具体表达式才行,同时还要求目标函数最起码是可微的那才有梯度吧。虽说这些条件一方面是限制了算法应用的范围,另外一方面反过来说明了梯度类算法引入了更多关于优化问题本身的信息来辅助算法搜索。

遗传算法和梯度类算法(数学优化)对比
1求解效果
对问题结构明确能够容易获得目标梯度的优化问题,有充分的关于优化问题的信息来利用的时候梯度类算法一般来说有优势,例如梯度类算法,线性规划,二次规划凸优化等等在业界的应用都非常广泛。反之,可能使用遗传算法就会有优势。对于一些传统数学优化目前不能彻底解决的问题例如NP hard问题,遗传算法也有一定的应用前景。此时遗传算法也需要更多的利用特定问题的结构去设计特定的算法才能够提升算法的能力。
2求解速率
遗传算法的计算速度比较慢这一点也很好理解,每迭代一次都需要计算M次目标函数,M是种群规模一般是30-50左右。遗传算法的前沿的研究方向其中一个就是针对大规模优化问题的(large-scale),我也曾查阅过相关顶级期刊的论文发现进化算法里的large-scale的规模,一般决策变量几千维就是large-scale的了。对数学优化算法来讲可能根本构不成large-scale。而实际问题中经常决策变量达到几百万以上的规模,此时遗传算法的缺点就被暴露了。所以侧面反应出了遗传算法在计算速度的瓶颈限制了其在大规模优化问题上的应用。
3理论性保证
目前对于遗传算法的理论性分析还停留在一个很初级的阶段,虽然有用随机过程(马尔科夫性)的方法来证明进化算法依概率收敛到最优解,但一般而言这类理论分析停留在 马尔可夫链证明的全局收敛性,当算法运行时间趋于无穷的时候,依概率1趋于全局最优。这个理论分析的结果聊胜于无吧。因为实际上在运行算法的时候没有人把运行时间设置为无穷大,而且何时停止搜索也不知道(因为缺乏最优性判定准则)。同时依概率1收敛的条件本身就非常弱,哪怕是完全随机搜索其实也都一样可以满足上面的收敛性条件。所以很多时候遗传算法说自己能收敛到全局最优也就成了一个美好的梦想。
遗传算法等进化计算方法主要适应场景
我列了一下目前以遗传算法为代表的进化算法方法主要的适用场景:
场景1: 神经网络参数优化
场景2: 一部分结构和特性固定的组合优化问题
场景3: 一部分机理模型难以建立的黑箱优化问题
场景4: 多目标优化问题
除了以上场景你可以认为基本上就是数学优化(梯度类)算法的天下了。以上场景大致有两种情况一种是优化问题的模型是黑箱,梯度难以求得,例如场景1,场景2,场景3都属于这种情况。另外一种就是目前传统数学优化还不能很好解决的问题,例如场景 2,场景4 都属于这种情况。所以总得来说目前遗传算法为代表的进化计算方法主要还是捡数学优化的漏。一般我们会优先考虑数学优化方法,当数学优化解决不了的时候再考虑遗传算法。当一类问题采用遗传算法时基本上代表这是没有办法的办法了。
综上所述,进化算法也好,数学优化也好都只是认识问题解决问题的工具之一,工具本身并不存在绝对的优劣之分,每种工具都有其适用的场景,辨别它们的长短,找到它们合适的应用场景是我们这些用工具的人应该做的。

  1. 定义问题

1.1 模型:此模型可以是公式、也可以是机器学习模型。

1.2 目标函数:给模型输入X和参数,得到模型预测Y,使预测Y和实际Y残差最小、或者使预测Y最小。

2. 使用优化算法求解

NSGA2代码示例:

# 导入NAGA2库
import naga2

# 定义目标函数
def objective_function(params):
    # params是一个字典类型,包含了所有需要优化的参数
    x=params['x']
    y=params['y']
    z=params['z']
    # 计算目标函数值
    result=x**2 + y**2 + z**2
    # 返回函数值
    return result

# 定义参数空间
parameter_space={
    'x': naga2.Parameter(-10, 10),
    'y': naga2.Parameter(-10, 10),
    'z': naga2.Parameter(-10, 10)
}

# 定义优化器
optimizer=naga2.Optimizer(objective_function, parameter_space)

# 进行优化
best_params, best_value=optimizer.optimize()

# 输出最优参数和函数值
print('Best params:', best_params)
print('Best value:', best_value)

在以上代码中,我们首先定义了一个目标函数objective_function,该函数接受一个字典类型的参数params,并计算在该参数下的函数值。然后我们定义了一个参数空间parameter_space,其中包含了所有需要优化的参数的取值范围。接着,我们使用这些定义好的参数创建了一个优化器optimizer,并使用该优化器进行目标优化。最后,我们输出了最优参数best_params和最优函数值best_value。

请注意,以上代码仅为示例,实际使用NAGA2进行目标优化需要根据具体情况进行修改和调整。

黑箱模型往往不能直接求导,因为无法获得系统内部的具体运行信息。

在机器学习中,很多时候我们使用的是黑箱模型,也就是说我们无法直接得到这个模型的梯度,因此需要采用一些特殊的方法来求解,包括以下几种:

  1. 数值微分法(Numerical Differentiation):通过计算函数在某一点处的近似导数值来得到梯度。这种方法简单易行,但相对于其他方法而言,计算效率较低,容易出现误差。
  2. 自动微分法(Automatic Differentiation):通过对函数进行解析,分离每个自变量对函数值的贡献,然后对每个自变量进行求导得到梯度。这种方法准确度非常高,而且计算效率也很高,但需要对函数进行解析,因此有一定难度。
  3. 反向传播法(Backpropagation):在神经网络中非常常见的方法,通过计算网络中每个节点的偏导数,然后沿着网络的反向传递,最终得到整个网络的梯度。这种方法是一种特殊的自动微分法,准确度和计算效率都很高。

中心差分法

中心差分法是一种数值微分方法,用于计算函数在某点处的导数。它通过计算函数在点左右两侧的差分来估计导数值,具有较高的精度和稳定性。

import numpy as np

def numerical_gradient(f, x, h=1e-5):
    """
    计算函数f在点x处的梯度,使用中心差分法
    f: 待计算梯度的函数
    x: 梯度计算点
    h: 步长
    """
    grad=np.zeros_like(x) # 梯度向量初始化
    for i in range(x.size):
        # 对第i个自变量使用中心差分法计算偏导数
        tmp=x[i]
        x[i]=tmp + h
        f1=f(x)
        x[i]=tmp - h
        f2=f(x)
        grad[i]=(f1 - f2) / (2*h)
        # 恢复第i个自变量的值
        x[i]=tmp
    return grad

# 示例函数:f(x,y)=x^2 + y^2
def f(x):
    return x[0]**2 + x[1]**2

# 计算函数f在点x=(1,2)处的梯度
x=np.array([1.0, 2.0])
grad=numerical_gradient(f, x)
print("grad_f({})={}".format(x, grad))

输出:

grad_f([1. 2.])=[2. 4.]

说明:在该示例中,我们定义了一个名为numerical_gradient的函数,用于计算任意给定多变量函数在任意给定点的梯度。f参数是待计算梯度的函数,x参数是梯度计算点,h参数是步长,默认值为1e-5,可以根据需要进行调整。函数内部对每个自变量使用中心差分法计算偏导数,并组合成梯度向量,最后返回结果。最后,我们定义了一个示例函数f(x,y)=x^2 + y^2,并计算该函数在点x=(1,2)处的梯度,结果为[2.0, 4.0]。

【返回列表页】
版权所有:Copyright © 2002-2017 首页-世纪娱乐-世纪商务站 版权所有电话:400-123-4657地址:广东省广州市天河区88号
ICP备案编号:粤IP**********

平台注册入口