如何优化含共享全局参数与独立局部参数的向量函数和?
优化方案:交替最小化(Alternating Minimization)
这个场景刚好符合交替最小化的适用条件,核心逻辑是把变量拆成全局共享参数和各子函数局部参数两组,交替固定一组优化另一组,完全避免变量规模随子函数数量线性暴涨的问题。
具体实现步骤
- 第一步:初始化全局参数(比如a、b)的初始值,可以随机取或者根据业务先验设置合理初始值
- 第二步:固定当前的全局参数,对每个子函数独立优化各自的局部参数。这一步所有子函数的优化完全独立,甚至可以开多进程并行提速,完全不会互相干扰
- 第三步:固定所有子函数已经优化好的局部参数,统一优化全局共享参数,这一步的优化变量只有全局参数的数量,和子函数的数量完全无关
- 第四步:重复第二步和第三步,直到两次迭代的总函数和的差值小于你设定的收敛阈值,或者达到最大迭代次数就停止
Python 实现参考
你可以直接用scipy.optimize模块的优化器实现,示例逻辑如下:
from scipy.optimize import minimize import numpy as np # 假设你有N个子函数存在func_list里,每个func的调用格式为func(global_params, local_params) # 全局参数维度为2(对应a、b),每个子函数的局部参数维度为1(对应x、y这类) N = 100 func_list = [你的N个函数实例] def total_loss(global_params, local_params_list): # 固定局部参数时,计算总损失用来优化全局参数 loss = 0.0 for i in range(N): loss += func_list[i](global_params, local_params_list[i]) return loss # 初始化参数 global_params = np.array([0.0, 0.0]) # a、b的初始值 local_params_list = [np.array([0.0]) for _ in range(N)] # 每个子函数的局部参数初始值 prev_loss = float('inf') threshold = 1e-6 max_iter = 100 for iter in range(max_iter): # 步骤1:固定全局参数,优化每个子函数的局部参数 for i in range(N): # 单个子函数的损失,只和自己的局部参数有关 def local_loss(p): return func_list[i](global_params, p) res = minimize(local_loss, local_params_list[i], method='L-BFGS-B') local_params_list[i] = res.x # 步骤2:固定所有局部参数,优化全局参数 res = minimize(total_loss, global_params, args=(local_params_list,), method='L-BFGS-B') global_params = res.x current_loss = res.fun # 收敛判断 if abs(current_loss - prev_loss) < threshold: break prev_loss = current_loss
额外优化点
- 如果子函数数量特别多,第二步优化局部参数的时候可以用
multiprocessing模块并行处理,优化速度会有明显提升 - 如果你的函数都是可微的,可以用
jax库做自动微分,替换scipy的优化器,收敛速度会快很多 - 如果你能确定子函数和全局参数、局部参数的关系是凸的,那这个方法可以收敛到全局最优解;如果是非凸的,也能收敛到一个不错的局部最优解,效果远好于直接把所有变量放一起优化的朴素方案
内容的提问来源于stack exchange,提问作者R K Rupesh
相关产品推荐
相关产品推荐

