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

在Keras随机搜索的Python函数中添加外部参数的实现困境

问题分析与解决方案

首先明确两种写法的核心问题:

  1. 第一种写法错误原因:Keras Tuner要求模型构建函数只能接受hp(超参数对象)作为唯一输入参数,额外添加n参数会导致Tuner调用函数时参数不匹配,直接报错。
  2. 第二种写法错误原因:循环中动态生成的hp.Int依赖于超参数n的取值,但Tuner在初始化阶段会扫描所有hp.*定义的超参数,此时n还未被采样,Tuner无法提前确定需要生成多少个cnt_i参数,导致超参数集合不稳定,运行失败。

可行方案分两种场景

场景1:n是固定的外部参数(不需要调优)

使用functools.partial或者闭包,将固定的n注入到模型函数中,保证模型函数仍只接受hp作为唯一参数:

方法1:用functools.partial

import functools
from keras_tuner import RandomSearch
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense

def build_model(hp, n):
    model = Sequential()
    # 循环生成n个超参数并构建对应层
    for i in range(n):
        units = hp.Int(f'cnt_{i}', min_value=4, max_value=32, step=4)
        model.add(Dense(units, activation='relu', input_shape=(784,) if i ==0 else ()))
    model.add(Dense(10, activation='softmax'))
    model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy'])
    return model

# 固定n为3,生成符合Tuner要求的单参数函数
tunable_model = functools.partial(build_model, n=3)

# 初始化随机搜索
rsearch = RandomSearch(
    tunable_model,
    objective='val_accuracy',
    max_trials=50,
    directory='my_dir',
    project_name='test_tuning'
)

方法2:用闭包

from keras_tuner import RandomSearch

def create_model_builder(n):
    def mymodel(hp):
        model = Sequential()
        for i in range(n):
            units = hp.Int(f'cnt_{i}', min_value=4, max_value=32, step=4)
            model.add(Dense(units, activation='relu'))
        model.add(Dense(10, activation='softmax'))
        model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy'])
        return model
    return mymodel

# 固定n=3,得到单参数的模型函数
tunable_model = create_model_builder(3)
rsearch = RandomSearch(tunable_model, objective='val_accuracy', max_trials=50)

场景2:n是需要调优的超参数(可变)

由于Tuner需要提前确定所有超参数的集合,我们可以预定义所有可能的cnt_i(根据n的最大值),然后根据采样到的n值选择使用前n个超参数:

from keras_tuner import RandomSearch
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense

def mymodel(hp):
    # 定义n为超参数(1到4)
    n = hp.Int('n', min_value=1, max_value=4, step=1)
    # 预定义所有可能的cnt_i(最多4个,对应n的最大值)
    all_cnts = []
    for i in range(4):
        all_cnts.append(hp.Int(f'cnt_{i}', min_value=4, max_value=32, step=4))
    # 只取前n个超参数用于构建模型
    selected_cnts = all_cnts[:n]
    
    model = Sequential()
    for idx, units in enumerate(selected_cnts):
        model.add(Dense(units, activation='relu', input_shape=(784,) if idx ==0 else ()))
    model.add(Dense(10, activation='softmax'))
    model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy'])
    return model

rsearch = RandomSearch(
    mymodel,
    objective='val_accuracy',
    max_trials=50,
    directory='my_dir',
    project_name='tune_n_and_cnts'
)

这种方式下,Tuner会提前识别到n和cnt_0到cnt_3所有超参数,在每次试验中先采样n的值,再使用对应的前n个cnt_i构建模型,完全符合Tuner的运行逻辑。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 01:45:36