介绍
Subtraction-Average-Based Optimizer (SABO) 是一种新型的群体优化算法,其灵感来源于搜索代理之间位置的差异平均值,用于更新种群成员在搜索空间中的位置。SABO在标准基准函数和实际工程设计问题中的表现优异。它在平衡探索(exploration)与开发(exploitation)之间展现出了强大的能力,特别适用于复杂的多模态和高维优化问题(MDPI)。
探索与开发的平衡
SABO 通过使用减法平均策略,在探索(exploration)和开发(exploitation)之间取得了良好的平衡。探索有助于发现全局最优解,开发则有助于深入挖掘当前找到的潜在最优解。这使得 SABO 更加适合于处理深度学习中的复杂、高维问题,并避免陷入局部最优。
PSO 和 GA 等算法通常在处理复杂搜索空间时,容易出现过早收敛或陷入局部最优的现象,尤其是在深度学习中当搜索空间大且复杂时(IAENG)(MDPI)。
全局优化能力
SABO 在高维度、多模态问题中的表现尤为出色,其利用平均差值来更新种群的位置,有效避免了局部最优解的困境。实验表明,SABO 在处理非线性、多模态函数时,能够以更高的精度找到全局最优解(MDPI)。
遗传算法(GA) 和 差分进化(DE) 在解决超参数优化问题时,虽然也有较好的探索能力,但在搜索过程中可能会面临全局收敛速度慢的挑战。而 SABO 通过智能调整搜索空间,可以快速收敛。
搜索效率和收敛速度
SABO 的收敛速度更快,尤其是在大规模数据集的超参数优化任务中,它能够快速找到接近最优的超参数组合。其高效的搜索策略也使得它在计算资源有限的情况下表现出色。
相比之下,PSO 的收敛速度可能更依赖于初始参数设置,而 GA 则往往需要更多的代数迭代才能找到最佳解。 SABO 的减法平均策略可以大幅减少冗余的计算步骤,使其在大规模深度学习模型的优化中具备优势(MDPI)。
实际应用场景的表现
在实际的机器学习和深度学习任务中(如神经网络超参数优化或支持向量机参数优化),SABO 能够通过自适应地调整参数,找到更加准确和稳定的模型配置。此外,SABO 已被成功应用于实际的工程设计优化任务,进一步验证了其在解决现实问题中的强大能力(MDPI)。
与之相比,差分进化(DE) 虽然在某些简单模型中表现良好,但在面对复杂模型时,SABO 的性能更加优越。
本文代码
在深度学习和机器学习模型的超参数优化中,Subtraction-Average-Based Optimizer (SABO) 与其他常见的优化算法(如粒子群优化(PSO)、遗传算法(GA)、差分进化(DE)等)相比,具有一些明显的优势。通过对比这些算法在超参数优化中的性能,可以更好地突出 SABO 的独特性和优势
核心代码
python
import numpy as np
import matplotlib.pyplot as plt
from scipy.optimize import differential_evolution, basinhopping
from sko.PSO import PSO
from sko.GA import GA
# Rastrigin Function (a common multimodal optimization function)
def rastrigin(x):
A = 10
return A * len(x) + sum([(xi ** 2 - A * np.cos(2 * np.pi * xi)) for xi in x])
# Define SABO (Subtraction-Average-Based Optimizer)
class SABO:
def __init__(self, func, pop_size=50, dim=2, max_iter=100):
self.func = func
self.pop_size = pop_size
self.dim = dim
self.max_iter = max_iter
self.pop = np.random.uniform(-5.12, 5.12, (self.pop_size, self.dim))
self.fitness = np.array([self.func(ind) for ind in self.pop])
def optimize(self):
best_fitness = np.min(self.fitness)
best_pos = self.pop[np.argmin(self.fitness)]
fitness_history = [best_fitness]
for _ in range(self.max_iter):
avg = np.mean(self.pop, axis=0)
self.pop = new_pop + np.random.uniform(-0.5, 0.5, (self.pop_size, self.dim))
self.fitness = np.array([self.func(ind) for ind in self.pop])
return best_pos, best_fitness, fitness_history
# Parameters
dim = 2
pop_size = 50
max_iter = 100
# PSO
pso = PSO(func=rastrigin, dim=dim, pop=pop_size, max_iter=max_iter, lb=[-5.12] * dim, ub=[5.12] * dim)
pso_res = pso.run()
# GA
ga = GA(func=rastrigin, n_dim=dim, size_pop=pop_size, max_iter=max_iter, lb=[-5.12] * dim, ub=[5.12] * dim)
ga_res = ga.run()
# SABO
sabo = SABO(rastrigin, pop_size=pop_size, dim=dim, max_iter=max_iter)
sabo_res, sabo_best_fitness, sabo_fitness_history = sabo.optimize()
# Plotting results
plt.plot(pso.gbest_y_hist, label='PSO')
plt.plot(ga.generation_best_Y, label='GA')
plt.plot(sabo_fitness_history, label='SABO')
plt.xlabel('Iterations')
plt.ylabel('Best Fitness')
plt.legend()
plt.title('Performance Comparison of SABO, PSO, and GA')
plt.show()
# Print final results
print(f"PSO Best Fitness: {
pso.gbest_y}")
print(f"GA Best Fitness: {
ga.gbest_y}")
print(f"SABO Best Fitness: {
sabo_best_fitness}")
matlab
clc; clear; close all;
% Define Rastrigin function
rastrigin = @(x) 10 * length(x) + sum(x.^2 - 10 * cos(2 * pi * x));
% Parameters
dim = 2; % Dimension
pop_size = 50; % Population size
max_iter = 100; % Maximum iterations
lb = -5.12; % Lower bound
ub = 5.12; % Upper bound
% ------------------------ PSO Algorithm ------------------------
pso_opt = pso(rastrigin, dim, pop_size, lb, ub, max_iter);
% ------------------------ Genetic Algorithm (GA) ------------------------
ga_opt = ga(rastrigin, dim, pop_size, lb, ub, max_iter);
% ------------------------ SABO Algorithm ------------------------
[sabo_opt, sabo_fitness_history] = sabo(rastrigin, pop_size, dim, max_iter, lb, ub);
% Plot results
figure;
plot(1:max_iter, pso_opt.fitness_history, 'b', 'LineWidth', 2); hold on;
plot(1:max_iter, ga_opt.fitness_history, 'r', 'LineWidth', 2);
plot(1:max_iter, sabo_fitness_history, 'g', 'LineWidth', 2);
xlabel('Iterations'); ylabel('Best Fitness');
legend('PSO', 'GA', 'SABO');
title('Performance Comparison of SABO, PSO, and GA');
% ------------------------ Function Definitions ------------------------
% PSO Algorithm
function pso_opt = pso(obj_func, dim, pop_size, lb, ub, max_iter)
w = 0.5; c1 = 1.5; c2 = 1.5; % PSO constants
swarm = lb + (ub - lb) * rand(pop_size, dim); % Initialize particles
velocity = zeros(pop_size, dim);
personal_best = swarm;
personal_best_fitness = arrayfun(@(i) obj_func(personal_best(i, :)), 1:pop_size);
[global_best_fitness, idx] = min(personal_best_fitness);
global_best = swarm(idx, :);
for iter = 1:max_iter
% Update velocity and position
swarm = swarm + velocity;
% Evaluate fitness
fitness = arrayfun(@(i) obj_func(swarm(i, :)), 1:pop_size);
for i = 1:pop_size
if fitness(i) < personal_best_fitness(i)
personal_best(i, :) = swarm(i, :);
personal_best_fitness(i) = fitness(i);
end
end
[global_best_fitness, idx] = min(personal_best_fitness);
global_best = personal_best(idx, :);
pso_opt.fitness_history(iter) = global_best_fitness; % Track fitness history
end
end
% Genetic Algorithm (GA)
function ga_opt = ga(obj_func, dim, pop_size, lb, ub, max_iter)
% Initialize population
population = lb + (ub - lb) * rand(pop_size, dim);
fitness = arrayfun(obj_func, population);
for iter = 1:max_iter
% Selection and Crossover
selected = tournament_selection(population, fitness, pop_size);
children = crossover(selected, lb, ub);
% Mutation
mutated = mutation(children, lb, ub);
% Evaluate fitness
fitness = arrayfun(obj_func, mutated);
% Replace old population
population = mutated;
[best_fitness_val, idx] = min(fitness(:)); % Ensure best_fitness is scalar
ga_opt.fitness_history(iter) = best_fitness_val; % Track scalar fitness value
end
end
% SABO Algorithm
function [best_pos, fitness_history] = sabo(obj_func, pop_size, dim, max_iter, lb, ub)
pop = lb + (ub - lb) * rand(pop_size, dim);
fitness = arrayfun(obj_func, pop);
best_fitness = min(fitness);
fitness_history = best_fitness;
for iter = 1:max_iter
avg = mean(pop, 1);
new_pop = pop - avg;
pop = new_pop + (rand(pop_size, dim) - 0.5);
if current_best_fitness < best_fitness
best_fitness = current_best_fitness;
end
fitness_history(iter) = min(best_fitness); % Track the minimum fitness value
end
best_pos = pop;
end
% Genetic Algorithm Helpers
function selected = tournament_selection(population, fitness, pop_size)
selected = zeros(size(population));
for i = 1:pop_size
candidates = randi([1, pop_size], 2, 1); % Randomly pick 2 candidates
if fitness(candidates(1)) < fitness(candidates(2))
selected(i, :) = population(candidates(1), :);
else
selected(i, :) = population(candidates(2), :);
end
end
end
function children = crossover(parents, lb, ub)
children = parents;
cross_points = rand(size(parents)) > 0.5;
children(cross_points) = parents(cross_points);
children = min(max(children, lb), ub); % Ensure within bounds
end
function mutated = mutation(children, lb, ub)
mutation_rate = 0.1;
mutations = rand(size(children)) < mutation_rate;
mutated = children + mutations .* (rand(size(children)) - 0.5);
mutated = min(max(mutated, lb), ub); % Ensure within bounds
end
效果展示
python
matlab
说明
SABO 表现:
收敛速度:SABO 的收敛速度与 PSO 相比稍慢一些,但比 GA 更快。
最终收敛值:从图中可以看到,SABO 在迭代结束时取得了相对较好的结果。虽然它没有像 PSO 那样快速下降到接近 0,但它的结果更加稳定,表现出了较强的全局优化能力,避免了过早陷入局部最优。
PSO 表现:
快速收敛:PSO 在前期(大约前 20 次迭代)中表现出了非常快的收敛速度,几乎立即找到接近最优解。这说明 PSO 在处理初始阶段的探索性非常强。
局部最优问题:不过,PSO 似乎很快陷入了局部最优,后期迭代中几乎没有进一步提升。虽然 PSO 在短时间内找到较好的解,但它的开发能力相对较弱。
GA 表现:
稳定但收敛较慢:GA 在整个过程中表现出相对稳定的下降趋势,但收敛速度明显慢于 PSO 和 SABO。GA 在找到最优解的过程中更加保守,虽然在探索上有一定的优势,但在解的精度和速度上不如另外两种算法。
总结:
SABO 的优势:SABO 在避免局部最优和处理复杂多模态问题上表现优异,它能够在多次迭代后逐渐逼近最优解,展示了良好的全局搜索能力。虽然它的收敛速度不如 PSO 快,但在深度学习等复杂模型的超参数优化中,SABO 的全局优化能力将会非常有用。
PSO 的优势与局限:PSO 非常适合快速收敛到局部最优解的场景,但在全局优化任务中可能不够有效,容易陷入局部最优。
GA 的适用性:GA 尽管稳定性较好,但收敛速度慢,适合在有充分时间的情况下进行更为全面的探索。
完整代码获取
关注下方卡片公众号,回复,SABO获取完整代码