TensorFlow/TensorBoard超参数分析时optimizer结果不显示问题
TensorBoard HParams 插件不展示optimizer超参数结果的解决方法
问题背景
使用TensorFlow/TensorBoard开展超参数profiling分析时,采用如下超参数配置:
HP_NUM_NODES_ONE = hp.HParam('nodes_one', hp.Discrete([128])) HP_NUM_NODES_TWO = hp.HParam('nodes_two', hp.Discrete([64, 128, 256])) HP_NUM_NODES_THR = hp.HParam('nodes_thr', hp.Discrete([64, 128, 256])) HP_NUM_FILT = hp.HParam('num_filter', hp.Discrete([64, 128, 256])) HP_DROPOUT = hp.HParam('dropout', hp.RealInterval(0.1, 0.3)) HP_OPTIMIZER = hp.HParam('optimizer', hp.Discrete(['adam', 'sgd', 'RMSprop'])) MSE = 'mean_squared_error' with tf.summary.create_file_writer('logs/hparam_21-6').as_default(): hp.hparams_config( hparams=[HP_NUM_NODES_ONE, HP_NUM_NODES_TWO, HP_NUM_NODES_THR, HP_NUM_FILT, HP_DROPOUT, HP_OPTIMIZER], metrics=[hp.Metric(MSE, display_name='Mean Squared Error')], )
配套模型训练测试代码如下:
def train_test_model(hparams): model = tf.keras.models.Sequential([ tf.keras.layers.Conv1D(filters = hparams[HP_NUM_FILT], kernel_size=6, strides=1, activation='relu', input_shape=(300,4), use_bias=True), tf.keras.layers.MaxPooling1D(pool_size=100), tf.keras.layers.Flatten(), tf.keras.layers.Dense(hparams[HP_NUM_NODES_ONE], activation=tf.nn.relu), tf.keras.layers.Dropout(hparams[HP_DROPOUT]), tf.keras.layers.Dense(hparams[HP_NUM_NODES_TWO], activation=tf.nn.relu), tf.keras.layers.Dropout(hparams[HP_DROPOUT]), tf.keras.layers.Dense(hparams[HP_NUM_NODES_THR], activation="linear"), ]) model.compile( optimizer=hparams[HP_OPTIMIZER], loss='mean_squared_error', metrics=['mean_squared_error'], ) model.fit(feature3, label2[0,], epochs=500) _, mean_squared_error = model.evaluate(x_test, y_test[0,]) return mean_squared_error
代码运行正常可输出结果,但TensorBoard面板无法展示optimizer超参数不同取值对应的实验结果。
解决方案
不需要对optimizer参数做特殊编码处理,问题基本都是日志写入逻辑缺失或配置不匹配导致,按以下步骤排查修复即可:
- 最常见原因:仅配置了超参数元信息,缺失单组实验的超参数值写入逻辑。你现有代码只调用了
hp.hparams_config()做全局定义,但每跑完一组超参数组合时,没有调用hp.hparams()将当前组的所有超参数取值(包括optimizer)写入对应实验的summary日志,TensorBoard无法关联每组实验对应的optimizer值,自然无法分组展示。
修复方法:给每组超参数实验创建独立的运行目录,在对应目录的日志写入上下文中,先写入当前组超参数,再记录训练得到的指标,参考实现:
遍历所有超参数组合时,给每个实验分配独立的子路径:def run_single_experiment(run_dir, hparams): with tf.summary.create_file_writer(run_dir).as_default(): # 必须添加该行,写入当前组所有超参数取值 hp.hparams(hparams) mse_res = train_test_model(hparams) tf.summary.scalar(MSE, mse_res, step=1)session_idx = 0 # 遍历所有超参数组合,连续值可根据需求换成随机采样 for n2 in HP_NUM_NODES_TWO.domain.values: for n3 in HP_NUM_NODES_THR.domain.values: for nf in HP_NUM_FILT.domain.values: for dp in [0.1, 0.2, 0.3]: for opt in HP_OPTIMIZER.domain.values: current_hparams = { HP_NUM_NODES_ONE: 128, HP_NUM_NODES_TWO: n2, HP_NUM_NODES_THR: n3, HP_NUM_FILT: nf, HP_DROPOUT: dp, HP_OPTIMIZER: opt } run_name = f"exp_{session_idx}" run_single_experiment(f"logs/hparam_21-6/{run_name}", current_hparams) session_idx += 1 - 检查参数值拼写一致性:字符串类型的离散超参数严格区分大小写,你定义的optimizer可选值为
adam、sgd、RMSprop,传参时不要写成Adam、rmsprop这类大小写、拼写不匹配的值,否则TensorBoard会将其识别为未定义的额外参数,无法归入预设分组。 - 检查日志加载路径:启动TensorBoard时指定的日志目录要到
logs/hparam_21-6这一层,不要选到单个实验的子目录,否则无法加载全量实验的超参数配置。如果之前生成过残缺日志,先清空该目录下的旧文件再重新跑实验,避免无效日志干扰。
内容的提问来源于stack exchange,提问作者Jim Maas
相关产品推荐
相关产品推荐

