来源:DeepHub IMBA
本文约3700字,建议阅读10+分钟 本文将介绍四种高级优化技术,这些技术在某些任务中可能优于传统方法,特别是在面对复杂优化问题时。
-
序列最小二乘规划(SLSQP) -
粒子群优化(PSO) -
协方差矩阵自适应进化策略(CMA-ES) -
模拟退火(SA)
-
无梯度优化: 适用于非可微操作,如采样、取整和组合优化。 -
仅需前向传播: 通常比传统方法更快,且内存效率更高。 -
全局优化能力: 有助于避免局部最优解。
from functools import partial
from collections import defaultdict
import torch
import torch.nn as nn
import torch.optim as optim
import torch.nn.functional as F
import numpy as np
import scipy.optimize as opt
import matplotlib.pyplot as plt
# 设置随机种子以确保结果可复现
torch.manual_seed(42)
np.random.seed(42)
# 辅助函数:在PyTorch模型和NumPy向量之间转换权重
def set_model_weights_from_vector(model, numpy_vector):
weight_vector = torch.tensor(numpy_vector, dtype=torch.float64)
model[0].weight.data = weight_vector[0:4].reshape(2, 2)
model[2].weight.data = weight_vector[4:8].reshape(2, 2)
model[2].bias.data = weight_vector[8:10]
return model
def get_vector_from_model_weights(model):
return torch.cat([
model[0].weight.data.view(-1),
model[2].weight.data.view(-1),
model[2].bias.data]
).detach().numpy()
# 用于跟踪和更新损失的函数
def update_tracker(loss_tracker, optimizer_name, loss_val):
loss_tracker[optimizer_name].append(loss_val)
if len(loss_tracker[optimizer_name]) > 1:
min_loss = min(loss_tracker[optimizer_name][-2], loss_val)
loss_tracker[optimizer_name][-1] = min_loss
return loss_tracker
def objective(x, model, input, target, loss_tracker, optimizer_name):
model = set_model_weights_from_vector(model, x)
loss_val = F.mse_loss(model(input), target).item()
loss_tracker = update_tracker(loss_tracker, optimizer_name, loss_val)
return loss_val
def pytorch_optimize(x, model, input, target, maxiter, loss_tracker, optimizer_name="Adam"):
x)
optimizer = optim.Adam(model.parameters(), lr=1.)
# 训练循环
for iteration in range(maxiter):
loss = F.mse_loss(model(input), target)
optimizer.step()
loss_tracker = update_tracker(loss_tracker, optimizer_name, loss.item())
final_x = get_vector_from_model_weights(model)
return final_x, loss.item()
model = nn.Sequential(nn.Linear(2, 2, bias=False), nn.ReLU(), nn.Linear(2, 2, bias=True)).double()
input_tensor = torch.randn(32, 2).double() # 随机输入张量
input_tensor[:, 1] *= 1e3 # 增加一个变量的敏感度
target = input_tensor.clone() # 目标是输入本身(恒等函数)
num_params = 10
maxiter = 100
x0 = 0.1 * np.random.randn(num_params)
loss_tracker = defaultdict(list)
optimizer_name = "PyTorch Adam"
result = pytorch_optimize(x0, model, input_tensor, target, maxiter, loss_tracker, optimizer_name)
print(f'Adam优化器最终损失: {result[1]}')
Adam优化器最终损失: 91.527
optimizer_name = "slsqp"
args = (model, input_tensor, target, loss_tracker, optimizer_name)
result = opt.minimize(objective, x0, method=optimizer_name, args=args, options={"maxiter": maxiter, "disp": False, "eps": 0.001})
print(f"SLSQP优化器最终损失: {result.fun}")
SLSQP优化器最终损失: 3.0268
from pyswarm import pso
lb = -np.ones(num_params)
ub = np.ones(num_params)
optimizer_name = 'pso'
args = (model, input_tensor, target, loss_tracker, optimizer_name)
result_pso = pso(objective, lb, ub, maxiter=maxiter, args=args)
{result_pso[1]}") :
PSO优化器最终损失: 1.04032
from cma import CMAEvolutionStrategy
es = CMAEvolutionStrategy(x0, 0.5, {"maxiter": maxiter, "seed": 42})
optimizer_name = 'cma'
args = (model, input_tensor, target, loss_tracker, optimizer_name)
while not es.stop():
solutions = es.ask()
object_vals = [objective(x, *args) for x in solutions]
es.tell(solutions, object_vals)
print(f"CMA-ES优化器最终损失: {es.result[1]}")
(5_w,10)-aCMA-ES (mu_w=3.2,w_1=45%) in dimension 10 (seed=42, Thu Oct 12 22:03:53 2024)
CMA-ES优化器最终损失: 4.0896
from scipy.optimize import dual_annealing
bounds = [(-1, 1)] * num_params
optimizer_name = 'simulated_annealing'
args = (model, input_tensor, target, loss_tracker, optimizer_name)
result = dual_annealing(objective, bounds, maxiter=maxiter, args=args, initial_temp=1.)
print(f"SA优化器最终损失: {result.fun}")
SA优化器最终损失: 0.39689
可以看到,针对我们的问题SA表现最佳,这突显了其在复杂优化问题中的潜力。
plt.figure(figsize=(10, 6))
line_styles = ['-', '--', '-.', ':']
for i, (optimizer_name, losses) in enumerate(loss_tracker.items()):
plt.plot(np.linspace(0, maxiter, len(losses)), losses,
label=optimizer_name,
linestyle=line_styles[i % len(line_styles)],
linewidth=5,
)
plt.xlabel("Iteration", fontsize=20)
plt.ylabel("Loss", fontsize=20)
plt.ylim(1e-1, 1e7)
plt.yscale('log')
plt.title("Loss For Different Optimizers", fontsize=20)
plt.grid(True, linestyle='--', alpha=0.6)
plt.legend(loc='upper right', fontsize=20)
plt.tight_layout()
plt.savefig('optimizers.png')
plt.show()
-
Adam优化器: 作为基准Adam表现稳定但收敛速度相对较慢。这反映了在某些复杂问题中,传统梯度下降方法可能不是最优选择。 -
SLSQP: 序列最小二乘规划表现出快速的初始收敛,这表明它在处理具有连续参数的问题时非常有效。 -
PSO: 粒子群优化展示了良好的全局搜索能力,能够迅速找到较好的解。这凸显了其在非凸优化问题中的潜力。 -
CMA-ES: 虽然在本实验中收敛较慢,但协方差矩阵自适应进化策略通常在处理高度复杂和多模态的问题时表现出色。其性能可能在更复杂的优化场景中更为突出。 -
模拟退火: 我们这个特定问题SA表现最为出色,仅用几次迭代就达到了最低损失。这突显了其在避免局部最优解并快速找到全局最优解方面的优势。
-
对于参数数量较少(100-1000个)的优化问题,考虑尝试本文介绍的高级优化技术。 -
在处理非可微操作或复杂的损失景观时,无梯度方法(如PSO、CMA-ES和SA)可能更有优势。 -
对于需要满足复杂约束的优化问题,SLSQP可能是一个很好的选择。 -
在计算资源有限的情况下,考虑使用仅需前向传播的方法,如PSO或SA。 -
对于高度非凸的问题,CMA-ES和SA可能更容易找到全局最优解。
-
探索这些高级优化技术在更复杂的深度学习模型中的应用。 -
研究如何有效地将这些方法与传统的梯度下降算法结合,以开发混合优化策略。 -
开发更高效的并行化实现,以提高这些算法在大规模问题上的适用性。 -
探索这些方法在特定领域(如强化学习、神经架构搜索)中的潜在应用。
-
Hansen, N. (2016). The CMA Evolution Strategy: A Tutorial. arXiv preprint arXiv:1604.00772. -
Kennedy, J., & Eberhart, R. (1995). Particle swarm optimization. Proceedings of ICNN'95 - International Conference on Neural Networks, 4, 1942-1948. -
Nocedal, J., & Wright, S. J. (1999). Numerical Optimization. New York: Springer. -
Tsallis, C., & Stariolo, D. A. (1996). Generalized simulated annealing. Physica A: Statistical Mechanics and its Applications, 233(1-2), 395-406. -
Kingma, D. P., & Ba, J. (2014). Adam: A Method for Stochastic Optimization. arXiv preprint arXiv:1412.6980. -
Ruder, S. (2016). An overview of gradient descent optimization algorithms. arXiv preprint arXiv:1609.04747.
关于我们
数据派THU作为数据科学类公众号,背靠清华大学大数据研究中心,分享前沿数据科学与大数据技术创新研究动态、持续传播数据科学知识,努力建设数据人才聚集平台、打造中国大数据最强集团军。
新浪微博:@数据派THU
微信视频号:数据派THU
今日头条:数据派THU
版权声明:
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若内容造成侵权、违法违规、事实不符,请将相关资料发送至xkadmin@xkablog.com进行投诉反馈,一经查实,立即处理!
转载请注明出处,原文链接:https://www.xkablog.com/jszy-jnts/49802.html