python - 模型构建函数没有返回有效的 Keras Model 实例,找到了 tensorflow.python.keras.engine.sequential.Sequential 对象
问题描述
我想借助在 kerastuner 中实现的贝叶斯优化来优化 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 而没有特征选择过程来创建模型,那么一切正常。:
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
事实上,我有两个问题,但如果有人可以帮助我解决第一个问题,我也许可以自己解决第二个问题:
- 如何解决模型构建函数未返回有效 Keras 模型的问题?
- 在我的 RNNHyperModel 类中返回 train_X 是否足以让 tuner.search() 识别它?因为之前的错误,我无法尝试。是否有更智能的解决方案可以根据每次试验中选择的超参数来调整 train_X 集?
提前感谢您的帮助。
解决方案
推荐阅读
- java - Java:如何访问项目文件之外的图像?
- autodesk-forge - 加载模型时有没有办法在网络浏览器中使用更少的内存?
- python - Numpy数组,选择行,同时将零附加到未选择的行
- javascript - 将鼠标悬停在单个菜单项上时如何使整个菜单出现?
- angular - 使用 Angular 11 进行动态表单输入验证
- c++ - 如何从文本文件中读取数据并将其存储到C++中的数组中
- python - 就地修改文本文件(读写文本文件)
- php - 如何创建像 WordPress 一样的自定义 sanitize_title() 函数?
- c# - 如何在 URP 中使用自定义着色器
- python - 使用逗号分隔符将带有列表的列拆分为单独的列,而不指定列名