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

如何在Keras Tuner中查看每个试验的多次执行结果?

问题

我正尝试使用Keras Tuner的Hyperband算法为自编码器模型选择超参数,相关伪代码如下:

class AEHyperModel(kt.HyperModel):
   def __init_(self, input_shape):
      self.input_shape = input_shape

   def build(self, hp):
    
       # Input layer
       x = Input(shape=(input_shape,))
    
       # Encoder layer 1
       hp_units1 = hp.Choice('units1', values=[10, 15])       
       z = Dense(units=hp_units1, activation='relu')(x)
       
       # Encoder layer 2
       hp_units2 = hp.Choice('units2', values=[3, 4])
       z = Dense(units=hp_units2, activation='relu')(z)
       
       # Decoder
       y = Dense(units=hp_units1, activation='relu')(z)
       y = Dense(inputnodes,activation='linear')(y)

       # compile encoder
       autoencoder = Model(x,y)                                                       
       autoencoder.compile(optimizer='adam', loss='mean_squared_error')
    
       return autoencoder

   def fit(self, hp, autoencoder, *args, **kwargs):
       return autoencoder.fit(*args,
                            batch_size=hp.Choice('batch_size', [16]),
                            **kwargs)

超参数搜索代码如下:

tuner= kt.Hyperband(AEHyperModel(input_shape),
                   objective='val_loss',
                   max_epochs=100,
                   factor=3,
                   directory=os.path.join(softwaredir, 'AEhypertuning'),
                   project_name='DRautoencoder2',
                   overwrite=True,
                   hyperband_iterations=5,
                   executions_per_trial=5)

# patient early stopping and tensorboard callback
callbacks=[EarlyStopping(monitor='val_loss', mode='min', verbose=1, patience=20, restore_best_weights=True),
          keras.callbacks.TensorBoard('C:/whatever/tmp/tb_logs')]

# Search the best hyperparameters for the model
tuner.search(Xz, Xz,
                   epochs=100,
                   shuffle=True,
                   validation_data=(valz, valz),
                   callbacks=[callbacks])

我设置了executions_per_trial=5,但查看试验指标时仅显示单次执行结果:

tuner.oracle.trials['0000'].metrics.metrics['val_loss'].get_history()
Out[19]: [MetricObservation(value=[0.118283973634243], step=1)]

tuner.oracle.trials['0000'].metrics.metrics['val_loss'].get_statistics()
Out[20]: 
{'min': 0.118283973634243,
 'max': 0.118283973634243,
 'mean': 0.118283973634243,
 'median': 0.118283973634243,
 'var': 0.0,
 'std': 0.0}

请问如何真正实现每个试验的多次执行,并获取每次执行的结果,或至少获取均值和标准差以了解结果稳定性?

解决方法

1. 修正HyperModel的fit方法

当前fit方法直接返回单次训练结果,没有处理多次执行的逻辑,导致executions_per_trial参数失效。需要手动循环执行训练,记录每次结果并计算统计量:

import numpy as np

class AEHyperModel(kt.HyperModel):
   def __init__(self, input_shape, inputnodes):
      self.input_shape = input_shape
      self.inputnodes = inputnodes  # 补充初始化inputnodes,避免未定义错误

   def build(self, hp):
       # Input layer
       x = Input(shape=(self.input_shape,))
       
       # Encoder layer 1
       hp_units1 = hp.Choice('units1', values=[10, 15])       
       z = Dense(units=hp_units1, activation='relu')(x)
       
       # Encoder layer 2
       hp_units2 = hp.Choice('units2', values=[3, 4])
       z = Dense(units=hp_units2, activation='relu')(z)
       
       # Decoder
       y = Dense(units=hp_units1, activation='relu')(z)
       y = Dense(self.inputnodes, activation='linear')(y)

       autoencoder = Model(x,y)                                                       
       autoencoder.compile(optimizer='adam', loss='mean_squared_error')
    
       return autoencoder

   def fit(self, hp, model, *args, **kwargs):
       executions = hp.get('executions_per_trial', 5)
       all_val_loss = []
       
       for _ in range(executions):
           # 每次执行重新构建模型,保证权重初始化独立
           model = self.build(hp)
           history = model.fit(*args,
                             batch_size=hp.Choice('batch_size', [16]),
                             **kwargs)
           # 记录最后一轮的验证损失
           all_val_loss.append(history.history['val_loss'][-1])
       
       # 返回统计指标,供Keras Tuner记录
       return {
           'val_loss': np.mean(all_val_loss),
           'val_loss_std': np.std(all_val_loss),
           'all_val_loss': all_val_loss
       }

2. 修正tuner.search的回调参数

你在传入回调时嵌套了一层列表[callbacks],会导致回调无法正确生效,改为直接传入列表:

tuner.search(Xz, Xz,
               epochs=100,
               shuffle=True,
               validation_data=(valz, valz),
               callbacks=callbacks)  # 移除外层的[]

3. 获取多次执行的结果

修改后,可通过以下方式提取单次试验的所有执行数据:

# 获取指定试验
trial = tuner.oracle.trials['0000']

# 获取所有执行的验证损失
all_execution_loss = trial.metrics.metrics['all_val_loss'].get_history()[0].value
# 获取均值和标准差
loss_mean = trial.metrics.metrics['val_loss'].get_history()[0].value[0]
loss_std = trial.metrics.metrics['val_loss_std'].get_history()[0].value[0]

print("所有执行的验证损失:", all_execution_loss)
print("均值:", loss_mean)
print("标准差:", loss_std)

关键注意事项

  • 每次执行重新构建模型:确保每次训练的权重初始化不同,避免因复用权重导致结果一致。
  • 补充inputnodes初始化:原代码中Dense(inputnodes)未定义inputnodes,需在__init__中传入并存储。
  • 自定义指标存储:通过返回字典的方式,将所有执行结果、均值、标准差都作为指标保存,方便后续分析稳定性。

内容的提问来源于stack exchange,提问作者YoungResearcher

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 21:15:34