Keras Tuner与Functional API调参时层名称重复错误排查
Keras Tuner超参数优化中层名重复错误分析与解决
问题场景
尝试使用Keras Tuner优化多输入模型的超参数,代码如下:
def criar_modelo(hp): lstm_input = Input(shape=(x_train_lstm.shape[1], 1), name='LSTM_Input_Layer') static_input = Input(shape=(x_train_static.shape[1], ), name='Static_Input_Layer') # LSTM 1 lstm_layer_1 = LSTM(units=hp.Int('units_lstm_layer_1', min_value=128, max_value=256, step=64), activation='tanh', return_sequences=False, name='1_LSTM_Layer')(lstm_input) # Static 1 static_layer_1 = Dense(units=hp.Int('units_static_layer_1', min_value=64, max_value=192, step=64), activation=hp.Choice('activation', ['relu', 'tanh']), name='1_Static_Layer')(static_input) # Static 2 e/ou 3 for i in range(hp.Int('num_static_layers', 1, 3)): static_layer = Dense(units=hp.Int(f'static_units_{i}', 128, 192, step=32), activation=hp.Choice('activation', ['relu', 'tanh']), name=f'{i+1}_Static_Layer')(static_layer_1) static_layer_1 = static_layer concatenar = Concatenate(axis=1, name='Concatenate')([lstm_layer_1, static_layer_1]) dense_1 = Dense(units=4*len(np.unique(y_train)), activation='relu', name='1_Dense_Layer')(concatenar) dense_2 = Dense(units=2*len(np.unique(y_train)), activation='relu', name='2_Dense_Layer')(dense_1) saida = Dense(units=len(np.unique(y_train)), activation='softmax', name='Output_Layer')(dense_2) model = Model(inputs=[lstm_input, static_input], outputs=[saida]) model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy']) return model
运行时触发以下错误:
Traceback (most recent call last): Cell In[11], line 27 tuner = keras_tuner.GridSearch( File ~\miniconda3\envs\tf-gpu\lib\site-packages\keras_tuner\src\tuners\gridsearch.py:420 in __init__ super().__init__(oracle, hypermodel, **kwargs) File ~\miniconda3\envs\tf-gpu\lib\site-packages\keras_tuner\src\engine\tuner.py:122 in __init__ super().__init__( File ~\miniconda3\envs\tf-gpu\lib\site-packages\keras_tuner\src\engine\base_tuner.py:132 in __init__ self._populate_initial_space() File ~\miniconda3\envs\tf-gpu\lib\site-packages\keras_tuner\src\engine\base_tuner.py:192 in _populate_initial_space self._activate_all_conditions() File ~\miniconda3\envs\tf-gpu\lib\site-packages\keras_tuner\src\engine\base_tuner.py:149 in _activate_all_conditions self.hypermodel.build(hp) Cell In[11], line 23 in criar_modelo model = Model(inputs=[lstm_input, static_input], outputs=[saida]) File ~\miniconda3\envs\tf-gpu\lib\site-packages\tensorflow\python\training\tracking\base.py:629 in _method_wrapper result = method(self, *args, **kwargs) File ~\miniconda3\envs\tf-gpu\lib\site-packages\keras\engine\functional.py:146 in __init__ self._init_graph_network(inputs, outputs) File ~\miniconda3\envs\tf-gpu\lib\site-packages\tensorflow\python\training\tracking\base.py:629 in _method_wrapper result = method(self, *args, **kwargs) File ~\miniconda3\envs\tf-gpu\lib\site-packages\keras\engine\functional.py:229 in _init_graph_network nodes, nodes_by_depth, layers, _ = _map_graph_network( File ~\miniconda3\envs\tf-gpu\lib\site-packages\keras\engine\functional.py:1049 in _map_graph_network raise ValueError( ValueError: The name "1_Static_Layer" is used 2 times in the model. All layer names should be unique.
用户已确认循环变量i值为0,可通过修改层命名规则绕过错误,但希望了解根本原因。
根本原因
- 命名逻辑直接冲突:
- 手动创建的第一个静态层已命名为
1_Static_Layer - 循环中超参数
num_static_layers的最小值为1,对应range(1)生成i=0,此时循环内的层名计算为f'{i+1}_Static_Layer',即1_Static_Layer,与手动层完全重名
- 手动创建的第一个静态层已命名为
- Keras核心约束:
Keras要求模型内所有层的名称必须唯一,检测到重复名称会直接抛出ValueError - Tuner的预检查机制:
Keras Tuner初始化时会调用_activate_all_conditions(),遍历所有可能的超参数组合构建模型以验证空间有效性,因此即使当前运行单一组参数,Tuner也会检测所有参数组合的合法性,触发了命名冲突的检测。
解决方案
方案1:修改手动层命名
将手动创建的第一个静态层改为不冲突的名称,比如:
static_layer_1 = Dense(..., name='0_Static_Layer')(static_input)
方案2:调整循环层命名规则
保持手动层命名不变,让循环层起始编号从2开始:
name=f'{i+2}_Static_Layer'
方案3:调整超参数取值范围
将num_static_layers最小值改为0,配合调整循环层编号逻辑,避免重复:
for i in range(hp.Int('num_static_layers', 0, 2)): static_layer = Dense(..., name=f'{i+2}_Static_Layer')(static_layer_1)
内容的提问来源于stack exchange,提问作者Murilo
相关产品推荐
相关产品推荐

