You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

多输出回归问题中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()

方案分析与修正建议

  1. 方案a的问题:PyGAD要求fitness_func必须返回单个数值作为当前解的适应度值,但方案a返回的是一个列表,这会导致PyGAD运行报错,无法正确评估解的优劣。
  2. 方案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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 11:57:16