使用功能性API进行Keras超参数调优

0 投票
1 回答
20 浏览
提问于 2025-04-13 13:11

我正在尝试使用 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_Static_Layer 是在一个循环中定义的,循环范围是 range(1, 3)

如果我尝试 print('i =', i),它确实显示 i = 0,但这是为什么呢?

我可以把 name=f'{i+1}_Static_Layer' 改成 name=f'{i+2}_Static_Layer' 来跳过这个错误。但我还是想搞明白到底发生了什么。

1 个回答

1

注意,

hp.Int('num_static_layers', 1, 3) 

这个部分会先被计算出来,然后结果会传递给范围生成器。所以举个例子,如果 hp.Int('num_static_layers', 1, 3) 返回的是 1,那么代码就会变成:

range(1)

这时的结果是 0。

撰写回答