超参数调整专题2
三种算法都是优化器,用来求最佳参数的组合,使得指标达到最优,区别在于每一个算法的策略有所区别。下表是总体介绍。
遗传算法
策略是以适应度为评价指标(可以是一些结果方面的指标),通过选择,交叉和变异三种操作,生成子代,作为新的种群去替换旧的种群(保留适应度高的个体),循环往复,知到适应度收敛或者达到预设的迭代次数。
其中选择是选择适应度高的个体做父本(轮盘赌、锦标赛、精英保留),交叉是指父代基因重组生成子代,变异是指对子代基因随机小幅度变动。
import numpy as np
from deap import base, creator, tools
# 定义目标函数(最大化)
creator.create("FitnessMax", base.Fitness, weights=(1.0,))
creator.create("Individual", list, fitness=creator.FitnessMax)
toolbox = base.Toolbox()
toolbox.register("attr_float", np.random.uniform, -5, 5) # 定义变量范围
toolbox.register("individual", tools.initRepeat, creator.Individual, toolbox.attr_float, n=2) # 2维问题
toolbox.register("population", tools.initRepeat, list, toolbox.individual)
def evaluate(individual):
# 目标函数(例:最大化 Rastrigin 函数)
x, y = individual
return 20 + x**2 - 10*np.cos(2*np.pi*x) + y**2 - 10*np.cos(2*np.pi*y),
toolbox.register("evaluate", evaluate)
toolbox.register("mate", tools.cxBlend, alpha=0.5) # 交叉
toolbox.register("mutate", tools.mutGaussian, mu=0, sigma=1, indpb=0.2) # 变异
toolbox.register("select", tools.selTournament, tournsize=3) # 选择
# 运行算法
population = toolbox.population(n=50)
for gen in range(100):
offspring = toolbox.select(population, len(population))
offspring = [toolbox.clone(ind) for ind in offspring]
for child1, child2 in zip(offspring[::2], offspring[1::2]):
if np.random.rand() < 0.8: # 交叉概率
toolbox.mate(child1, child2)
del child1.fitness.values, child2.fitness.values
for mutant in offspring:
if np.random.rand() < 0.1: # 变异概率
toolbox.mutate(mutant)
del mutant.fitness.values
invalid_ind = [ind for ind in offspring if not ind.fitness.valid]
fitnesses = toolbox.map(toolbox.evaluate, invalid_ind)
for ind, fit in zip(invalid_ind, fitnesses):
ind.fitness.values = fit
population[:] = offspring
粒子群算法
策略是模拟鸟群或鱼群的社会协作行为,粒子通过跟踪个体历史最优(pbest)和群体历史(gbest)最优更新速度和位置,逐步收敛到最优解。
步骤:
1.初始化:随机生成粒子群(位置和速度)。
2.评估适应度:计算每个粒子的适应度值。
3.更新 pbest 和 gbest:记录个体和群体最优。
4.更新速度和位置:按公式调整粒子运动。
5.终止条件:达到最大迭代次数或 gbest 稳定
import numpy as np
def pso_demo():
n_particles = 20 # 粒子数量
max_iter = 50 # 最大迭代次数
dim = 2 # 变量维度(x和y)
bounds = [(-5, 5)] * dim # 变量范围
# 初始化粒子群
particles = np.random.uniform(low=-5, high=5, size=(n_particles, dim))
velocities = np.zeros((n_particles, dim))
pbest_pos = particles.copy()
pbest_val = np.array([float('inf')] * n_particles)
gbest_pos = np.zeros(dim)
gbest_val = float('inf')
# 目标函数
def fitness(pos):
return np.sum(pos ** 2)
# PSO主循环
for _ in range(max_iter):
for i in range(n_particles):
current_val = fitness(particles[i])
if current_val < pbest_val[i]:
pbest_val[i] = current_val
pbest_pos[i] = particles[i].copy()
if current_val < gbest_val:
gbest_val = current_val
gbest_pos = particles[i].copy()
# 更新速度和位置(ω=0.5, c1=1.5, c2=1.5)
inertia = 0.5 * velocities
cognitive = 1.5 * np.random.rand() * (pbest_pos - particles)
social = 1.5 * np.random.rand() * (gbest_pos - particles)
velocities = inertia + cognitive + social
particles = np.clip(particles + velocities, bounds[0][0], bounds[0][1])
print(f"Iter {_}: Best Value = {gbest_val:.4f}, Position = {gbest_pos}")
pso_demo()
退火算法
模拟退火算法受金属退火过程启发,通过 温度控制 的随机扰动和 Metropolis接受准则(允许一定概率接受较差解)逐步逼近全局最优。其理论可保证全局收敛,尤其适合中小规模组合优化问题(如集成电路布线、TSP),但效率受降温策略影响显著,初始温度、降温速率等参数需精细调节,大规模问题中计算耗时较长。
步骤:
初始化:随机生成初始解,设定初始温度 T0T0。
扰动生成新解:在当前解附近随机扰动(如交换、位移)。
计算能量差:ΔE=Enew−EcurrentΔE=Enew−Ecurrent。
Metropolis 判断:若 ΔE<0ΔE<0 则接受新解;否则以概率 PP 接受。
降温:按策略降低温度 TT。
终止条件:温度降至阈值或解不再改进。
import numpy as np
import math
def sa_demo():
def fitness(x):
return x ** 2 # 目标函数
def neighbor(x, T):
return x + np.random.uniform(-0.5, 0.5) * T # 温度控制扰动幅度
current_sol = 10.0 # 初始解
current_val = fitness(current_sol)
T = 1000.0 # 初始温度
T_min = 1e-5 # 终止温度
alpha = 0.95 # 降温系数
best_sol = current_sol
best_val = current_val
while T > T_min:
new_sol = neighbor(current_sol, T)
new_val = fitness(new_sol)
delta = new_val - current_val
# Metropolis接受准则
if delta < 0 or np.random.rand() < math.exp(-delta / T):
current_sol, current_val = new_sol, new_val
if current_val < best_val:
best_sol, best_val = current_sol, current_val
T *= alpha # 降温
print(f"Temp {T:.2f}: Current {current_sol:.2f} (Val {current_val:.2f}), Best {best_sol:.2f} (Val {best_val:.2f})")
sa_demo()
@浙大疏锦行