Modelbuilding函数未返回有效的Keras模型实例,找到tensorflow.python.Keras.engine.sequential.sequential对象

2024-09-24 22:19:07 发布

您现在位置:Python中文网/ 问答频道 /正文

我想借助kerastuner中实现的Bayesian优化来优化LSTM的超参数。到目前为止,这一切进展顺利。我想在我的优化中添加另一件事,即贝叶斯优化找到最佳的特征组合。为此,我使用带0的hp.Int来排除该功能,使用等于1的hp.Int来包含该功能。这意味着,tuner.search()中使用的培训功能将随每次试用而更改

这是我的密码:

import os
import datetime

import IPython
import IPython.display
import matplotlib as mpl
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import seaborn as sns
import tensorflow as tf
from tensorflow import keras
from kerastuner import HyperModel, Objective
from kerastuner import BayesianOptimization
import keras.backend as K
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import (
    Dense,
    Dropout,
    LSTM,
    GRU
)

#data preparation is left out of the code

class RNNHyperModel(HyperModel):
    def __init__(self, input_shape):
        self.input_shape = input_shape

    def build(self, hp):

        # feature selection within BO:
        use = {}


        for i in list(train_df.columns):

            use[str(i)] = hp.Int(
                            str(i), 
                            min_value=0,
                            max_value=1,
                            default=1)
        
        use_df = pd.DataFrame.from_dict(use, orient='index', columns = ['use'])
        list_use_features=list(use_df[use_df.use == 1].index)

        use_train_df = train_df[list_use_features]
        use_val_df = val_df[list_use_features]
        use_test_df = test_df[list_use_features]

        # get the selected features into a numpy array
        train_X = train_df.to_numpy()
        test_X = test_df.to_numpy()
        val_X = val_df.to_numpy()

        # reshape input to be 3D [samples, timesteps, features]
        train_X = train_X.reshape((train_X.shape[0], 1, train_X.shape[1]))
        test_X = test_X.reshape((test_X.shape[0], 1, test_X.shape[1]))
        val_X = val_X.reshape((val_X.shape[0], 1, val_X.shape[1]))
        #print(train_X, train_X.shape, train_y, train_y.shape)

        #implement hyperparameters for BO

        activation = hp.Choice('activation', 
                            [
                              'relu',
                              'tanh',
                              'linear',
                              'selu',
                              'elu'
                              #PReLU and LeakyReLU als zusätzlichen layer einfügen
                            ])

        num_rnn_layers = hp.Int(
                            'num_rnn_layers', 
                            min_value=0,
                            max_value=12,
                            default=3)

        recurrent_dropout = hp.Float(
                            'recurrent_dropout', 
                            min_value=0.0,
                            max_value=0.99,
                            default=0)
        num_units = hp.Int(
                            'num_units', 
                            min_value=0,
                            max_value=64,
                            default=32)

        model = tf.keras.models.Sequential()
        
        for i in range(num_rnn_layers):
            model.add(LSTM(num_units, return_sequences=True, activation=activation, recurrent_dropout = recurrent_dropout))
            
        model.add(Dense(units=1))



        model.compile(
            optimizer=keras.optimizers.Adam(
                hp.Float(
                    'learning_rate',
                    min_value=1e-10,
                    max_value=1e-2,
                    sampling='LOG',
                    default=1e-6
                ),

            ),
            loss=tf.losses.MeanSquaredError(),
            metrics=[tf.metrics.MeanAbsoluteError()]
        )
        return model, train_X, val_X, test_X

INPUT_SHAPE = (12, 1, 21)
hypermodel = RNNHyperModel(input_shape=INPUT_SHAPE)

tuner = BayesianOptimization(
    hypermodel,
    max_trials=70,
    objective='val_loss',
    seed=2,
    num_initial_points=10,
    directory=os.path.normpath('C:/'),
    overwrite=True,
    tune_new_entries=True, 
    allow_new_entries=True,
)

tuner.search(train_X, train_y, callbacks=[tf.keras.callbacks.EarlyStopping(monitor='val_loss',  
              patience=20)], validation_data = (val_X, val_y))

我跑步时有问题

tuner = BayesianOptimization(
    hypermodel,
    max_trials=10,
    objective='val_loss',
    seed=2,
    num_initial_points=10,
    directory=os.path.normpath('C:/'),
    overwrite=True,
    tune_new_entries=True, 
    allow_new_entries=True,
)

。然后我得到错误消息:

---------------------------------------------------------------------------
RuntimeError                              Traceback (most recent call last)
<ipython-input-213-e925add95826> in <module>
----> 1 tuner = BayesianOptimization(
      2     hypermodel,
      3     max_trials=10,
      4     objective='val_loss',
      5     seed=2,

~\anaconda3\envs\myenv\lib\site-packages\kerastuner\tuners\bayesian.py in __init__(self, hypermodel, objective, max_trials, num_initial_points, seed, hyperparameters, tune_new_entries, allow_new_entries, **kwargs)
    326             tune_new_entries=tune_new_entries,
    327             allow_new_entries=allow_new_entries)
