多输出回归问题中PyGAD适应度函数选型咨询
回归问题中PyGAD适应度函数的方案选择
我正在处理回归任务,需要为PyGAD设计适配的适应度函数。我的数据集包含1000组输入输出数据:X_train为形状(1000,72,2)的numpy数组,Y_train为形状(1000,72,4)的numpy数组。目前我有两种适应度函数实现方案,同时附上了Keras模型和PyGAD初始化代码,想请教哪种方案更合理,或者应该如何修正。
方案a代码
def fitness_func(ga_instance, solution, sol_idx): global keras_ga, model, all_data fitness_values = [] for X_train, Y_train in all_data: model_weights_matrix = pygad.kerasga.model_weights_as_matrix(model=model, weights_vector=solution) model.set_weights(weights=model_weights_matrix) predictions = model.predict(X_train) mae = tf.keras.losses.MeanAbsoluteError() abs_error = mae(Y_train, predictions).numpy() + 0.00000001 solution_fitness = 1.0 / abs_error fitness_values.append(solution_fitness) return fitness_values
方案b代码
def fitness_func(ga_instance, solution, sol_idx): global keras_ga, model, all_data fitness_values = [] for X_train, Y_train in all_data: model_weights_matrix = pygad.kerasga.model_weights_as_matrix(model=model, weights_vector=solution) model.set_weights(weights=model_weights_matrix) predictions = model.predict(X_train) mae = tf.keras.losses.MeanAbsoluteError() abs_error = mae(Y_train, predictions).numpy() + 0.00000001 solution_fitness = 1.0 / abs_error fitness_values.append(solution_fitness) average_fitness = np.mean(fitness_values) return average_fitness
Keras模型与PyGAD初始化代码
sequence_length = X_train.shape[1] feature_dimensions = X_train.shape[2] input_layer = Input(shape=(2,), name='input_layer') hidden_layer = Dense(units=8, activation='relu')(input_layer) output_layer = Dense(units=4, activation='linear', name='output_layer')(hidden_layer) model = Model(inputs=input_layer, outputs=output_layer) model.compile(optimizer='adam', loss='mse') weights_vector = pygad.kerasga.model_weights_as_vector(model=model) keras_ga = pygad.kerasga.KerasGA(model=model, num_solutions=15) num_generations = 10000#0#0 num_parents_mating = 5 initial_population = keras_ga.population_weights ga_instance = pygad.GA(num_generations=num_generations, num_parents_mating=num_parents_mating, initial_population=initial_population, on_generation=callback_generation, crossover_type="two_points", fitness_func=fitness_func) ga_instance.run()
方案分析与修正建议
- 方案a的问题:PyGAD要求
fitness_func必须返回单个数值作为当前解的适应度值,但方案a返回的是一个列表,这会导致PyGAD运行报错,无法正确评估解的优劣。 - 方案b的问题:
return average_fitness语句写在for循环内部,这会导致循环只执行一次(处理第一组X_train/Y_train)就直接返回结果,完全没有遍历all_data中的所有数据,计算的平均适应度毫无意义。
正确的实现方式
应该将返回语句移到循环外部,遍历完所有数据后再计算平均适应度并返回:
def fitness_func(ga_instance, solution, sol_idx): global keras_ga, model, all_data fitness_values = [] for X_train, Y_train in all_data: model_weights_matrix = pygad.kerasga.model_weights_as_matrix(model=model, weights_vector=solution) model.set_weights(weights=model_weights_matrix) predictions = model.predict(X_train) mae = tf.keras.losses.MeanAbsoluteError() abs_error = mae(Y_train, predictions).numpy() + 1e-8 # 用科学计数法更规范 solution_fitness = 1.0 / abs_error fitness_values.append(solution_fitness) # 遍历完所有数据后计算平均适应度 average_fitness = np.mean(fitness_values) return average_fitness
额外优化点
- 避免使用
global变量,可以通过PyGAD的user_inputs参数传递模型、all_data等数据,代码更整洁且易于维护。 - 考虑到模型预测的开销,若
all_data数据量较大,可考虑批量处理或减少重复计算,提升GA的运行效率。 - 注意输入数据的形状与模型输入是否匹配:你的模型输入是
(2,),但X_train的形状是(1000,72,2),需要确保预测时数据维度正确(比如是否需要展开或调整维度)。
内容的提问来源于stack exchange,提问作者Sadia Ferdous Snigdha
相关产品推荐
相关产品推荐

