除Keras外,基于群智能元启发式算法的LSTM超参数调优方案咨询
群智能算法调优LSTM超参数(Google Colab环境)
一、除Keras外的适用库
- Optuna:支持粒子群(PSO)、蚁群(ACO)等群智能算法扩展,可直接对接TensorFlow/PyTorch,无需依赖Keras专属API,调优逻辑灵活。
- DEAP:分布式进化算法框架,能自定义实现各类群智能算法(如粒子群、萤火虫算法),适合手动封装LSTM超参数搜索逻辑。
- Scikit-Optimize:虽主打贝叶斯优化,但可集成群智能算法插件,配合纯TensorFlow或Scikit-Learn使用。
二、PyGAD实现LSTM超参数调优示例
以下是Colab可直接运行的代码,以二分类任务为例:
import pygad import tensorflow as tf import numpy as np # 生成模拟时间序列数据(替换为你的真实数据) def generate_data(): X = np.random.rand(1000, 10, 1) # 1000个样本,10个时间步,1个特征 y = np.random.randint(0, 2, size=(1000, 1)) # 二分类标签 return X, y X_train, y_train = generate_data() # 根据超参数构建LSTM模型 def build_lstm_model(params): lstm_units, num_layers, dropout_rate, learning_rate = params model = tf.keras.Sequential() for i in range(num_layers): return_seq = i != num_layers - 1 model.add(tf.keras.layers.LSTM(lstm_units, return_sequences=return_seq, input_shape=(10, 1))) model.add(tf.keras.layers.Dropout(dropout_rate)) model.add(tf.keras.layers.Dense(1, activation='sigmoid')) optimizer = tf.keras.optimizers.Adam(learning_rate=learning_rate) model.compile(optimizer=optimizer, loss='binary_crossentropy', metrics=['accuracy']) return model # PyGAD适应度函数:返回模型准确率 def fitness_func(ga_instance, solution, solution_idx): model = build_lstm_model(solution) history = model.fit(X_train, y_train, epochs=5, batch_size=32, verbose=0) return history.history['accuracy'][-1] # 配置PyGAD参数 num_generations = 10 num_parents_mating = 4 sol_per_pop = 8 num_genes = 4 # 对应4个超参数:LSTM单元数、层数、dropout率、学习率 # 定义每个超参数的取值范围 gene_space = [ range(32, 128, 16), # LSTM单元数:32、48...112 range(1, 3), # 层数:1或2 np.arange(0.1, 0.5, 0.1), # dropout率:0.1-0.4 np.logspace(-4, -2, 10) # 学习率:1e-4到1e-2的对数空间 ] # 初始化并运行遗传算法 ga_instance = pygad.GA(num_generations=num_generations, num_parents_mating=num_parents_mating, fitness_func=fitness_func, sol_per_pop=sol_per_pop, num_genes=num_genes, gene_space=gene_space, mutation_percent_genes=20) ga_instance.run() # 输出最优结果 best_sol, best_fitness, _ = ga_instance.best_solution() print("最优超参数组合:", best_sol) print("对应模型准确率:", best_fitness)
三、无第三方库的手动实现方案
如果不想依赖调优库,可手动实现粒子群优化(PSO),核心代码如下:
import tensorflow as tf import numpy as np # 生成模拟数据(替换为真实数据) X_train = np.random.rand(1000, 10, 1) y_train = np.random.randint(0, 2, size=(1000, 1)) # 定义超参数搜索范围 param_bounds = { 'lstm_units': (32, 128), 'num_layers': (1, 2), 'dropout': (0.1, 0.4), 'lr': (1e-4, 1e-2) } # 评估超参数性能:返回模型准确率 def evaluate_params(params): model = tf.keras.Sequential() for i in range(int(params['num_layers'])): return_seq = i != int(params['num_layers']) - 1 model.add(tf.keras.layers.LSTM(int(params['lstm_units']), return_sequences=return_seq, input_shape=(10,1))) model.add(tf.keras.layers.Dropout(params['dropout'])) model.add(tf.keras.layers.Dense(1, activation='sigmoid')) model.compile(optimizer=tf.keras.optimizers.Adam(params['lr']), loss='binary_crossentropy', metrics=['accuracy']) history = model.fit(X_train, y_train, epochs=5, batch_size=32, verbose=0) return history.history['accuracy'][-1] # 手动实现PSO算法 class PSO: def __init__(self, param_bounds, num_particles=10, max_iter=10, w=0.7, c1=1.5, c2=1.5): self.param_bounds = param_bounds self.num_particles = num_particles self.max_iter = max_iter self.w = w # 惯性权重 self.c1 = c1 # 认知系数 self.c2 = c2 # 社会系数 # 初始化粒子位置、速度及最优值 self.particles = [] self.velocities = [] self.pbest = [] self.pbest_fitness = [] self.gbest = None self.gbest_fitness = -np.inf for _ in range(num_particles): # 随机初始化粒子位置 pos = {k: np.random.uniform(v[0], v[1]) for k, v in param_bounds.items()} self.particles.append(pos) # 初始化速度 self.velocities.append({k: np.random.uniform(-(v[1]-v[0]), v[1]-v[0]) for k, v in param_bounds.items()}) # 计算初始适应度 fit = evaluate_params(pos) self.pbest.append(pos.copy()) self.pbest_fitness.append(fit) # 更新全局最优 if fit > self.gbest_fitness: self.gbest = pos.copy() self.gbest_fitness = fit def update_particles(self): for i in range(self.num_particles): # 更新速度 for k in self.param_bounds.keys(): r1, r2 = np.random.rand(2) self.velocities[i][k] = (self.w * self.velocities[i][k] + self.c1 * r1 * (self.pbest[i][k] - self.particles[i][k]) + self.c2 * r2 * (self.gbest[k] - self.particles[i][k])) # 限制速度范围 max_vel = self.param_bounds[k][1] - self.param_bounds[k][0] self.velocities[i][k] = np.clip(self.velocities[i][k], -max_vel, max_vel) # 更新位置 for k in self.param_bounds.keys(): self.particles[i][k] += self.velocities[i][k] # 限制位置在参数范围内 self.particles[i][k] = np.clip(self.particles[i][k], self.param_bounds[k][0], self.param_bounds[k][1]) # 整数参数取整 if k in ['lstm_units', 'num_layers']: self.particles[i][k] = int(round(self.particles[i][k])) # 更新个体最优 current_fit = evaluate_params(self.particles[i]) if current_fit > self.pbest_fitness[i]: self.pbest[i] = self.particles[i].copy() self.pbest_fitness[i] = current_fit # 更新全局最优 if current_fit > self.gbest_fitness: self.gbest = self.particles[i].copy() self.gbest_fitness = current_fit def run(self): for iter in range(self.max_iter): self.update_particles() print(f"迭代 {iter+1}/{self.max_iter} | 当前最优准确率:{self.gbest_fitness:.4f}") print("\n最优超参数:", self.gbest) print("最优准确率:", self.gbest_fitness) # 启动PSO调优 pso = PSO(param_bounds, num_particles=8, max_iter=10) pso.run()
内容的提问来源于stack exchange,提问作者B OZTURK
相关产品推荐
相关产品推荐