--> 328         super(BayesianOptimization, self, ).__init__(oracle=oracle,
    329                                                      hypermodel=hypermodel,
    330                                                      **kwargs)

~\anaconda3\envs\myenv\lib\site-packages\kerastuner\engine\multi_execution_tuner.py in __init__(self, oracle, hypermodel, executions_per_trial, **kwargs)
     55                  executions_per_trial=1,
     56                  **kwargs):
---> 57         super(MultiExecutionTuner, self).__init__(
     58             oracle, hypermodel, **kwargs)
     59         if isinstance(oracle.objective, list):

~\anaconda3\envs\myenv\lib\site-packages\kerastuner\engine\tuner.py in __init__(self, oracle, hypermodel, max_model_size, optimizer, loss, metrics, distribution_strategy, directory, project_name, logger, tuner_id, overwrite)
     96                 distribution_strategy=distribution_strategy)
     97 
---> 98         super(Tuner, self).__init__(oracle=oracle,
     99                                     hypermodel=hypermodel,
    100                                     directory=directory,

~\anaconda3\envs\myenv\lib\site-packages\kerastuner\engine\base_tuner.py in __init__(self, oracle, hypermodel, directory, project_name, logger, overwrite)
     89         self._display = tuner_utils.Display()
     90 
---> 91         self._populate_initial_space()
     92 
     93         if not overwrite and tf.io.gfile.exists(self._get_tuner_fname()):

~\anaconda3\envs\myenv\lib\site-packages\kerastuner\engine\base_tuner.py in _populate_initial_space(self)
    104         """
    105         hp = self.oracle.get_space()
--> 106         self.hypermodel.build(hp)
    107         self.oracle.update_space(hp)
    108 

~\anaconda3\envs\myenv\lib\site-packages\kerastuner\engine\hypermodel.py in _build_wrapper(self, hp, *args, **kwargs)
     63             # to the search space.
     64             hp = hp.copy()
---> 65         return self._build(hp, *args, **kwargs)
     66 
     67 

~\anaconda3\envs\myenv\lib\site-packages\kerastuner\engine\hypermodel.py in build(self, hp)
    118             # Stop if `build()` does not return a valid model.
    119             if not isinstance(model, keras.models.Model):
--> 120                 raise RuntimeError(
    121                     'Model-building function did not return '
    122                     'a valid Keras Model instance, found {}'.format(model))

RuntimeError: Model-building function did not return a valid Keras Model instance, found (<tensorflow.python.keras.engine.sequential.Sequential object at 0x0000020888F67A00>`

更具体地说,如果我只定义了类RNNHyperModel,而没有创建模型的feeature选择过程,那么一切都很好。 :

class RNNHyperModel(HyperModel):
    def __init__(self, input_shape):
        self.input_shape = input_shape

    def build(self, hp):


        #implement hyperparameters for BO

        activation = hp.Choice('activation', 
                            [
                              'relu',
                              'tanh',
                              'linear',
                              'selu',
                              'elu'
                              #PReLU and LeakyReLU als zusätzlichen layer einfügen
                            ])

        num_rnn_layers = hp.Int(
                            'num_rnn_layers', 
                            min_value=0,
                            max_value=12,
                            default=3)

        recurrent_dropout = hp.Float(
                            'recurrent_dropout', 
                            min_value=0.0,
                            max_value=0.99,
                            default=0)
        num_units = hp.Int(
                            'num_units', 
                            min_value=0,
                            max_value=64,
                            default=32)

        model = tf.keras.models.Sequential()
        
        for i in range(num_rnn_layers):
            model.add(LSTM(num_units, return_sequences=True, activation=activation, recurrent_dropout = recurrent_dropout))
            
        model.add(Dense(units=1))



        model.compile(
            optimizer=keras.optimizers.Adam(
                hp.Float(
                    'learning_rate',
                    min_value=1e-10,
                    max_value=1e-2,
                    sampling='LOG',
                    default=1e-6
                ),

            ),
            loss=tf.losses.MeanSquaredError(),
            metrics=[tf.metrics.MeanAbsoluteError()]
        )
        return model

我已经检查了一些旧的帖子,但是那里提供的答案(即从tensorflow导入keras)并没有解决我的问题

我检查了tuner.search_space_summary()的结果,这与预期的一样,也就是说,我的特性表示为0或1的Int。我添加了一个功能的简短示例:

Search space summary
|-Default search space size: 25
Arbeitslose (Int)
|-default: 1
|-max_value: 1
|-min_value: 0
|-sampling: None
|-step: 1
touristische_Übernachtungen (Int)
|-default: 1
|-max_value: 1
|-min_value: 0
|-sampling: None
|-step: 1

事实上,我有两个问题,但如果有人能帮我解决第一个问题,我也许可以自己解决第二个问题:

  1. 如何解决模型构建函数未返回有效Keras模型的问题
  2. 在我的RNNHyperModel类中返回train_X是否足以让tuner.search()识别它?因为之前的错误,我无法尝试。是否有更智能的解决方案根据每次试验中选择的超参数调整train_X集合

提前感谢您的帮助


Tags: importselfdfmodelvalueusetrainval