使用 Python 的 SPSA(同时扰动随机近似)算法
同时扰动随机优化算法 (SPSA) 通过同时扰动目标函数来找到目标函数的最小值。
使用 SPSA,通过评估随机扰动下的少量函数来估计目标函数梯度。当目标函数有噪声、不可微分或具有许多参数时,它特别有用。
此算法已成功实现了各种应用,例如系统识别、控制和机器学习。
使用 SPSA 算法的优势
SPSA 已应用于工程、金融和机器学习等各个领域。与其他优化算法(例如随机梯度下降和梯度下降)相比,它具有多种优势,
其中一些优势是 −
减少计算和内存需求
处理非平滑和噪声函数
不需要导数
它能够处理大型参数空间
该算法可用于通过优化权重和偏差来有效地训练深度神经网络。此外,SPSA 还可用于金融领域,例如优化股票、债券和其他金融工具的投资组合。
算法
步骤 1 - 导入 numpy 库并定义任何函数以应用 SPSA 算法来优化/最小化函数
步骤 2 − 使用一些初始值初始化输入变量(参数)。
步骤 3 − 选择迭代次数和步骤大小。
步骤 4 − 使用函数评估之间的差异,估计目标函数的梯度。
步骤 5 − 使用估计的梯度更新输入变量以最小化目标函数。
步骤 6 − 返回最佳参数值和对应的损失值。
第 7 步 − 重复第 3 步至第 5 步,直至收敛。
示例
在下面的代码中,我们使用了 Rosenbrock 函数来解释 SPSA 算法的实现。它是优化算法的常用测试函数。它在 (-1, 1) 处具有全局最小值,并且有一个通向最小值的狭窄谷底。
import numpy as np def rosenbrock(x): """ The Rosenbrock function. """ return (1 - x[0])**2 + 100 * (x[1] - x[0]**2)**2 def SPSA(loss_function, theta, a, c, num_iterations): """ A method for minimizing a loss function via simultaneous perturbation stochastic approximation (SPSA). Parameters: loss_function (function): Loss function to be minimized. theta (numpy array): The initial values of the parameters. a (float): Size of the step when updating parameters. c (float): The noise parameter for randomly generating perturbations. num_iterations (int): Number of iterations in the algorithm. Returns: tuple: A tuple containing the best parameter values found and the corresponding loss value. """ # 初始化最佳参数值和损失 best_theta = theta best_loss = loss_function(theta) # 初始化迭代计数器 i = 0 # 重复,直到收敛或达到最大迭代次数 while i < num_iterations: # 生成一个随机扰动向量,其元素为 +1 或 -1 delta = np.random.choice([-1, 1], size=len(theta)) # 在正和负扰动下评估目标函数 loss_plus = loss_function(theta + c * delta) loss_minus = loss_function(theta - c * delta) # 使用扰动计算梯度估计 gradient = (loss_plus - loss_minus) / (2 * c * delta) # 更新参数值 theta = theta - a * gradient # 如果新参数值导致损失较低,则更新最佳值 new_loss = loss_function(theta) if new_loss < best_loss: best_theta = theta best_loss = new_loss # 增加迭代计数器 i += 1 # 返回最佳参数值和对应的损失值 return (best_theta, best_loss) # 设置初始参数值、步长、噪声参数和迭代次数 theta0 = np.array([-1.5, 1.5]) a = 0.1 c = 0.1 num_iterations = 1000 # 在 Rosenbrock 函数上运行 SPSA 算法 best_theta, best_loss = SPSA(rosenbrock, theta0, a, c, num_iterations) # 打印结果 print("最佳参数值:", best_theta) print("对应的损失:", best_loss)
我们导入所有必要的库。在 SPSA 函数中,根据给定的 theta 值初始化初始参数值和损失。迭代计数器设置为 0,主循环继续运行,直到达到最大收敛或最大迭代次数。在主循环内部,生成一个随机扰动向量"delta",其元素为 +1 或 -1。
然后通过从 theta 中减去 (c*delta,其中 c 是噪声参数) 来评估损失函数。使用公式 theta = theta - a*gradient 更新参数值。继续执行该过程,直到分配最佳参数值和损失值,然后显示最终结果。
输出
最佳参数值:[-1.5 1.5] 对应损失:62.5
结论
最终,SPSA 是一种能够优化具有许多参数的复杂函数的优化算法。与其他优化算法相比,SPSA 的一个主要优势是它不需要了解函数的导数或曲率,因此适用于广泛的优化问题。
因此,SPSA 对任何数据科学家或机器学习从业者来说都是一个有价值的工具,它的简单性和有效性使其成为许多优化问题的热门选择。